I’ve been working on an application that activates rtc alarms every few seconds, when the alarm is activated it sends a message to a thread. This msg is used in a thread that in its turn sends messages over gnrc. However, after a while sending messages, it stops and the mcu only gets in in the rtc alarm, without returning to the thread context.
I tested a basic thread, that just puts some serial message, and a rtc alarm showing another message. The program starts running the thread but every time the rtc alarm activates i get a Riot Kernel panic: HARD FAULT HANDLER and then reboots the system.
I imagine there is a problem when both functions are supposed to run at the same time and it gets a kernel panic, or some kind of problem with the context switcher. Any thoughts on why this is happening, advice on how to workaround it, etc. would be much appreciated. Cheers,
can you share the code of your application somewhere? That might help to find
the issues. I would suppose that the interrupt handler is faulty or consumes
too much memory or something like this.
I think start debugging with a basic application that just prints some text
whenever a message from the RTC interrupt is received is a smart idea. Now, we
need to figure out what exactly triggers the kernel panic. Are you compiling
your application with the DEVELHELP macro enabled? And which port are you
using? Maybe you can use `make debug` to get more information.
Thanks for your help. I should mention that i’m working on the 2017.07 release. This is the main functions of the code, the behavor i’m expecting is to trigger the alarm every TIME_WAITING seconds, run sale_test() and the go back to the control thread. However i get a kernel panic or run only the control_thread, without considering the rtc_alarm after a while.
It is likely that the debug print in the sale_test function overflows the ISR stack. You can increase that stack size by adding
CFLAGS += -DISR_STACKSIZE=1024
to your Makefile.
The interrupt service routines on cortex m have a separate stack which is set to 512 bytes by default. Usually when you need to do more complex tasks you will unlock a mutex from the ISR or set a thread flag which will tell some user space thread to perform the complex tasks instead of running it inside the ISR.
Having long interrupt service routines may also delay the execution of other interrupt handlers, so there are several benefits of performing tasks in user space threads.