There are some things that I don’t understand in ff_locking.c :
153 /* Called when a task want to make changes to a directory.
154 First it waits for the desired bit to come high. */
155 xEventGroupWaitBits( pxIOManager->xEventGroup,
156 FF_DIR_LOCK_EVENT_BITS, /* uxBitsToWaitFor */
157 ( EventBits_t )0, /* xClearOnExit */
Why the cast? This parameter should be const BaseType_t xClearOnExit
.
158 pdFALSE, /* xWaitForAllBits n.a. */
159 pdMS_TO_TICKS( 10000UL ) );
160
161 /* The next operation will only succeed for 1 task at a time,
162 because it is an atomary test & set operation: */
163 xBits = xEventGroupClearBits( pxIOManager->xEventGroup, FF_DIR_LOCK_EVENT_BITS );
The comment on lines 161 and 162 seems contradictory to this explanation in Mastering the FreeRTOS Real Time Kernel; A Hands-On Tutorial Guide; Richard Barry; Pre-release 161204 Edition:
Event bits can be cleared using the xEventGroupClearBits() API function, but using that
function to manually clear event bits will lead to race conditions in the application code if:
- There is more than one task using the same event group.
- Bits are set in the event group by a different task, or by an interrupt service routine.
The xClearOnExit parameter is provided to avoid these potential race conditions. If
xClearOnExit is set to pdTRUE, then the testing and clearing of event bits appears to the
calling task to be an atomic operation (uninterruptable by other tasks or interrupts).
The same code is repeated a couple of more times. Next,
315 void FF_BufferProceed( FF_IOManager_t *pxIOManager )
…
322 /* Wake-up all tasks that are waiting for a sector buffer to become available. */
323 xEventGroupSetBits( pxIOManager->xEventGroup, FF_BUF_LOCK_EVENT_BITS );
The comment seems misleading to me. I would expect it to wake up one task. Or, does this have something to do with the way xClearOnExit
is set to false, above?
UPDATE: Here is my proposed rewrite: ff_locking.c (8.9 KB)