1 #!/bin/sh -eu 2 # SPDX-License-Identifier: GPL-2.0 3 # 4 # Helper script for the Linux Kernel GPIO slop 5 # 6 # Copyright (C) Wolfram Sang <wsa@sang-engineer 7 # Copyright (C) Renesas Electronics Corporatio 8 9 samplefreq=1000000 10 numsamples=250000 11 cpusetdefaultdir='/sys/fs/cgroup' 12 cpusetprefix='cpuset.' 13 debugdir='/sys/kernel/debug' 14 ladirname='gpio-sloppy-logic-analyzer' 15 outputdir="$PWD" 16 neededcmds='taskset zip' 17 max_chans=8 18 duration= 19 initcpu= 20 listinstances=0 21 lainstance= 22 lasysfsdir= 23 triggerdat= 24 trigger_bindat= 25 progname="${0##*/}" 26 print_help() 27 { 28 cat << EOF 29 $progname - helper script for the Linux Kernel 30 Available options: 31 -c|--cpu <n>: which CPU to isolate for 32 Remember that a more pow 33 Also CPU0 is not recomme 34 -d|--duration-us <SI-n>: number of mic 35 -h|--help: print this help 36 -i|--instance <str>: name of the logic 37 to first instance 38 -k|--kernel-debug-dir <str>: path to t 39 -l|--list-instances: list all availabl 40 -n|--num_samples <SI-n>: number of sam 41 -o|--output-dir <str>: directory to pu 42 -s|--sample_freq <SI-n>: desired sampl 43 Default: <100 44 -t|--trigger <str>: pattern to use as 45 char is channel nu 46 "L" - low; "H" - h 47 These pairs can be 48 is high while prob 49 combined with ",". 50 waits for a rising 51 first trigger has 52 Trigger data will 53 54 <SI-n> is an integer value where SI units "T", 55 56 Examples: 57 Samples $numsamples values at 1MHz with an alr 58 use the first logic analyzer instance found: 59 '$progname' 60 Samples 50us at 2MHz waiting for a falling edg 61 '$progname -d 50 -s 2M -t "2F"' 62 63 Note that the process exits after checking all 64 the background. The result is only available o 65 66 Result is a .sr file to be consumed with Pulse 67 a zip file which also contains the binary samp 68 The filename is the logic analyzer instance na 69 EOF 70 } 71 72 fail() 73 { 74 echo "$1" 75 exit 1 76 } 77 78 parse_si() 79 { 80 conv_si="$(printf $1 | sed 's/[tT]+\?/ 81 si_val="$((conv_si))" 82 } 83 set_newmask() 84 { 85 for f in $(find "$1" -iname "$2"); do 86 } 87 88 init_cpu() 89 { 90 isol_cpu="$1" 91 92 [ -d "$lacpusetdir" ] || mkdir "$lacpu 93 94 cur_cpu=$(cat "${lacpusetfile}cpus") 95 [ "$cur_cpu" = "$isol_cpu" ] && return 96 [ -z "$cur_cpu" ] || fail "CPU$isol_cp 97 98 echo "$isol_cpu" > "${lacpusetfile}cpu 99 echo 1 > "${lacpusetfile}cpu_exclusive 100 echo 0 > "${lacpusetfile}mems" 101 102 oldmask=$(cat /proc/irq/default_smp_af 103 newmask=$(printf "%x" $((0x$oldmask & 104 105 set_newmask '/proc/irq' '*smp_affinity 106 set_newmask '/sys/devices/virtual/work 107 108 # Move tasks away from isolated CPU 109 for p in $(ps -o pid | tail -n +2); do 110 mask=$(taskset -p "$p") || con 111 # Ignore tasks with a custom m 112 [ "${mask##*: }" = "$oldmask" 113 taskset -p "$newmask" "$p" || 114 done 2>/dev/null >/dev/null 115 116 # Big hammer! Working with 'rcu_moment 117 # still printed warnings. Same for re- 118 echo 1 > /sys/module/rcupdate/paramete 119 120 cpufreqgov="/sys/devices/system/cpu/cp 121 [ -w "$cpufreqgov" ] && echo 'performa 122 } 123 124 parse_triggerdat() 125 { 126 oldifs="$IFS" 127 IFS=','; for trig in $1; do 128 mask=0; val1=0; val2=0 129 IFS='+'; for elem in $trig; do 130 chan=${elem%[lhfrLHFR] 131 mode=${elem#$chan} 132 # Check if we could pa 133 [ "$chan" != "$elem" ] 134 bit=$((1 << (chan - 1) 135 mask=$((mask | bit)) 136 case $mode in 137 [hH]) val1=$(( 138 [fF]) val1=$(( 139 [rR]) val2=$(( 140 esac 141 done 142 trigger_bindat="$trigger_binda 143 [ $val1 -ne $val2 ] && trigger 144 done 145 IFS="$oldifs" 146 } 147 148 do_capture() 149 { 150 taskset "$1" echo 1 > "$lasysfsdir"/ca 151 152 srtmp=$(mktemp -d) 153 echo 1 > "$srtmp"/version 154 cp "$lasysfsdir"/sample_data "$srtmp"/ 155 cat > "$srtmp"/metadata << EOF 156 [global] 157 sigrok version=0.2.0 158 159 [device 1] 160 capturefile=logic-1 161 total probes=$(wc -l < "$lasysfsdir"/meta_data 162 samplerate=${samplefreq}Hz 163 unitsize=1 164 EOF 165 cat "$lasysfsdir"/meta_data >> "$srtmp 166 167 zipname="$outputdir/${lasysfsdir##*/}- 168 zip -jq "$zipname" "$srtmp"/* 169 rm -rf "$srtmp" 170 delay_ack=$(cat "$lasysfsdir"/delay_ns 171 [ "$delay_ack" -eq 0 ] && delay_ack=1 172 echo "Logic analyzer done. Saved '$zip 173 echo "Max sample frequency this time: 174 } 175 176 rep=$(getopt -a -l cpu:,duration-us:,help,inst 177 eval set -- "$rep" 178 while true; do 179 case "$1" in 180 -c|--cpu) initcpu="$2"; shift;; 181 -d|--duration-us) parse_si $2; duratio 182 -h|--help) print_help; exit 0;; 183 -i|--instance) lainstance="$2"; shift; 184 -k|--kernel-debug-dir) debugdir="$2"; 185 -l|--list-instances) listinstances=1;; 186 -n|--num_samples) parse_si $2; numsamp 187 -o|--output-dir) outputdir="$2"; shift 188 -s|--sample_freq) parse_si $2; samplef 189 -t|--trigger) triggerdat="$2"; shift;; 190 --) break;; 191 *) fail "error parsing command line: $ 192 esac 193 shift 194 done 195 196 for f in $neededcmds; do 197 command -v "$f" >/dev/null || fail "Co 198 done 199 200 # print cpuset mountpoint if any, errorcode > 201 cpusetdir=$(awk '$3 == "cgroup" && $4 ~ /cpuse 202 if [ -z "$cpusetdir" ]; then 203 cpusetdir="$cpusetdefaultdir" 204 [ -d $cpusetdir ] || mkdir $cpusetdir 205 mount -t cgroup -o cpuset none $cpuset 206 fi 207 208 lacpusetdir="$cpusetdir/$ladirname" 209 lacpusetfile="$lacpusetdir/$cpusetprefix" 210 sysfsdir="$debugdir/$ladirname" 211 212 [ "$samplefreq" -ne 0 ] || fail "Invalid sampl 213 214 [ -d "$sysfsdir" ] || fail "Could not find log 215 [ -x "$sysfsdir" ] || fail "Could not access l 216 217 [ $listinstances -gt 0 ] && find "$sysfsdir" - 218 219 if [ -n "$lainstance" ]; then 220 lasysfsdir="$sysfsdir/$lainstance" 221 else 222 lasysfsdir=$(find "$sysfsdir" -mindept 223 fi 224 [ -d "$lasysfsdir" ] || fail "Logic analyzer d 225 [ -d "$outputdir" ] || fail "Output directory 226 227 [ -n "$initcpu" ] && init_cpu "$initcpu" 228 [ -d "$lacpusetdir" ] || { echo "Auto-Isolatin 229 230 ndelay=$((1000000000 / samplefreq)) 231 echo "$ndelay" > "$lasysfsdir"/delay_ns 232 233 [ -n "$duration" ] && numsamples=$((samplefreq 234 echo $numsamples > "$lasysfsdir"/buf_size 235 236 if [ -n "$triggerdat" ]; then 237 parse_triggerdat "$triggerdat" 238 printf "$trigger_bindat" > "$lasysfsdi 239 fi 240 241 workcpu=$(cat "${lacpusetfile}effective_cpus") 242 [ -n "$workcpu" ] || fail "No isolated CPU fou 243 cpumask=$(printf '%x' $((1 << workcpu))) 244 instance=${lasysfsdir##*/} 245 echo "Setting up '$instance': $numsamples samp 246 do_capture "$cpumask" &
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.