kristianlm / updi-gdbserver

Debug your AVR programs with avr-gdb through UPDI and a UART dongle
1 stars 0 forks source link

Support for other chips #1

Closed kajusK closed 6 months ago

kajusK commented 8 months ago

Hi,

I've just found your great project! Would it be possible to add other chips (looking for Attiny1616 debugger currently)?

Is this project based on reverse engineering the debug protocol or is there any documentation? I was not able to find anything debugging related except the UPDI protocol itself...

kristianlm commented 8 months ago

Hi and thanks for your interest in this. The intention is definitely to support more UPDI-enabled chips, we just haven't gotten around to it. The code here is based off of a document written by @andyjpb and I. Perhaps you can add your latest version to the repo here, Andy?

@kajusK The good news is that there are not too many target-specific paramteres needed to be kept for a gdbserver, as avr-gdb itself knows its target pretty well. The list of target-specific registers is handled at the bottom of avr-updi.scm:

The bad news is that some of these locations are undocumented. Can you try this on your attiny1616 target and see if it Just Works™? I'd guess it's likely they are the same across the same families at least. Unfortunately, I don't have a device I can test.

kristianlm commented 8 months ago

Looking at ATtiny1616.atdf from packs.download.microchip.com, I can verify that SP and SREG are 0x3d and 0x3f, respectively, on both devices.

Edit: It seems to work on attiny1614:

updi-gdbserver > avr-gcc -DF_CPU=4000000 -g -O1 -g -mmcu=attiny1614 example-led-blink.c -o example-led-blink.elf
updi-gdbserver > avr-gdb -ex "target extended-remote 127.0.0.1:4444" example-led-blink.elf
GNU gdb (GDB) 12.1
…
(gdb) p/x *0x00@128
$6 = {0xffff <repeats 128 times>}

(gdb) load
Loading section .text, size 0xd4 lma 0x0
Start address 0x00000000, load size 212
Transfer rate: 39 bytes/sec, 42 bytes/write.

(gdb) p/x *0x00@128
$7 = {0x940c, 0x3e, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48,
  0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48,
  0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48,
  0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x940c, 0x48, 0x2411, 0xbe1f, 0xefcf, 0xbfcd, 0xe3df, 0xbfde, 0x940e, 0x4a, 0x940c, 0x68,
  0x940c, 0x0, 0xe480, 0x9380, 0x400, 0xe0e0, 0xe0f4, 0x8184, 0x6480, 0x8384, 0xe72f, 0xe388, 0xe091, 0x5021, 0x4080, 0x4090, 0xf7e1,
  0xc000, 0x0, 0x8184, 0x7b8f, 0x8384, 0xe72f, 0xe388, 0xe091, 0x5021, 0x4080, 0x4090, 0xf7e1, 0xc000, 0x0, 0xcfe7, 0x94f8, 0xcfff,
  0xffff <repeats 22 times>}

(gdb) hbreak example-led-blink.c:7
Hardware assisted breakpoint 1 at 0x9e: file example-led-blink.c, line 7.

(gdb) c
Continuing.

Breakpoint 1, main () at example-led-blink.c:7
7       PORTA.OUT |=  (1 << PIN6_bp); _delay_ms(100);
andyjpb commented 8 months ago

Hi @kajusK!

Thanks for your interest. Please could you try it on the ATTiny1616? I suspect it will work OK as it's in the same series as the 414 and has the same size address space.

We don't currently list it as supported because we've not tested it but if you test it and it works then please let us know and we will try to maintain it there as well.

kajusK commented 7 months ago

Hi, thank you for a quick response,I've tried with attiny1616, unfortunately it doesn't seem to work:

./gdbserver -b 10000 /dev/ttyUSB0 
Starting gdbserver on port 4444. Press ctrl-c to quit.
Connect with, for example:
  avr-gdb -ex "target extended-remote 127.0.0.1:4444" program.elf

Current device SIB:
  OBS: data available 

Error: updi read timeout (1s)

    Call history:

    avr-updi.scm:43: chicken.file.posix#file-select   
    avr-updi.scm:75: chicken.file.posix#file-write    
    avr-updi.scm:76: chicken.memory.representation#number-of-bytes    
    avr-updi.scm:76: file-read-retrying   
    avr-updi.scm:50: ##sys#get-keyword    
    avr-updi.scm:55: chicken.file.posix#file-read     
    avr-updi.scm:57: scheme#substring     
    avr-updi.scm:60: loop     
    avr-updi.scm:61: chicken.string#reverse-string-append     
    avr-updi.scm:79: file-read-retrying   
    avr-updi.scm:50: ##sys#get-keyword    
    avr-updi.scm:55: chicken.file.posix#file-read     
    avr-updi.scm:57: scheme#substring     
    avr-updi.scm:59: timeout      
    avr-updi.scm:51: chicken.string#conc      
    avr-updi.scm:51: chicken.base#error     <--

I don't have the 414 to try if I compiled the tool correctly, so not sure it's problem of just my build or of the attuny1616 itself. Or is there something I need to change in the sources before testing with attiny1616?

kristianlm commented 7 months ago

Hi KajusK, thanks for trying this out.

It could be a physical wiring problem. Are you sure you've hooked up the USB UART dongle GND connections correctly? Have you tried the pymcuprog (mentioned in the readme) on your setup? If you can ping your device with pymcuprog, updi-gdbserver should be working too.

Do you have an oscilloscope? If pymcuprog is working but updi-gdbserver isn't, perhaps a scope trace of the two "greetings" can help spot the problem.

You shouldn't need to change the source for the initial SIB greeting, as it's part of the UPDI protocol (documented in the UPDI chapter of your datasheet) and device-independent.

kajusK commented 7 months ago

Hi @kristianlm,

yes, I'm using the identical setup for programming the chip using avrdude (it has UPDI support). I'll test with the scope tomorrow. I can hook up the logical analyzer and make a capture.

kristianlm commented 7 months ago

A logic dump would be very useful, thank you.

Also, what USB-to-UART adapter are you using on /dev/ttyUSB0? I knew avrdude could do UPDI over atmel-ice or similar, but I didn't know it could do it over serial. Does that mean your're using jtag2updi with that? I'm not sure I follow exactly what avrdude is doing here.

kajusK commented 7 months ago

I'm using a custom board with Chinese CH340 USB-to-UART converter. I'm not sure how it's implemented on the avrdude side,but there's a dedicated programmer called serialupdi which works pretty well, the standard command is like:

avrdude -c serialupdi -P /dev/ttyUSB0 -p attiny1616 -U flash:w:app.hex

The captures are here, you can open them in saleae logic tool captures.zip

The preamble from avrdude is: image

