Hi Wolfram, On Mon, Dec 20, 2021 at 10:07 AM Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> wrote: > This is a sloppy logic analyzer using GPIOs. It comes with a script to > isolate a CPU for polling. While this is definitely not a production > level analyzer, it can be a helpful first view when remote debugging. > Read the documentation for details. > > Signed-off-by: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> Thanks for your patch! > --- /dev/null > +++ b/tools/gpio/gpio-sloppy-logic-analyzer > @@ -0,0 +1,221 @@ > +#!/bin/sh -eu > +# Helper script for the Linux Kernel GPIO sloppy logic analyzer > +# > +# Copyright (C) Wolfram Sang <wsa@xxxxxxxxxxxxxxxxxxxx> > +# Copyright (C) Renesas Electronics Corporation > +# > +# TODO: support SI units in command line parameters? > + > +samplefreq=1000000 > +numsamples=250000 > +cpusetdir='/dev/cpuset' > +debugdir='/sys/kernel/debug' > +ladirname='gpio-sloppy-logic-analyzer' > +outputdir="$PWD" > +neededcmds='taskset zip' > +max_chans=8 > +duration= > +initcpu= > +lainstance= > +lasysfsdir= > +triggerdat= > +trigger_bindat= > +progname="${0##*/}" > +print_help() > +{ > + cat << EOF > +$progname - helper script for the Linux Kernel Sloppy GPIO Logic Analyzer > +Available options: > + -c|--cpu <n>: which CPU to isolate for sampling. Only needed once. Default <1>. > + Remember that a more powerful CPU gives you higher sampling speeds. > + Also CPU0 is not recommended as it usually does extra bookkeeping. > + -d|--duration-us <n>: number of microseconds to sample. Overrides -n, no default value. > + -h|--help: print this help > + -i|--instance <str>: name of the logic analyzer in case you have multiple instances. Default > + to first instance found > + -k|--kernel-debug-dir: path to the kernel debugfs mountpoint. Default: <$debugdir> > + -n|--num_samples <n>: number of samples to acquire. Default <$numsamples> > + -o|--output-dir <str>: directory to put the result files. Default: current dir > + -s|--sample_freq <n>: desired sampling frequency. Might be capped if too large. Default: 1MHz. > + -t|--trigger <str>: pattern to use as trigger. <str> consists of two-char pairs. First > + char is channel number starting at "1". Second char is trigger level: > + "L" - low; "H" - high; "R" - rising; "F" - falling > + These pairs can be combined with "+", so "1H+2F" triggers when probe 1 > + is high while probe 2 has a falling edge. You can have multiple triggers > + combined with ",". So, "1H+2F,1H+2R" is like the example before but it > + waits for a rising edge on probe 2 while probe 1 is still high after the > + first trigger has been met. > + Trigger data will only be used for the next capture and then be erased. > +Examples: > +Samples $numsamples values at 1MHz with an already prepared CPU or automatically prepares CPU1 if needed, > +use the first logic analyzer instance found: > + '$progname' > +Samples 50us at 2MHz waiting for a falling edge on channel 2. CPU and instance as above: > + '$progname -d 50 -s 2000000 -t "2F"' > + > +Note that the process exits after checking all parameters but a sub-process still works in > +the background. The result is only available once the sub-process finishes. > + > +Result is a .sr file to be consumed with PulseView from the free Sigrok project. It is > +a zip file which also contains the binary sample data which may be consumed by others. > +The filename is the logic analyzer instance name plus a since-epoch timestamp. > +EOF > +} > + > +fail() > +{ > + echo "$1" > + exit 1 > +} > + > +set_newmask() > +{ > + for f in $(find "$1" -iname "$2"); do echo "$newmask" > "$f" 2>/dev/null || true; done > +} > + > +init_cpu() > +{ > + isol_cpu="$1" > + [ -d $cpusetdir ] || mkdir $cpusetdir > + mount | grep -q $cpusetdir || mount -t cpuset cpuset $cpusetdir This needs CONFIG_CPUSETS=y, so you may want to document that. > + [ -d "$lacpusetdir" ] || mkdir "$lacpusetdir" > + > + cur_cpu="$(cat "$lacpusetdir"/cpus)" cat: /dev/cpuset/gpio-sloppy-logic-analyzer/cpus: No such file or directory I do have a "cpuset.cpus" file. > + [ "$cur_cpu" = "$isol_cpu" ] && return > + [ -z "$cur_cpu" ] || fail "CPU$isol_cpu requested but CPU$cur_cpu already isolated" > + > + echo "$isol_cpu" > "$lacpusetdir"/cpus || fail "Could not isolate CPU$isol_cpu. Does it exist?" > + echo 1 > "$lacpusetdir"/cpu_exclusive > + echo 0 > "$lacpusetdir"/mems No complaint, although the real files have a "cpuset."-prefix again. [...] > +workcpu=$(cat "$lacpusetdir"/effective_cpus) cat: /dev/cpuset/gpio-sloppy-logic-analyzer/effective_cpus: No such file or directory I do have a "cpuset.effective_cpus" file. > +[ -n "$workcpu" ] || fail "No isolated CPU found" > +cpumask=$(printf '%x' $((1 << workcpu))) > +instance=${lasysfsdir##*/} > +echo "Setting up '$instance': $numsamples samples at ${samplefreq}Hz with ${triggerdat:-no} trigger using CPU$workcpu" > +do_capture "$cpumask" & Anyone with a clue? Thanks! Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds