This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

FreeRTOS and SoftDevice events: hard fault

We have used FreeRTOS a lot, also on nRF51 and nRF52. Now I'm trying to migrate our nRF52 code form SDK11-alpha and SoftDevice 2.0.0-7-alpha (?) to the most recent versions. Most of things are working but one problem remains. We use s132_nrf52_2.0.1_softdevice.hex.

Everything runs fine for a few minutes, but then some race condition occurs and causes a hard fault. Possibly when a lower priority task is preempted, due to a tasks invoked by calling intern_softdevice_events_execute();

Question 1) Any ideas why in the SoftDevice event handler (ble_new_event_handler() copied straight form the SDK11 example ble_app_hrs_freeertos) fails with a stack trace like this:

HardFault_handler () ... gcc_startup_nrf52.s
<signal_handler called>
0x000092a in ?? ()
<signal_handler called>
... in vPortStartFirstTask()

Otherwise this looks good to me but should have exited the previous signal handler before the new one gets called. This stack trace is (manually) copied probably from a test running the signal handled event task on the lowest FreeRTOS priority.

If using a high FreeRTOS task priority, then the same error happens at portYIELD_FROM_ISR(yield_req) in the ble_new_event_handler(). Specificly the hard fault happens in portmacro_cmsis.h at the end of the portYIELD() call at the __ISB(); line.

Our application logic can manage with omitting the portYIELD_FROM_ISR() call in ble_new_event_handler() and that seems to fix the instability. This is not optimal.

Question 2) Is there somewhere documentation on how the SoftDevice handles mutual exclusivity - in RTOS context? We use several FreeRTOS tasks and priorities, with multiple of them making calls to softdevice functions...

Is there a mutex on the SoftDevice side so that we can just call the functions without putting a mutex sempahore around every SD call (which would become cumbersome with asynchronous calls). And is there something we should avoid when processing events firm SoftDevice and making new softdevice calls based on those?

I'm wondering it some of these issues is causing the trouble above...

Parents
  • They're just my musings at this point- I'm still thinking it through and need to spend some time doing a FreeRTOS deep dive until I really feel comfortable with it.

    I just looked at a few more of the examples and actually it seems the kernel priority is 0x0f, the lowest level (and this port doesn't seem to follow the documented convention that it should be the fully-shifted, lowest bits set to 1 version, ie 0xff). The highest available interrupt which can use FreeRTOS ISR calls is set to 1, which is lower than the softdevice critical priority, which makes sense. With that the case, you shouldn't have to protect SVC calls as the kernel can never interrupt one and task switch you. That would be the case with the kernel interrupt level anywhere between 0x4 and 0xf.

    interrupt priority 3 should be fine, you can even call RTOS functions from it. So your actual problem must lie elsewhere.

Reply
  • They're just my musings at this point- I'm still thinking it through and need to spend some time doing a FreeRTOS deep dive until I really feel comfortable with it.

    I just looked at a few more of the examples and actually it seems the kernel priority is 0x0f, the lowest level (and this port doesn't seem to follow the documented convention that it should be the fully-shifted, lowest bits set to 1 version, ie 0xff). The highest available interrupt which can use FreeRTOS ISR calls is set to 1, which is lower than the softdevice critical priority, which makes sense. With that the case, you shouldn't have to protect SVC calls as the kernel can never interrupt one and task switch you. That would be the case with the kernel interrupt level anywhere between 0x4 and 0xf.

    interrupt priority 3 should be fine, you can even call RTOS functions from it. So your actual problem must lie elsewhere.

Children
No Data
Related