GDB-server/J-Link issues (one maybe solved)

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • GDB-server/J-Link issues (one maybe solved)

    When debugging an AT91SAM9260 with a SAM-ICE and the gdb-server, we cannot single step through or set a breakpoint near certain memory accesses (seem to be accesses using a non-divisible by 4 offset from a register - the target location is aligned) - it causes an incorrect value to be loaded into the register. The correct value is loaded if we just run the code without setting breakpoints or single stepping. Here is more detail:

    The first case incorrectly reads 0xff00 into r0 from a gpio register.
    Setting a breakpoint and then continuing was ok, but single-
    stepping the ldr instruction resulting in a bad read. Single stepping
    through the other cases worked properly

    Case 1:
    mvn r1, #2304
    ldr r0, [r1, #-195]


    Case 2:
    mvn r1, #2304
    sub r1, r1, #195
    ldr r0, [r1]


    Case 3:
    mov r1, #0xb0000000
    mov r1, r1, asr #19
    ldr r0, [r1, #60]


    Playing around with different ldr offsets showed that anything that wasn't a
    multiple of 4 would return a shifted value.

    This seems to be a problem with the GDB server, because if I use the
    jlink.exe utility to single-step through Case 1, it reads the PIO correctly.

    ---------------------------------------------------------------
    The second issue is regarding resetting the chip, since we use a particular reset mode register setting that
    disables NRST and causes the Atmel reset manager to be busy doing an external reset (using NRST) for
    30ms after boot. We were having a real hard time being able to terminate and relaunch a process in
    the debugger, as the j-link GDB server would try to reset the chip, then complain it could not connect.
    We'd have to power cycle the board. Here is a gdb init routine that I found through trial and error that
    seems to be working for now.. Note that it only works if you always use this - if it's already in the bad
    state I described, this won't get it out of that state, you gotta powercycle.

    target remote localhost:2331
    # Wait for firmware external reset to be done?
    monitor sleep 500
    # Enable external reset pin
    monitor long 0xFFFFFD08 0xA5000001
    monitor reset
    monitor speed 30
    monitor speed auto
    # Disable watchdog
    monitor long 0xfffffd44 0xa0008000
  • Confirmed that 3.79h fixes the erroneous memory read issue we were seeing. Thanks!

    Still troubled by the reset issue, as our workaround is apparently fragile - I'm working with the engineer who's got the issue today, I'll post if we figure out more details.

    Thanks again,
    -brad
  • We eventually solved our problems with reset, via a lengthier GDB script. Two issues were: we were bringing the bus clock down to 16khz (half the slow clock) at one point before we activated the PLL, which caused intermittent failures with the couple bus accesses that happened during that time. Made sure we switched to the main oscillator before we programmed the prescaler. And secondly, Atmel doesn't seem to have a reset mechanism that brings their peripheral (non-ARM) registers to sane values. We tried all your reset types (0,1,2...). Their boot ROM code resets things it seems, but that doesn't help if you're debugging by loading right into RAM, booting off directly accessible flash, or doing a warm reset. With a warm reset, you'd need to disable and clear all interrupts before resetting at a minimum, and we needed to do this via direct memory access commands in our gdb init script. Now everything seems to work great!

    Thought I'd share the conclusions in case the info might help someone else out!
    Thanks,
    -brad
  • Hi Brad,

    there should be a way to properly reset the CPU.
    The first thing you need to do is set the speed to either adaptive or 5kHz since the CPU starts at 32kHz;
    after that, a Reset with Zero delay should work.

    We had a similar problem on a SAM7S and something like

    monitor speed 5 // Slow speed so we can work with 32KHz
    monitor reset 0 0 // Halt CPU with 0 delay
    monitor MemU32 0xfffffd00 = a5000004 // Reset peripherals ... Note that a5000005 may also work (resets also CPU, MMU, caches)
    ... // Set up PLL
    monitor speed adaptive

    fixed it. (Without comments, I am not sure they work)
    In general, performing a RESET using 0xFFFFFD00 (for CPU and peripherals) should be the best solution once the CPU is halted.
    If the MMU is enabled and a non-flat mapping (virtual memory != phys. memory) is used, then the MMU may need to be disabled.
    However, something along that line (see above) should work fine.

    Can you give it a shot and post results ?

    --Mike