The gdb preamble looks like this (I've tried with various baudrates, still the same pattern) image

kristianlm commented 7 months ago

Hi, and thanks for getting those traces. I've been trying to look at this today, but haven't really gotten anywhere. I'm running the latest git version of avrdude, in case it left something on the target configured differently than what updi-gdbserver expects, but without luck - it's still working for me unfortunately.

I've carefully inspected the preamble from avrdude, but all I can see is that the break signal is much shorter - this is inefficient but shouldn't be causing trouble.

Tomorrow I will try to see if I have a CH340 lying around and see if that could be what's causing this. I'm using a Ltd FT232 Serial (UART) IC. Am understanding you correctly in that you're setting different baud rates with ./updi-gdbserver -b 115200 …, but that your scope is telling you that this has no affect? If you change the baudrate with avrdude, does that produce correct baudrates?

https://github.com/avrdudes/avrdude/blob/main/src/updi_link.c#L129

kristianlm commented 7 months ago

Hi again,

I don't have a CH430 to test on unfortunately. I've tried something else, though: Could you try and build and run the issue1-trobleshoot branch? I've tried to copy the stty settings from avrdude.

kajusK commented 7 months ago

Hi, thanks for all the support, it's nice to see such helpful people around :).

I'm running the avrdude v7.2 which seems to be the last official release. Changing the baudrate doesn't affect the first few bytes, the timing is always the same, what is changing is the actual data transfer baudrate afterwards.

I've tried launching the issue1-trobleshoot branch compiled code with baudrates of 10000 from readme and 115200 the avrdude is using by default with no luck, all the captures are here: captures.zip

The "programmer" I'm using looks like this and it works well with avrdude... image

I'll try to read some UPDI docs over the weekend to get some background to be a bit more helpful with the debugging.

kristianlm commented 7 months ago

Hi @kajusK, I'm glad someone is willing to try our software - thanks for helping out!

I think I have some good news! I looked at your schematic, and one difference from my setup is that I'm using a diode instead of a 4k7 resistor. If I put in a 4k7 resistor, I'm getting the same results as you: avrdude works but updi-gdbserver does not. Could you try it with the diode?

As to why avrdude is able to work with the resistor, and updi-gdbserver is not is still a bit of a mystery. I will document the caveat, and try to look into this when I get the time.

EDIT: For reference, I've put this guide in the readme.

kajusK commented 7 months ago

Great! Good catch! I'll get to my workshop at Friday, so I'll try with a diode and let you know!

kajusK commented 7 months ago

Hmm, I've replaced the resistor with diode, the avrdude still works pretty well, unfortunately the updi-gdbserver still fails with read timeout :/

kristianlm commented 7 months ago

Hi @kajusK , oh that's bad news. Thanks for reporting. I'll try to get updi-gdbserver to use the exact same tty initialization procedure as avrdude - since everything else is identical as far as I can tell. Thanks for taking the time to try this. It's the only way to make this piece of software move forward.

kristianlm commented 7 months ago

Hi @kajusK ,

I've pushed a commit to the issue 1 troubleshooting branch. It adds a "double break" during initialization. My setup now works with a resistor. Could you please try on your setup?

kajusK commented 7 months ago

Hmm, still the same issue, I'll hook it up to the oscilloscope after Christmas and take a further look what might be going on.

kristianlm commented 7 months ago

Okey. That's bad news, but thanks for getting back to me and not giving up on this yet!

I looked briefly over this yesterday and the tty-tettings are still slightly different from avrdude's. After the holidays, I will give this another spin. Thanks for not giving up!

Meanwhile, 🎄happy holidays and new year!

kristianlm commented 6 months ago

Happy New Years, kajusK!

I've started looking into this, and I'm trying to document the process here. Please feel free to skip this part. The good news is that I'm able to reproduce your situation. Here is a Sigrok/Pulseview capture which contains the preambles from avrdude and updi-gdbserver. It looks like this:

image

I'm capturing both the TX and the combined TX/RX pins so I can see what's coming from the target. Both captures are from after updi-gdbserver's failed initialization as that triggers avrdude's' "double break signal" condition with a warning:

avrdude: serialupdi_recv(): programmer is not responding

After the double break, avrdude is able to recover the link and retries its updi_link_init_session_parameters and updi_link_check procedures. These take place at locations A and D in the image above. At D, we're seeing the first reply from the target:

image

I found a bug, which I've fixed in 2856c. You may have encountered this. But it didn't solve the problem altogether.

It seems that the target doesn't always respond unless you "configure" the UPDI link with the proper 55 c3 08 and 55 c2 80 options, and sometimes even that isn't enough. This sets CTRLA to 80 (enabling Inter-Byte Delay) and CTRLB to 08 (disables Content and Collision Detection). I think this is primarily needed because avrdude configures these registers differently upon exit:

avrdude: STCS 0x0C to address 0x03
avrdude: sending 3 bytes [0x55, 0xc3, 0x0c]

avrdude done.  Thank you.

Which essentially disable the UPDI PHY interface. So it makes sense that we need to re-enable that with 55 c3 08. What's confusing is that I also need a double-break signal after running avrdude on the same tty. It's as if the two tty-setting are incompatible (but they should be identical).


Hopefully what I have this far will resolve this issue. I've pushed the fixes to the master branch. Can you check out master, rebuild and retry?

~/p/updi-gdbserver > git checkout master
~/p/updi-gdbserver > csc -O2 gdbserver.scm
~/p/updi-gdbserver > ./gdbserver -v -b 115200 /dev/ttyUSB0
updi-break: 25000µs
updi-cmd drain
  read: #${00}
updi-cmd 3 + 0
 write: #${55c308}
  read: #${55c308}
  read: #${}
updi-cmd 3 + 0
 write: #${55c280}
  read: #${55c280}
  read: #${}
updi-cmd 2 + 1
 write: #${5580}
  read: #${5580}
updi-init: no response from programmer, resetting UPDI link
updi-break: 25000µs
updi-break: 25000µs
updi-cmd drain
  read: #${00}
updi-cmd drain
  read: #${00}
updi-cmd 3 + 0
 write: #${55c308}
  read: #${55c308}
  read: #${}
updi-cmd 3 + 0
 write: #${55c280}
  read: #${55c280}
  read: #${}
updi-cmd 2 + 1
 write: #${5580}
  read: #${5580}
  read: #${20}
Starting gdbserver on port 4444. Press ctrl-c to quit.
Connect with, for example:
  avr-gdb -ex "target extended-remote 127.0.0.1:4444" program.elf
updi-cmd 2 + 32
 write: #${55e6}
  read: #${55e6}
  read: #${74696e7941565220503a30443a302d334d32202830312e35394231352e302900}
Current device SIB:
  "tinyAVR P:0D:0-3M2 (01.59B15.0)\x00"

Best of luck!

kajusK commented 6 months ago

Happy new year!

You are awesome! I still haven't had much time to dig deeper, but this looks promising. I'll get home on Friday, so I'll test the latest changes you've made and let you know.

Thank you very much!

kajusK commented 6 months ago

Hello @kristianlm,

you are awesome, it works! I was able to connect to target and step the program! Thank you very much for all your help!

kristianlm commented 6 months ago

I'm glad to hear it, @kajusK ! Thanks for your patience and good luck with your upcoming debug sessions. Please file more issues if you encounter any more issues or ideas for improvements.