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

task_yield results in hard fault.

Hi.

I have a RAK5010 i use for iot application.

i recently moved from SDK 15.20 to sdk 16.
I use the task manager to manage two tasks:

1. task to dump nrf logs

2. task to handle the GSM and  main loop.

in the near future i do expect to add some more tasks or at least use more the task_Wait, for the time being each task is a for(;;) loop with task_yield in it's end.

since sdk 16 i have an issue with task_yield, the first task task yield works fine, the other task starts running and when it calls task yield i get hard fault. The hard fault occurs since the PC is 0x0000! the LR showed me the return address is just AFTER task_switch was called from task_yield function. adding SEGGER_RTT_printf also sows that (i wrap the task_Switch function with prints, both show).
That means that after the task switch for some reason the processor is sure 0x0000 is the right address to go.

Any hint on that would be appreciated, if it's my software that corrupts the stack before the task_yield call, how do i test that ?

Parents
  • Hello,

    What does the task_yield() function do? Is it something that you wrote? What does it do?

    Are you sure you experience a hardfault, and not an APP_ERROR_CHECK()? I am just asking because these names are often mixed up. Does the log say anything?

    I know nothing about your application. What do you use? Do you use the softdevice? Any RTOS?

  • and yes i use S140 and the BT stack. i use the task switch since i dumped freerots, so no other rtos than the softdevice.

  • i don't know if the GSM module is necessary i didn't check without it, i do know that  when it calls task_switch it gets hard fault for memory region 0x00000, yes it's a hard fault i got the hardfault module from the sdk compiled in and i checked the registers state when i got the breakpoint, it was definatly not an assert, what's more all the asserts are BEFORE the call to task_switch and the exception according to LR happens AFTER the return from the function.

  • It is difficult to say exactly whats going on here. Perhaps you pass on a bad pointer somewhere (NULL) you change some data that is too long for the data type you are using somewhere in your code? What is in the SP register when you get the hardfault?

  • could be that i wrote to an invalid address of course, however, once removed the task manager (again one task was just flushing the logs...) i don't get those hardfaults anymore, not surprising since i got them from task_switch that is not called anymore.

    How do i retrive the SP during the hardfault ? one register up from the stacked PC ?

  • Hello,

    You can do a register read command using the nrfjprog (nRF command line tools). You can use the command "nrfjprog --readregs" and it will print out all the registers.

    You say that you added a task to flash the logs. Do you call this task from several places? That is, is it a risk for the log flush to be interrupted by another log flush? If so, then this may be the issue. You should only flush the logs from one instance, because of how it the log module is built up, it may cause an issue if it is flushed from several places.

    BR,

    Edvin

  • not really.
    I have 2 tasks, 3 if you include the idle task.
    1 in the main loop, the other can be considered the "flush log thread". however you and me both know that until the yield the task wont end so it's not really a "thread" per se.
    In any case i call the flush in the end of each loop in my main loop and in the logger thread. the yield will take place only after the flush is over, flush is blocking as far as i know there for what you describe cannot occur.

Reply
  • not really.
    I have 2 tasks, 3 if you include the idle task.
    1 in the main loop, the other can be considered the "flush log thread". however you and me both know that until the yield the task wont end so it's not really a "thread" per se.
    In any case i call the flush in the end of each loop in my main loop and in the logger thread. the yield will take place only after the flush is over, flush is blocking as far as i know there for what you describe cannot occur.

Children
Related