philpem wrote on Wednesday, September 16, 2015:
Hi,
I’m trying to set up PC-Lint to check for correct releasing of mutexes in FreeRTOS. This is normally done by specifying semantics for the functions which perform the locking and unlocking operations, specifically:
-sem(xSemaphoreTake, thread_lock, 1p)
-sem(xSemaphoreGive, thread_unlock, 1p)
-sem(xTaskCreate, thread_create(1), 1p)
The problem is that xSemaphoreTake and xSemaphoreGive are implemented as macros:
:::c
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
This prevents PC-Lint from applying the semantics as the macro is expanded out to a call to xQueueGenericSend. There’s also a side issue relating to mutexes and semaphores being fed to the same lock and unlock functions and thus one being misinterpreted as the other, but I’ll leave that aside for the moment.
I could reimplement xSemaphoreGive as follows (and do the same to xSemaphoreTake), which allows PC-Lint to detect the lock and unlock operations:
:::c
static inline BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore )
{
return xQueueGenericSend( ( QueueHandle_t ) xSemaphore, NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK );
}
This also has the benefit of improving type safety, e.g. preventing a mistyped variable name from passing the wrong thing into xSemaphoreGive. I’ll note that I’ve seen a bug like that at work – a variable protected by a mutex was accidentally passed into the Give function, which caused said function to crash quite spectacularly. The variable names in question were something like “varName” and “varNameLock”; a developer used the autocomplete function in their editor and forgot to add the “lock” suffix. In our case, even the C compiler’s own basic type checking would have likely caught that a struct was being passed in place of a semaphore (and if not, Lint’s strict type checking could have been configured to do so).
Back to the topic at hand – the problem I have is that my suggested modification would require a lot of changes to the FreeRTOS source code.
Is there any way I can do something like this without radically altering the FreeRTOS headers?
Is there a reason FreeRTOS was implemented using macros instead of static inline functions?
Thanks,
Phil.