Debugging With SwdcomΒΆ

IRC log 15 June 2022

<crest> tp: i produced about 300 bytes of logging/tracing through swdcom per byte send via usb
<crest> usb should peak at 5-8Mb/s realworld throughput and swdcom at ~1Mb/s with an stlink v2
<tp> crest, so youre using swdcom to debug usb code ?
<crest> yes
<crest> how else would i debug my usb driver?
<tp> very handy!
<crest> a serial would be even slower

<crest> i came up with this nice little helper:
<crest> -1 variable debug
<crest> 0 bit constant d-tx
<crest> 1 bit constant d-rx
<crest> 2 bit constant d-isr
<crest> : if-debug ( mask -- )
<crest>     s" debug bit@ if" evaluate \ only run the following code literal mask matches the
<crest>     immediate compileonly ;
<crest> : swd-cr ( -- ) 10 swd-emit ;
<crest> : swd-type ( c-addr length -- )
<crest>     over + swap ?do i c@ swd-emit loop ;
<crest> : swd-hex. ( x -- )
<crest>         dup 28 rshift        .digit swd-emit
<crest>         dup 24 rshift $f and .digit swd-emit
<crest>         dup 20 rshift $f and .digit swd-emit
<crest>         dup 16 rshift $f and .digit swd-emit
<crest>         dup 12 rshift $f and .digit swd-emit
<crest>         dup  8 rshift $f and .digit swd-emit
<crest>         dup  4 rshift $f and .digit swd-emit
<crest>                       $f and .digit swd-emit ;
<crest> : d-hex. ( x debug-mask -- )
<crest>     postpone if-debug<tp> yes, I saw the debug switch

<crest>         postpone swd-hex.
<crest>     postpone else
<crest>         postpone drop
<crest>     postpone then
<crest>     immediate compileonly ;
<crest> \ produce code printing "msg" on a new line if mask matches debug
<crest> : d" ( debug-mask "msg" -- )
<crest>     postpone if-debug
<crest>         postpone swd-cr postpone s" postpone swd-type
<crest>     postpone then
<crest>     immediate compileonly ;

<crest> if-debug is a new if statement that matches a mask against the variable named debug
<crest> if any bit is set in the mask and the debug variable the if path is taken
<crest> i use evaluate to allow the compiler to produce better code because postpone would still flush the optimizer state
<crest> while just force feeding the compiler a short constant string allows it to perform constant folding, opcoding and make use of the cached stack elements (just before it has to normalize the stack for the control flow "if" word

<crest> : foo 10 bit d" foobar" ;

<crest> would only print foobar on a new line if bit 10 in the debug variable is set at runtime
<tp> so this is basically a printf but via swdcom ?
<crest> printf that you can enable/disable at runtime
<tp> it doesnt use any on mcu debug peripheral stuff ?

<crest> e.g. 0 debug ! disables all d" " output

<crest> unless you consider the debug hardware a peripheral
<tp> isnt it ?
<crest> it can be argued that the debug hardare is part of the cpu core
<crest> instead of one of its peripherals

<crest> but the imporant thing i gain it runtime latency and throughput by disabling the debug output
<crest> and i can enable/disable groups of debug printfs
<crest> e.g. enable generic interrupt entry/exit tracing
<crest> enable usb rx
<crest> enable usb tx logging etc.
<crest> which results in smaller and slightly faster code
<crest> but i needed the ability to quickly switch between different potentially buggy parts of my code