Skip to main content
jVerd.1
Associate II
April 13, 2023
Solved

HAL_Delay exits from HAL_SD_RxCpltCallback

  • April 13, 2023
  • 2 replies
  • 2673 views

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.

This topic has been closed for replies.
Best answer by Bob S

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).

2 replies

MNapi
Senior II
April 13, 2023

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 ......

jVerd.1
jVerd.1Author
Associate II
April 13, 2023

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?

Bob S
Super User
April 13, 2023

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.

Bob S
Bob SBest answer
Super User
April 13, 2023

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).

jVerd.1
jVerd.1Author
Associate II
April 13, 2023

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?

Bob S
Super User
April 13, 2023

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.