You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have some RP2040 code which used to work fine in pico-sdk 1.4.0.
Now, I've upgraded to pico-sdk 2.1.0, and after making all the changes so the project builds again, I've stumbled upon quite a surprising problem - namely, somewhat randomly, the code fails to run after being flashed on the RP2040 MCU, because it hits an assert in gpio_set_irq_enabled.
I say that I hit the condition "somewhat randomly", because the first time I noticed this problem with the Debug .elf, I think I just reflashed the same .elf (or maybe I rebuilt the code, however without any code changes, can't really remember exactly), and then it started working. But then I rebuilt and reflashed Debug .elf again, and it started hitting the assert again; ever since, I cannot build a Debug .elf which works (does not hit the assert). However, I have built a Release .elf that does work.
I compile in a MINGW64 bash shell on Windows 10, with:
$ arm-none-eabi-gcc --version | head -1
arm-none-eabi-gcc.exe (GCC) 13.3.0
Here is a transcript of gdb-multiarch session, where the assert has been hit after flashing, and then (after program restart) stepping through the first three lines of prestart_irq_setup (some spacing added, and removed "target halted due ..." lines after p commands, for readability):
__breakpoint () at C:/src/pico-sdk/src/rp2040/pico_platform/include/pico/platform.h:126
126 pico_default_asm_volatile ("bkpt #0" : : : "memory");
(gdb) bt
#0 __breakpoint () at C:/src/pico-sdk/src/rp2040/pico_platform/include/pico/platform.h:126
#1 _exit (status=status@entry=1) at C:/src/pico-sdk/src/rp2_common/pico_clib_interface/newlib_interface.c:45
#2 0x1000c894 in __assert_func (file=file@entry=0x10056dd8 "C:/src/pico-sdk/src/rp2_common/hardware_gpio/gpio.c",
line=line@entry=190, func=func@entry=0x1005dc24 <__func__.4> "gpio_set_irq_enabled",
failedexpr=failedexpr@entry=0x10056e18 "!enabled || (raw_irq_mask[get_core_num()] & (1ull<<gpio)) || callbacks[get_core_num()]")
at C:/src/pico-sdk/src/rp2_common/pico_clib_interface/newlib_interface.c:168
#3 0x10009a84 in gpio_set_irq_enabled (gpio=<optimized out>, events=events@entry=12, enabled=enabled@entry=true)
at C:/src/pico-sdk/src/rp2_common/hardware_gpio/gpio.c:190
#4 0x1000f110 in prestart_irq_setup () at C:/src/myproject/my_setup.c:430
#5 0x100008ea in main () at C:/src/myproject/main.c:607
(gdb) b prestart_irq_setup
Breakpoint 1 at 0x1000f0f0: file C:/src/myproject/my_setup.c, line 408.
Note: automatically using hardware breakpoints for read-only addresses.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: C:\src\myproject\build\Debug\myproject.elf
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
[New Thread 1]
[Switching to Thread 1]
Thread 2 hit Breakpoint 1, prestart_irq_setup () at C:/src/myproject/my_setup.c:408
427 {
(gdb) n
428 irq_set_exclusive_handler( IO_IRQ_BANK0, on_gpio_edge_isr );
(gdb) p raw_irq_mask[get_core_num()]
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x00000184 msp: 0x20041f00
$1 = 0
(gdb) p callbacks[get_core_num()]
$2 = (gpio_irq_callback_t) 0x0
(gdb) n
429 irq_set_enabled( IO_IRQ_BANK0, true );
(gdb) p raw_irq_mask[get_core_num()]
$3 = 0
(gdb) p callbacks[get_core_num()]
$4 = (gpio_irq_callback_t) 0x0
(gdb) n
430 gpio_set_irq_enabled( iopins.PIN_RX, GPIO_IRQ_EDGE_FALL | GPIO_IRQ_EDGE_RISE, true );
(gdb) p raw_irq_mask[get_core_num()]
$5 = 0
(gdb) p callbacks[get_core_num()]
$6 = (gpio_irq_callback_t) 0x0
(gdb) p get_core_num()
$7 = 0
(gdb) n
Thread 2 received signal SIGTRAP, Trace/breakpoint trap.
_exit (status=status@entry=1) at C:/src/pico-sdk/src/rp2_common/pico_clib_interface/newlib_interface.c:45
45 __breakpoint();
(gdb) bt
#0 _exit (status=status@entry=1) at C:/src/pico-sdk/src/rp2_common/pico_clib_interface/newlib_interface.c:45
#1 0x1000c894 in __assert_func (file=file@entry=0x10056dd8 "C:/src/pico-sdk/src/rp2_common/hardware_gpio/gpio.c",
line=line@entry=190, func=func@entry=0x1005dc24 <__func__.4> "gpio_set_irq_enabled",
failedexpr=failedexpr@entry=0x10056e18 "!enabled || (raw_irq_mask[get_core_num()] & (1ull<<gpio)) || callbacks[get_core_num()]")
at C:/src/pico-sdk/src/rp2_common/pico_clib_interface/newlib_interface.c:168
#2 0x10009a84 in gpio_set_irq_enabled (gpio=<optimized out>, events=events@entry=12, enabled=enabled@entry=true)
at C:/src/pico-sdk/src/rp2_common/hardware_gpio/gpio.c:190
#3 0x1000f110 in prestart_irq_setup () at C:/src/myproject/my_setup.c:430
#4 0x100008ea in main () at C:/src/myproject/main.c:607
So, I guess, neither of irq_set_exclusive_handler or irq_set_enabled changes neither callbacks nor raw_irq_mask from their starting value of 0 for that core, which ends up triggering the assert in gpio_set_irq_enabled.
I've also tried using gpio_set_irq_callback( &on_gpio_edge_isr ); instead of irq_set_exclusive_handler, but it generates compiler warnings:
warning: passing argument 1 of 'gpio_set_irq_callback' from incompatible pointer type [-Wincompatible-pointer-types]
note: expected 'gpio_irq_callback_t' {aka 'void (*)(unsigned int, long unsigned int)'} but argument is of type 'void (*)(void)'
,,, as it apparently expects a function with two int arguments instead of no (void) arguments; this skips the assert and allows the rest of my code to run, but on_gpio_edge_isr never fires (so overall, it does not work for me). Apparently I'm using gpio_set_irq_callback incorrectly, as I'd need a different prototype for on_gpio_edge_isr, but I haven't been able to find a proper example for that so far. But at least, it confirms that gpio_set_irq_callbackdoes set either callbacks or raw_irq_mask, as the assert in gpio_set_irq_enabled is not hit.
What can I do, to have my code running again?
The text was updated successfully, but these errors were encountered:
ah, the assertion (which is trying to be helpful) assumes you have used some of the hardware_gpio functionality to set up the IRQ handler (either via gpio_set_irq_callback or gpio_add_raw_irq_handler... it should probably be relaxed
ah, the assertion (which is trying to be helpful) assumes you have used some of the hardware_gpio functionality to set up the IRQ handler (either via gpio_set_irq_callback or gpio_add_raw_irq_handler... it should probably be relaxed
Great - thanks for the hint: I tried gpio_add_raw_irq_handler( iopins.PIN_RX, on_gpio_edge_isr ); instead of irq_set_exclusive_handler( IO_IRQ_BANK0, on_gpio_edge_isr ); and things seem to work fine again; although if the assert gets relaxed in 2.1.1, I'd definitely try to go back to irq_set_exclusive_handler, just to keep changes in respect to older versions of my code minimal.
I have some RP2040 code which used to work fine in pico-sdk 1.4.0.
Now, I've upgraded to pico-sdk 2.1.0, and after making all the changes so the project builds again, I've stumbled upon quite a surprising problem - namely, somewhat randomly, the code fails to run after being flashed on the RP2040 MCU, because it hits an assert in
gpio_set_irq_enabled
.I say that I hit the condition "somewhat randomly", because the first time I noticed this problem with the Debug .elf, I think I just reflashed the same .elf (or maybe I rebuilt the code, however without any code changes, can't really remember exactly), and then it started working. But then I rebuilt and reflashed Debug .elf again, and it started hitting the assert again; ever since, I cannot build a Debug .elf which works (does not hit the assert). However, I have built a Release .elf that does work.
I have seen gpio_set_irq_enabled() will not enable GPIO interrupt handling · Issue #1594 · raspberrypi/pico-sdk and tried to reorganize my setup code according to #1594 (comment) .
My
main()
function in this project calls this function somewhere at start:... where the function prototype for
on_gpio_edge_isr
isI compile in a MINGW64
bash
shell on Windows 10, with:Here is a transcript of gdb-multiarch session, where the assert has been hit after flashing, and then (after program restart) stepping through the first three lines of
prestart_irq_setup
(some spacing added, and removed "target halted due ..." lines afterp
commands, for readability):So, I guess, neither of
irq_set_exclusive_handler
orirq_set_enabled
changes neithercallbacks
norraw_irq_mask
from their starting value of 0 for that core, which ends up triggering the assert ingpio_set_irq_enabled
.I've also tried using
gpio_set_irq_callback( &on_gpio_edge_isr );
instead ofirq_set_exclusive_handler
, but it generates compiler warnings:,,, as it apparently expects a function with two int arguments instead of no (void) arguments; this skips the assert and allows the rest of my code to run, but
on_gpio_edge_isr
never fires (so overall, it does not work for me). Apparently I'm usinggpio_set_irq_callback
incorrectly, as I'd need a different prototype foron_gpio_edge_isr
, but I haven't been able to find a proper example for that so far. But at least, it confirms thatgpio_set_irq_callback
does set eithercallbacks
orraw_irq_mask
, as the assert ingpio_set_irq_enabled
is not hit.What can I do, to have my code running again?
The text was updated successfully, but these errors were encountered: