Add ability to save core file to flash #1385

Open
opened 2023-05-22 11:08:18 -05:00 by strspn · 3 comments
strspn commented 2023-05-22 11:08:18 -05:00 (Migrated from github.com)

The SDK contains many points of error checking that result in program termination, but unless the Pico is connected to a host via UART or USB, there is no record left behind. This works well for development, but for deployed products, there is no debug information saved to help solve crashes.

It would be helpful if the SDK could write a core file to the lower portion of flash memory, such that it could be downloaded to a development host system and examined using gdb "target core". This then would also require a way to locate the core file and upload it to a host. Even if only the stack is saved, it would be helpful to determining the cause.

A compile-time define switch passed through cmake would allow users to opt-out to save executable file space. The hooks include assert(), panic*(), and __breakpoint().

The SDK contains many points of error checking that result in program termination, but unless the Pico is connected to a host via UART or USB, there is no record left behind. This works well for development, but for deployed products, there is no debug information saved to help solve crashes. It would be helpful if the SDK could write a core file to the lower portion of flash memory, such that it could be downloaded to a development host system and examined using gdb "target core". This then would also require a way to locate the core file and upload it to a host. Even if only the stack is saved, it would be helpful to determining the cause. A compile-time define switch passed through cmake would allow users to opt-out to save executable file space. The hooks include *assert*(), panic*(), and __breakpoint().
peterharperuk commented 2023-05-22 12:05:39 -05:00 (Migrated from github.com)

Yes, that would be good

Yes, that would be good
strspn commented 2023-05-29 13:42:40 -05:00 (Migrated from github.com)

In the case where the full memory image is not saved, the saved stack should include some number of stack bytes/frames above the current stack pointer. This allows the developer to see the frame(s) of call(s) made and returned prior to the crash.

In the case where the full memory image is not saved, the saved stack should include some number of stack bytes/frames above the current stack pointer. This allows the developer to see the frame(s) of call(s) made and returned prior to the crash.
akohlsmith commented 2026-01-24 16:43:55 -06:00 (Migrated from github.com)

I've been playing with doing this exact thing. At the moment I'm recording the state of both cores when one hits an exception, along with dumping stack for each into a 512 byte area at the top of RAM. This is (mostly) working, but there's an issue with shared IRQ use over the RP2350 doorbell interrupt, which both FreeRTOS and my "trigger NMI on the other core to capture state" use that I haven't yet been able to figure out.

I modified FreeRTOS to use irq_add_shared_handler() instead of irq_set_exclusive_handler() and this works fine as long as I don't add my shared handler, but as soon as I add mine (even if I never trigger my doorbell), FreeRTOS' timer tick seems to run at 1/2 to 3/8 speed and nothing works quite right. I'm pretty sure there is a bug in the way the shared interrupt code tries to be slick.

I catch the exception on reboot (I use the internal watchdog to do this) and the idea is to write the crash information out to I2C or microsd (512 bytes is exactly the size of a single sector, which is why I chose it, don't need to support filesystems if you don't want to).

I've been playing with doing this exact thing. At the moment I'm recording the state of both cores when one hits an exception, along with dumping stack for each into a 512 byte area at the top of RAM. This is (mostly) working, but there's an issue with shared IRQ use over the RP2350 doorbell interrupt, which both FreeRTOS and my "trigger NMI on the other core to capture state" use that I haven't yet been able to figure out. I modified FreeRTOS to use `irq_add_shared_handler()` instead of `irq_set_exclusive_handler()` and this works fine as long as I don't add my shared handler, but as soon as I add mine (even if I never trigger my doorbell), FreeRTOS' timer tick seems to run at 1/2 to 3/8 speed and nothing works quite right. I'm pretty sure there is a bug in the way the shared interrupt code tries to be slick. I catch the exception on reboot (I use the internal watchdog to do this) and the idea is to write the crash information out to I2C or microsd (512 bytes is exactly the size of a single sector, which is why I chose it, don't need to support filesystems if you don't want to).
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#1385
No description provided.