How to implement locking between ISR and main() in a HAL-based architecture. What is the added value of __HAL_(UN)LOCK() in the HAL UART source code as it is currently implemented?
Hello,
I need an ISR that fills a circular buffer. Data will be consumed in the main() loop and critical section/mutex locking functionality is required to manage properly. So I looked at the HAL UART code for inspiration and came across __HAL_LOCK(huart)
1) What is the added value of the __HAL_LOCK(huart); and __HAL_UNLOCK(huart); statements in the HAL_UART_*** functions?
__HAL__LOCK sets the Lock member of the uart structure to HAL_LOCKED:
#define __HAL_LOCK(__HANDLE__) \
do{ \
if((__HANDLE__)->Lock == HAL_LOCKED) \
{ \
return HAL_BUSY; \
} \
else \
{ \
(__HANDLE__)->Lock = HAL_LOCKED; \
} \
}while (0U)__HAL_UNLOCK does the opposite, but there seems no active “locking�? logic implemented in the code.
Also the “while (0U)�? loop does not make that much sense to me; If the idea was to implement a kind of critical section behavior, then I would assume some interaction with enabling or disabling interrupts or some other kind of logic but, as far as I can see, there is no such thing implemented?
If I look in the files that make up the UART HAL, what I assume is that the “try lock functionality�? the author tried (?) to implement is nowhere used (return value of _HAL_LOCK() that could be used in an "if (__HAL_LOCK(__HANDLE__)== HAL_BUSY)" kind of statement.)
But even, then, using the code in such a construct seems not ok to me as the while (0U) would result an undefined return value hence undefined behavior.
On top while() loops in ISR are also not the best way to go ether.
2) How to reliably implement locking between main() and ISR?
To me blocking interrupts while addressing the circular buffer in the main() seems the way to go. Could somebody provide a reference to such an approach or present a reliable alternative approach? (ISR data can arrive any time)
Thanks for any advice,
Johi.
