cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_Delay exits from HAL_SD_RxCpltCallback

jVerd.1
Associate II

When reading from the sd card is completed, HAL_SD_RxCpltCallback is executed. But when I use the HAL_Delay() function within the callback, the rest of the code within the callback after that delay doesn't run.

Any information about this issue is greatly appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

Callbacks run in the interrupt context (Called by the interrupt handler). Delays in callbacks, specially millisecond delay, are almost always a bad idea as you are delaying other (lower priority) interrupts from being serviced.

Set a flag in your callback that your main polling loop handles (or set a mutex for an RTOS thread/task to handle).

View solution in original post

10 REPLIES 10
MNapi
Senior III

HAL_Delay() does not work in callbacks.

you have to use something like this, enable timer in this case tim1.

void delay_us (uint16_t us)

{

   __HAL_TIM_SET_COUNTER(&htim1,0); // set the counter value a 0

   while (__HAL_TIM_GET_COUNTER(&htim1) < us); // wait for the counter to reach the us input in the parameter

}

or just loop for (i = 0 ......

Bob S
Principal

Callbacks run in the interrupt context (Called by the interrupt handler). Delays in callbacks, specially millisecond delay, are almost always a bad idea as you are delaying other (lower priority) interrupts from being serviced.

Set a flag in your callback that your main polling loop handles (or set a mutex for an RTOS thread/task to handle).

Thank you for the reply and the tip! Do you also know why hal_delay doesn't work in callbacks or is this just general knowledge?

Thank you for your response! Perhaps you also know if it's a bad idea to call for a callback from within another callback? Or can this be done without problems?

Generally the SYSTICK interrupt is of lower priority than most/all other interrupts. That means that when in an interrupt handler (or the callback function that called from the interrupt handler), the SYSTICK interrupt cannot be serviced. That means the tick count cannot change, the HAL_Delay() waits forever.

The hack solution is to make the SYSTICK priority higher than other interrupts. But the REAL answer is almost always to restructure your code so the interrupt handler and callbacks are are short and quick as possible. Real-time systems aren't real time if they can't service their interrupts.

As in my answer about why HAL_Delay() doesn't work from callbacks, the general rule for interrupts and callbacks is "short and quick". You can call other functions from callbacks. Just keep in mind that all of those functions are running in an interrupt context.

Generally, each callback is specific to the peripheral and event, as shown by the callback naming convention. Just from the names, it doesn't make sense to, for example, call HAL_UART_TxCpltCallback() from HAL_UART_RxCpltCallback(). I know, silly example, but that shows the idea.

If there is some common code that needs to be run from different callbacks, make it a separate function and call it from both callbacks. Better function names makes for easier to understand code.

Thank you so much for your insightful answers. Right now the code receives a command over UART, UART RX callback starts, reads data from SD card in that callback, SD RX callback starts, transmits data over UART from that callback, UART TX callback starts before all of the callbacks end. So the example you gave was quite accurate :D. So your advice is to let each callback toggle a mutex and let the RTOS deal with reading/sending on its own once the mutex is set?

How would you call a call-back?

Generally you're setting up some other event that will happen in the future.

You can initiate some different interrupt based function within a call-back, but you need to be conscious if other requests are already in-flight.

You need to change how you think/approach these things, away from linear code execution, to a more asynchronous model.

You might also want to consider if a RTOS is more appropriate for your problem, or if the HAL is too limited/restrictive

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

yes