Hardware timer not working after reset under debugger
Hello,
During testing some examples I noticed SDK Timer functions are not working when I'm debugging my program. It seems like they are waiting indefinitely for hw timer, which has value 0.
x/2x 0x40054024
0x40054024: 0x00000000 0x00000000
x/32x 0x40054000
0x40054000: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054010: 0x00000000 0x00000000 0x00000000 0x000003e2
0x40054020: 0x00000008 0x00000000 0x00000000 0x00000007
0x40054030: 0x00000000 0x00000000 0x00000008 0x00000000
0x40054040: 0x00000000 0x54494d52 0x00000000 0x00000001
0x40054050: 0x00000000 0x00000000 0x00000000 0x00000001
0x40054060: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054070: 0x00000000 0x00000000 0x00000000 0x00000000
But if I power cycle my target and then attach debugger (just attach - not resetting core or touching anything in flash) I can see that code is definitely progressing and timer is no longer stuck.
x/2x 0x40054024
0x40054024: 0x00000000 0x002b4a54
x/32x 0x40054000
0x40054000: 0x00000000 0x00000000 0x00000000 0x002b4a54
0x40054010: 0x00000000 0x00000000 0x00000000 0x002b4c8e
0x40054020: 0x00000008 0x00000000 0x002b4a54 0x00000007
0x40054030: 0x00000000 0x00000000 0x00000008 0x00000000
0x40054040: 0x00000000 0x54494d52 0x00000000 0x00000001
0x40054050: 0x00000000 0x00000000 0x00000000 0x00000001
0x40054060: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054070: 0x00000000 0x00000000 0x00000000 0x00000000
if I step though the code I can see that now timer is progressing normally. If I then reset target using debugger I can see core staring from 0x000000ee. After some initialization (I cannot track it, it's before runtime_init function) timer registers seem to be reset:
x/32x 0x40054000
0x40054000: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054010: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054020: 0x00000000 0x00000000 0x00000000 0x00000007
0x40054030: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054040: 0x00000000 0x54494d52 0x00000000 0x00000001
0x40054050: 0x00000000 0x00000000 0x00000000 0x00000001
0x40054060: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054070: 0x00000000 0x00000000 0x00000000 0x00000000
x/2x 0x40054024
0x40054024: 0x00000000 0x00000000
And after full initialization (after runtime_init - I verified core is performing that function), registers are a little different, but timer is stuck at 0:
x/32x 0x40054000
0x40054000: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054010: 0x00000000 0x00000000 0x00000000 0x000003e2
0x40054020: 0x00000008 0x00000000 0x00000000 0x00000007
0x40054030: 0x00000000 0x00000000 0x00000008 0x00000000
0x40054040: 0x00000000 0x54494d52 0x00000000 0x00000001
0x40054050: 0x00000000 0x00000000 0x00000000 0x00000001
0x40054060: 0x00000000 0x00000000 0x00000000 0x00000000
0x40054070: 0x00000000 0x00000000 0x00000000 0x00000000
x/2x 0x40054024
0x40054024: 0x00000000 0x00000000
My code no longer functions, all timer-related functions are blocking infinitely. Of course power-cycling whole board is fixing this issue, until next target reset.
I'm using OpenOCD, Picoprobe with Cortex Debug plugin in VSCode. Is this a known issue? Am I am doing anything wrong? I'm fighting with this issue second day, any help is highly appreciated. Thanks!
Is this the same thing as https://github.com/raspberrypi/picoprobe/issues/45 ?
@lurch you're right, it's the same thing. After adding USE_CORE 0 to openocd configuration I no longer have that problem. Thanks! I would say it's still very confusing timer is configured like that? Can you point me to documentation which register should I change to have counter still running when core is halted?
I've not run any code, but a quick look at https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf suggests that TIMER: DBGPAUSE looks like a likely candidate?
I had the same problem and can confirm that adding timer_hw->dbgpause = 0; to my code fixed the problem for me.
I had the same problem and can confirm that adding
timer_hw->dbgpause = 0;to my code fixed the problem for me.
Dumb question... It looks timer_hw->dbgpause defaults to 0x7 (DBG1/DBG0) enabled. Turning off DBG1 appears to fix the issue... Should pico_runtime/runtime.c::runtime_init set the timer_hw->dbgpause to 0x2 or 0x0 until the second core is "turned" on, then clear it again if the second core is disabled?
Re-opening to investigate suggestion
@kilograham - Directing your attention regarding this issue here in case you haven't seen it recently. I believe the cause of this problem is users using official releases of OpenOCD 0.12.0 as directed to in the getting started guide, but doing so on non-Raspberry Pi systems. Raspberry Pi appears to serve a more up-to-date build of OpenOCD through apt, as 0.12.0 official does not contain SMP support.
Solution for me was to DL OpenOCD's current snapshot build for Windows, and building OpenOCD from source on Debian to achieve SMP support and resolve timers from freezing. See the linked comment/issue for details.
@recursivenomad Our current recommended setup is to use the Raspberry Pi Pico VSCode extension, which downloads the tools that it needs from https://github.com/raspberrypi/pico-sdk-tools
@will-v-pi Do you think it's worth updating https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf to suggest that people always use pico-sdk-tools rather than installing OpenOCD via other methods?
Specifically this section still recommends using apt:
https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf#_install_openocd
Until OpenOCD 1.0.0 releases later this year, it would also be nice if it could state that OpenOCD 0.12.0 is not supported.
@will-v-pi Do you think it's worth updating https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf to suggest that people always use pico-sdk-tools rather than installing OpenOCD via other methods?
The guide does already state as the first thing that building from source or downloading from pico-sdk-tools is necessary after RP2350 release, so I think that guidance will just need to persist until the next OpenOCD release, and then we can fix the guide to use OpenOCD 1.0.0
I think the confusion stems from the section immediately below that, titled "Install OpenOCD", which recommends installing from apt. I think a lot of users might click that on the table of contents, and not see the section above it.
FWIW, I think the "Install OpenOCD" section isn't necessary, with the how clear the information provided in "Building OpenOCD" is.