Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suppress MISRA C:2012 rule 11.5 deviations #878

Merged
merged 16 commits into from
Dec 6, 2023
38 changes: 38 additions & 0 deletions MISRA.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,44 @@ _Ref 8.4.1_
a declaration in header file is not useful as the assembly code will
still need to declare it separately.


#### Rule 11.5
chinglee-iot marked this conversation as resolved.
Show resolved Hide resolved

_Ref 11.5.1_

- MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to
void into pointer to object.
The rule requires a pointer to void should not be converted into a pointer
to object cause this may result in a pointer that is not correctly aligned,
resulting in undefined behavior. The memory blocks allocated by pvPortMalloc()
must be guaranteed to meet the alignment requirements specified by portBYTE_ALIGMENT_MASK.
Therefore, casting the void pointer which points to the returned memory to
a pointer to object is ensured to be aligned.

_Ref 11.5.2_

- MISRA C:2012 Rule 11.5: EventGroupHandle_t is a pointer to an EventGroup_t, but
EventGroupHandle_t is kept opaque outside of this file for data hiding
purposes.

_Ref 11.5.3_

- MISRA C:2012 Rule 11.5: ` void * ` is used in list macros for list item owner as these
macros are used with tasks, timers and co-routines. Alignment is known to be
fine as the type of the pointer stored and retrieved is the same.

_Ref 11.5.4_

- MISRA C:2012 Rule 11.5: ` void * ` is used in a generic callback function prototype since
this callback is for general use case. Casting this pointer back to original
type is safe.

_Ref 11.5.5_

- MISRA C:2012 Rule 11.5: ` void * ` is converted into a pointer to uint8_t for ease of
sizing, alignment and access.


### MISRA configuration

Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel.
Expand Down
16 changes: 16 additions & 0 deletions event_groups.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
* sizeof( TickType_t ), the TickType_t variables will be accessed in two
* or more reads operations, and the alignment requirements is only that
* of each individual read. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */

if( pxEventBits != NULL )
Expand Down Expand Up @@ -740,6 +743,9 @@ void vEventGroupSetBitsCallback( void * pvEventGroup,
{
traceENTER_vEventGroupSetBitsCallback( pvEventGroup, ulBitsToSet );

/* MISRA Ref 11.5.4 [Callback function parameter] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */

traceRETURN_vEventGroupSetBitsCallback();
Expand All @@ -753,6 +759,9 @@ void vEventGroupClearBitsCallback( void * pvEventGroup,
{
traceENTER_vEventGroupClearBitsCallback( pvEventGroup, ulBitsToClear );

/* MISRA Ref 11.5.4 [Callback function parameter] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */

traceRETURN_vEventGroupClearBitsCallback();
Expand Down Expand Up @@ -822,6 +831,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
UBaseType_t uxEventGroupGetNumber( void * xEventGroup )
{
UBaseType_t xReturn;

/* MISRA Ref 11.5.2 [Opaque pointer] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */

traceENTER_uxEventGroupGetNumber( xEventGroup );
Expand Down Expand Up @@ -850,6 +863,9 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
{
traceENTER_vEventGroupSetNumber( xEventGroup, uxEventGroupNumber );

/* MISRA Ref 11.5.2 [Opaque pointer] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */

traceRETURN_vEventGroupSetNumber();
Expand Down
3 changes: 3 additions & 0 deletions queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,9 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue,
* are greater than or equal to the pointer to char requirements the cast
* is safe. In other cases alignment requirements are not strict (one or
* two bytes). */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */

if( pxNewQueue != NULL )
Expand Down
15 changes: 15 additions & 0 deletions stream_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,13 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,

if( pvAllocatedMemory != NULL )
{
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pvAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
( ( uint8_t * ) pvAllocatedMemory ) + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */
xBufferSizeBytes,
xTriggerLevelBytes,
Expand All @@ -391,6 +397,9 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,

traceRETURN_xStreamBufferGenericCreate( pvAllocatedMemory );

/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
return ( StreamBufferHandle_t ) pvAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */
}
#endif /* configSUPPORT_DYNAMIC_ALLOCATION */
Expand Down Expand Up @@ -931,6 +940,9 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
if( xDataLengthBytes != ( size_t ) 0 )
{
/* Write the data to the buffer. */
/* MISRA Ref 11.5.5 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxStreamBuffer->xHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes, xNextHead ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alignment and access. */
}

Expand Down Expand Up @@ -1195,6 +1207,9 @@ static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer,
if( xCount != ( size_t ) 0 )
{
/* Read the actual data and update the tail to mark the data as officially consumed. */
/* MISRA Ref 11.5.5 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxStreamBuffer->xTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xCount, xNextTail ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */
}

Expand Down
36 changes: 36 additions & 0 deletions tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;

if( pxTaskDefinition->puxStackBuffer != NULL )
{
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );

if( pxNewTCB != NULL )
Expand Down Expand Up @@ -1619,6 +1622,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
/* Allocate space for the TCB. Where the memory comes from depends on
* the implementation of the port malloc function and whether or not static
* allocation is being used. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) );

if( pxNewTCB != NULL )
Expand All @@ -1628,6 +1634,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
/* Allocate space for the stack used by the task being created.
* The base of the stack memory stored in the TCB so the task can
* be deleted later if required. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */

if( pxNewTCB->pxStack == NULL )
Expand All @@ -1643,11 +1652,17 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION;
StackType_t * pxStack;

/* Allocate space for the stack used by the task being created. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */

if( pxStack != NULL )
{
/* Allocate space for the TCB. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */

if( pxNewTCB != NULL )
Expand Down Expand Up @@ -3899,6 +3914,9 @@ BaseType_t xTaskResumeAll( void )
* appropriate ready list. */
while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE )
{
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
listREMOVE_ITEM( &( pxTCB->xEventListItem ) );
portMEMORY_BARRIER();
Expand Down Expand Up @@ -4701,6 +4719,9 @@ BaseType_t xTaskIncrementTick( void )
* item at the head of the delayed list. This is the time
* at which the task at the head of the delayed list must
* be removed from the Blocked state. */
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) );

Expand Down Expand Up @@ -5309,6 +5330,9 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList )
*
* This function assumes that a check has already been made to ensure that
* pxEventList is not empty. */
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
configASSERT( pxUnblockedTCB );
listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) );
Expand Down Expand Up @@ -6002,6 +6026,9 @@ static void prvCheckTasksWaitingTermination( void )
taskENTER_CRITICAL();
{
{
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
--uxCurrentNumberOfTasks;
Expand All @@ -6023,6 +6050,9 @@ static void prvCheckTasksWaitingTermination( void )
* waiting to enter the critical section. */
if( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
{
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */

if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING )
Expand Down Expand Up @@ -7170,6 +7200,9 @@ static void prvResetNextTaskUnblockTime( void )
/* Allocate an array index for each task. NOTE! if
* configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will
* equate to NULL. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */

if( pxTaskStatusArray != NULL )
Expand Down Expand Up @@ -7324,6 +7357,9 @@ static void prvResetNextTaskUnblockTime( void )
/* Allocate an array index for each task. NOTE! If
* configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will
* equate to NULL. */
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */

if( pxTaskStatusArray != NULL )
Expand Down
3 changes: 3 additions & 0 deletions timers.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,9 @@
static void prvProcessExpiredTimer( const TickType_t xNextExpireTime,
const TickType_t xTimeNow )
{
/* MISRA Ref 11.5.3 [Void pointer assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */

/* Remove the timer from the list of active timers. A check has already
Expand Down
Loading