moreshwar wrote on Tuesday, March 19, 2019:
Hello all,
I am using FreeRTOS. The board code (lower level) is autogenerated. This code calls vTaskDelay indirectly as it needs to wait for some milliseconds to allow for device initialization. The device initialization function is being called from main(). This is obvious as I need board to be initialized before creating tasks.
The device initalization function calls vTaskDelay() indirectly to delay further execution.
The device initialization function is unaware that no tasks exist when it is called.
vTaskDelay executes
/* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for
both lists. */
if( uxListRemove( &( pxCurrentTCB->xGenericListItem ) ) == ( UBaseType_t ) 0 )
Herein lies the problem
The comment says the task should remove itself from ready list
There is only one task at this stage i.e. main() . How will main remove itself?
the function
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
does not check validity of “pxItemToRemove->pxNext->pxPrevious” and “pxItemToRemove->pxPrevious->pxNext” before attempting the below assignments leading to crash.
pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
I agree that caller of vTaskDelay should have checked if there are any other tasks that can replace the current task. However, the basic rule says NULL pointer check is a must and neither vTaskDelay nor uxListRemove check that there is only one task and pointers can be NULL.
If I ask an OS to delay a task and there is no other task to replace the current task, a tight loop should be implemented in vTaskDelay or some other function provided.
There is no comment whatsoever that this function must be called if and only if there are more than one tasks and not in context of main() before any tasks are created.
It only states that “This function blocks (sleep) the current thread for a number of milliseconds.”.
I expected a comment saying that this function must not be called when this is only one task a for delay implement another function yourself if thread can’t be created.
It should be noted here that the idle task is created only when vTaskStartScheduler() and after vTaskStartScheduler(), control never returns to main() so doing any board level initalization after vTaskStartScheduler() in main() is impossible,
Can anyone confirm my finding and guide me on how to add delay in board level initialization in main() before i can create other tasks or call vTaskStartScheduler()?