From 0cc70257f67e1a4997eb7424022923d7c8e5b9ec Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 3 Nov 2023 09:30:04 +0000 Subject: [PATCH 01/11] Suppress MISRA C:2012 rule 11.5 deviations by comment --- MISRA.md | 38 ++++++++++++++++++++++++++++++++++++++ event_groups.c | 16 ++++++++++++++++ queue.c | 3 +++ stream_buffer.c | 15 +++++++++++++++ tasks.c | 36 ++++++++++++++++++++++++++++++++++++ timers.c | 3 +++ 6 files changed, 111 insertions(+) diff --git a/MISRA.md b/MISRA.md index e7ebf77ea6a..d7457b88cd5 100644 --- a/MISRA.md +++ b/MISRA.md @@ -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 + +_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 coverted into a pointer + to object cause this may result in a pointer that is not correctly aligned, + resulting in undefined behaviour. 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. Alighment 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. diff --git a/event_groups.c b/event_groups.c index 556637b4cda..2f2833a8c53 100644 --- a/event_groups.c +++ b/event_groups.c @@ -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 ) @@ -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(); @@ -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(); @@ -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 ); @@ -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(); diff --git a/queue.c b/queue.c index 3bc959721ed..1f7020e738c 100644 --- a/queue.c +++ b/queue.c @@ -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 ) diff --git a/stream_buffer.c b/stream_buffer.c index 32aa8e4f2b3..e299b873c32 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -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, @@ -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 */ @@ -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. */ } @@ -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. */ } diff --git a/tasks.c b/tasks.c index 2e1cce402ed..41ff8c44373 100644 --- a/tasks.c +++ b/tasks.c @@ -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 ) @@ -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 ) @@ -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 ) @@ -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 ) @@ -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(); @@ -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 ) ); @@ -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 ) ); @@ -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; @@ -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 ) @@ -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 ) @@ -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 ) diff --git a/timers.c b/timers.c index bff14ea7ecb..2e439a2fd2e 100644 --- a/timers.c +++ b/timers.c @@ -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 From 76c69a9ab178fbd1daf1b8819f4c2bb71447ebe1 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 3 Nov 2023 09:32:49 +0000 Subject: [PATCH 02/11] Fix typo --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index d7457b88cd5..36709d5b143 100644 --- a/MISRA.md +++ b/MISRA.md @@ -40,7 +40,7 @@ _Ref 11.5.1_ void into pointer to object. The rule requires a pointer to void should not be coverted into a pointer to object cause this may result in a pointer that is not correctly aligned, - resulting in undefined behaviour. The memory blocks allocated by pvPortMalloc() + 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. From 06f6789f75fe1c530f9f28eac6ff67768576d8a4 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 3 Nov 2023 09:33:35 +0000 Subject: [PATCH 03/11] Fix typo --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index 36709d5b143..f6ef1c853ae 100644 --- a/MISRA.md +++ b/MISRA.md @@ -38,7 +38,7 @@ _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 coverted into a pointer + 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. From ad777e80a1d9d76dee03b274edc685b38739cebf Mon Sep 17 00:00:00 2001 From: Rahul Kar Date: Fri, 3 Nov 2023 09:54:57 +0000 Subject: [PATCH 04/11] Fix spell check error and formatting --- MISRA.md | 8 ++++---- stream_buffer.c | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MISRA.md b/MISRA.md index f6ef1c853ae..f793d6c6f40 100644 --- a/MISRA.md +++ b/MISRA.md @@ -53,19 +53,19 @@ _Ref 11.5.2_ _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. Alighment is known to be +- 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 +- 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 +- MISRA C:2012 Rule 11.5: ` void * ` is converted into a pointer to uint8_t for ease of sizing, alignment and access. diff --git a/stream_buffer.c b/stream_buffer.c index e299b873c32..1444462e6e5 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -378,9 +378,9 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* 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] */ + /* 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, From abbeda51e3074ce31c8e2fa0beb04b4a9ed0fb1f Mon Sep 17 00:00:00 2001 From: Rahul Kar Date: Fri, 3 Nov 2023 09:59:54 +0000 Subject: [PATCH 05/11] Fix typo --- MISRA.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MISRA.md b/MISRA.md index f793d6c6f40..307386d5e17 100644 --- a/MISRA.md +++ b/MISRA.md @@ -41,7 +41,7 @@ _Ref 11.5.1_ 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. + must be guaranteed to meet the alignment requirements specified by portBYTE_ALIGNMENT_MASK. Therefore, casting the void pointer which points to the returned memory to a pointer to object is ensured to be aligned. From 289dc3b14e444a270adcbf79360ea00da3bfd40e Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 6 Nov 2023 04:31:34 +0000 Subject: [PATCH 06/11] Update more deviations --- tasks.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tasks.c b/tasks.c index 41ff8c44373..aa77bc6cc19 100644 --- a/tasks.c +++ b/tasks.c @@ -4128,10 +4128,16 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { + /* 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] */ listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*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. */ do { + /* 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] */ listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*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. */ /* Check each character in the name looking for a match or @@ -6222,6 +6228,9 @@ static void prvCheckTasksWaitingTermination( void ) if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) { + /* 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] */ listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*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. */ /* Populate an TaskStatus_t structure within the @@ -6230,6 +6239,9 @@ static void prvCheckTasksWaitingTermination( void ) * meaning of each TaskStatus_t structure member. */ do { + /* 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] */ listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*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. */ vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); uxTask++; From 7b969ff0f0303a0fa049baa5766817968130a9f5 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 6 Nov 2023 04:35:56 +0000 Subject: [PATCH 07/11] Fix more 11.5 rule deviations --- croutine.c | 3 +++ tasks.c | 9 +++++++++ timers.c | 3 +++ 3 files changed, 15 insertions(+) diff --git a/croutine.c b/croutine.c index f7d8ab95dd7..daa88275f01 100644 --- a/croutine.c +++ b/croutine.c @@ -110,6 +110,9 @@ traceENTER_xCoRoutineCreate( pxCoRoutineCode, uxPriority, uxIndex ); /* Allocate the memory that will store the co-routine control block. */ + /* 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] */ pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); if( pxCoRoutine ) diff --git a/tasks.c b/tasks.c index aa77bc6cc19..de4f1a92218 100644 --- a/tasks.c +++ b/tasks.c @@ -1035,6 +1035,9 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; for( pxIterator = listGET_HEAD_ENTRY( pxReadyList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { + /* 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] */ TCB_t * pxTCB = ( TCB_t * ) listGET_LIST_ITEM_OWNER( pxIterator ); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) @@ -4202,6 +4205,9 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char { for( pxIterator = listGET_HEAD_ENTRY( pxList ); pxIterator != pxEndMarker; pxIterator = listGET_NEXT( pxIterator ) ) { + /* 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] */ TCB_t * pxTCB = listGET_LIST_ITEM_OWNER( pxIterator ); /* Check each character in the name looking for a match or @@ -5425,6 +5431,9 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, /* Remove the event list form the event flag. Interrupts do not access * event flags. */ + /* 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_LIST_ITEM_OWNER( pxEventListItem ); /*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( pxEventListItem ); diff --git a/timers.c b/timers.c index 2e439a2fd2e..ffc611442ac 100644 --- a/timers.c +++ b/timers.c @@ -349,6 +349,9 @@ traceENTER_xTimerCreate( pcTimerName, xTimerPeriodInTicks, xAutoReload, pvTimerID, pxCallbackFunction ); + /* 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] */ pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_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 Timer_t is always a pointer to the timer's name. */ if( pxNewTimer != NULL ) From 7518cf396fda1ab734b52a9994b8747010ff8f55 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 6 Nov 2023 04:38:49 +0000 Subject: [PATCH 08/11] Fix more deviations --- tasks.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasks.c b/tasks.c index de4f1a92218..11bbb266ddc 100644 --- a/tasks.c +++ b/tasks.c @@ -5105,6 +5105,9 @@ BaseType_t xTaskIncrementTick( void ) /* Select a new task to run using either the generic C or port * optimised asm code. */ + /* 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] */ taskSELECT_HIGHEST_PRIORITY_TASK(); /*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. */ traceTASK_SWITCHED_IN(); From 6951c19dad28e2a675f9a0ac5a5116595c500f1b Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 10 Nov 2023 08:09:05 +0000 Subject: [PATCH 09/11] Also remove this rule in global config --- MISRA.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/MISRA.md b/MISRA.md index 307386d5e17..abd5c83ce8d 100644 --- a/MISRA.md +++ b/MISRA.md @@ -100,11 +100,7 @@ Copy below content to `misra.conf` to run Coverity on FreeRTOS-Kernel. { deviation: "Rule 8.7", reason: "API functions are not used by the library outside of the files they are defined; however, they must be externally visible in order to be used by an application." - }, - { - deviation: "Rule 11.5", - reason: "Allow casts from `void *`. List owner, pvOwner, is stored as `void *` and are cast to various types for use in functions." } ] } -``` \ No newline at end of file +``` From 04721e7d3e2fd8406503e6806d8b7c2d202f8173 Mon Sep 17 00:00:00 2001 From: Gaurav Aggarwal Date: Tue, 5 Dec 2023 11:59:46 +0000 Subject: [PATCH 10/11] Code review suggestions Signed-off-by: Gaurav Aggarwal --- MISRA.md | 44 ++++++++++++++++++++++---------------------- event_groups.c | 23 +++++------------------ queue.c | 11 +---------- stream_buffer.c | 10 +++++----- tasks.c | 32 ++++++++++++++++---------------- timers.c | 4 ++-- 6 files changed, 51 insertions(+), 73 deletions(-) diff --git a/MISRA.md b/MISRA.md index db929a2cb4c..7606014f173 100644 --- a/MISRA.md +++ b/MISRA.md @@ -50,39 +50,39 @@ _Ref 11.3.1_ #### Rule 11.5 -_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_ALIGNMENT_MASK. - Therefore, casting the void pointer which points to the returned memory to - a pointer to object is ensured to be aligned. + This rule prohibits conversion of a pointer to void into a pointer to + object because it may result in an incorrectly aligned pointer leading + to undefined behavior. -_Ref 11.5.2_ +_Ref 11.5.1_ + The memory blocks returned by pvPortMalloc() are guaranteed to meet the + architecture alignment requirements specified by portBYTE_ALIGNMENT. + The casting of the pointer to void returned by pvPortMalloc() is, + therefore, safe because it is guaranteed to be aligned. -- 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 +_Ref 11.5.2_ + The conversion from a pointer to void into a pointer to EventGroup_t is + safe because it is a pointer to EventGroup_t, which is returned to the + application at the time of event group creation 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. + The conversion from a pointer to void in list macros for list item owner + is safe because 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. + The conversion from a pointer to void into a pointer to EventGroup_t is + safe because it is a pointer to EventGroup_t, which is passed as a + parameter to the xTimerPendFunctionCallFromISR API when the callback is + pended. _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. + The conversion from a pointer to void into a pointer to uint8_t is safe + because data storage buffers are implemented as uint8_t arrays for the + ease of sizing, alignment and access. ### MISRA configuration diff --git a/event_groups.c b/event_groups.c index 6ff5cc2cfc4..68f8e9ddb6a 100644 --- a/event_groups.c +++ b/event_groups.c @@ -143,23 +143,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, traceENTER_xEventGroupCreate(); - /* Allocate the event group. Justification for MISRA deviation as - * follows: pvPortMalloc() always ensures returned memory blocks are - * aligned per the requirements of the MCU stack. In this case - * pvPortMalloc() must return a pointer that is guaranteed to meet the - * alignment requirements of the EventGroup_t structure - which (if you - * follow it through) is the alignment requirements of the TickType_t type - * (EventBits_t being of TickType_t itself). Therefore, whenever the - * stack alignment requirements are greater than or equal to the - * TickType_t alignment requirements the cast is safe. In other cases, - * where the natural word size of the architecture is less than - * 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. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); if( pxEventBits != NULL ) { @@ -755,7 +742,7 @@ void vEventGroupSetBitsCallback( void * pvEventGroup, /* 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. */ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); traceRETURN_vEventGroupSetBitsCallback(); } @@ -771,7 +758,7 @@ void vEventGroupClearBitsCallback( void * pvEventGroup, /* 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. */ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); traceRETURN_vEventGroupClearBitsCallback(); } @@ -844,7 +831,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, /* 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. */ + EventGroup_t const * pxEventBits = ( EventGroup_t * ) xEventGroup; traceENTER_uxEventGroupGetNumber( xEventGroup ); @@ -875,7 +862,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, /* 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. */ + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; traceRETURN_vEventGroupSetNumber(); } diff --git a/queue.c b/queue.c index 015a1572967..1aabc9f3195 100644 --- a/queue.c +++ b/queue.c @@ -517,19 +517,10 @@ BaseType_t xQueueGenericReset( QueueHandle_t xQueue, * zero in the case the queue is used as a semaphore. */ xQueueSizeInBytes = ( size_t ) ( ( size_t ) uxQueueLength * ( size_t ) uxItemSize ); - /* Allocate the queue and storage area. Justification for MISRA - * deviation as follows: pvPortMalloc() always ensures returned memory - * blocks are aligned per the requirements of the MCU stack. In this case - * pvPortMalloc() must return a pointer that is guaranteed to meet the - * alignment requirements of the Queue_t structure - which in this case - * is an int8_t *. Therefore, whenever the stack alignment requirements - * 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. */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); if( pxNewQueue != NULL ) { diff --git a/stream_buffer.c b/stream_buffer.c index 8b3649d5c35..d6a9ffffc81 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -377,11 +377,11 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* 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. */ + prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pvAllocatedMemory, /* Structure at the start of the allocated memory. */ /* 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. */ + ( ( uint8_t * ) pvAllocatedMemory ) + sizeof( StreamBuffer_t ), /* Storage area follows. */ xBufferSizeBytes, xTriggerLevelBytes, ucFlags, @@ -400,7 +400,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, /* 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. */ + return ( StreamBufferHandle_t ) pvAllocatedMemory; } #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ /*-----------------------------------------------------------*/ @@ -952,7 +952,7 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, /* 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. */ + pxStreamBuffer->xHead = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes, xNextHead ); } return xDataLengthBytes; @@ -1219,7 +1219,7 @@ static size_t prvReadMessageFromBuffer( StreamBuffer_t * pxStreamBuffer, /* 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. */ + pxStreamBuffer->xTail = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xCount, xNextTail ); } return xCount; diff --git a/tasks.c b/tasks.c index 424da42cfcb..a9427539aab 100644 --- a/tasks.c +++ b/tasks.c @@ -1643,7 +1643,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* 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. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); if( pxNewTCB->pxStack == NULL ) { @@ -1661,7 +1661,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* 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. */ + pxStack = pvPortMallocStack( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); if( pxStack != NULL ) { @@ -1669,7 +1669,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; /* 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. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); if( pxNewTCB != NULL ) { @@ -3958,7 +3958,7 @@ BaseType_t xTaskResumeAll( void ) /* 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. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); listREMOVE_ITEM( &( pxTCB->xEventListItem ) ); portMEMORY_BARRIER(); listREMOVE_ITEM( &( pxTCB->xStateListItem ) ); @@ -4172,14 +4172,14 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char /* 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] */ - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*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. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); do { /* 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] */ - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*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. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /* Check each character in the name looking for a match or * mismatch. */ @@ -4771,7 +4771,7 @@ BaseType_t xTaskIncrementTick( void ) /* 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. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); if( xConstTickCount < xItemValue ) @@ -5145,7 +5145,7 @@ BaseType_t xTaskIncrementTick( void ) /* 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] */ - taskSELECT_HIGHEST_PRIORITY_TASK(); /*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. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); traceTASK_SWITCHED_IN(); /* After the new task is switched in, update the global errno. */ @@ -5385,7 +5385,7 @@ BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) /* 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. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( &( pxUnblockedTCB->xEventListItem ) ); @@ -5474,7 +5474,7 @@ void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, /* 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_LIST_ITEM_OWNER( pxEventListItem ); /*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. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); configASSERT( pxUnblockedTCB ); listREMOVE_ITEM( pxEventListItem ); @@ -6084,7 +6084,7 @@ static void prvCheckTasksWaitingTermination( void ) /* 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. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); --uxCurrentNumberOfTasks; --uxDeletedTasksWaitingCleanUp; @@ -6108,7 +6108,7 @@ static void prvCheckTasksWaitingTermination( void ) /* 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. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); if( pxTCB->xTaskRunState == taskTASK_NOT_RUNNING ) { @@ -6298,7 +6298,7 @@ static void prvCheckTasksWaitingTermination( void ) /* 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] */ - listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*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. */ + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /* Populate an TaskStatus_t structure within the * pxTaskStatusArray array for each task that is referenced from @@ -6309,7 +6309,7 @@ static void prvCheckTasksWaitingTermination( void ) /* 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] */ - listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*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. */ + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); uxTask++; } while( pxNextTCB != pxFirstTCB ); @@ -7282,7 +7282,7 @@ static void prvResetNextTaskUnblockTime( void ) /* 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. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) { @@ -7444,7 +7444,7 @@ static void prvResetNextTaskUnblockTime( void ) /* 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. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); if( pxTaskStatusArray != NULL ) { diff --git a/timers.c b/timers.c index 5591816cc4e..2d24bf04247 100644 --- a/timers.c +++ b/timers.c @@ -352,7 +352,7 @@ /* 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] */ - pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_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 Timer_t is always a pointer to the timer's name. */ + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); if( pxNewTimer != NULL ) { @@ -727,7 +727,7 @@ /* 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. */ + Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /* Remove the timer from the list of active timers. A check has already * been performed to ensure the list is not empty. */ From d70d1048f78f752af9ddc06b99484d87b02e19d4 Mon Sep 17 00:00:00 2001 From: chinglee-iot <61685396+chinglee-iot@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:13:29 +0800 Subject: [PATCH 11/11] Update MISRA.md --- MISRA.md | 89 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/MISRA.md b/MISRA.md index 7606014f173..33e96681744 100644 --- a/MISRA.md +++ b/MISRA.md @@ -20,69 +20,72 @@ grep 'MISRA Ref 8.4.1' . -rI #### Rule 8.4 +MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an + object or function with external linkage is defined. + _Ref 8.4.1_ -- MISRA C:2012 Rule 8.4: A compatible declaration shall be visible when an - object or function with external linkage is defined. - This rule requires that a compatible declaration is made available - in a header file when an object with external linkage is defined. - pxCurrentTCB(s) is defined with external linkage but it is only - referenced from the assembly code in the port files. Therefore, adding - a declaration in header file is not useful as the assembly code will - still need to declare it separately. +- This rule requires that a compatible declaration is made available + in a header file when an object with external linkage is defined. + pxCurrentTCB(s) is defined with external linkage but it is only + referenced from the assembly code in the port files. Therefore, adding + a declaration in header file is not useful as the assembly code will + still need to declare it separately. + #### Rule 11.3 +MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to +object type and a pointer to a different object type. + _Ref 11.3.1_ + - This rule prohibits casting a pointer to object into a pointer to a + different object because it may result in an incorrectly aligned pointer, + leading to undefined behavior. Even if the casting produces a correctly + aligned pointer, the behavior may be still undefined if the pointer is + used to access an object. FreeRTOS deliberately creates external aliases + for all the kernel object types (StaticEventGroup_t, StaticQueue_t, + StaticStreamBuffer_t, StaticTimer_t and StaticTask_t) for data hiding + purposes. The internal object types and the corresponding external + aliases are guaranteed to have the same size and alignment which is + checked using configASSERT. -- MISRA C:2012 Rule 11.3: A cast shall not be performed between a pointer to - object type and a pointer to a different object type. - This rule prohibits casting a pointer to object into a pointer to a - different object because it may result in an incorrectly aligned pointer, - leading to undefined behavior. Even if the casting produces a correctly - aligned pointer, the behavior may be still undefined if the pointer is - used to access an object. FreeRTOS deliberately creates external aliases - for all the kernel object types (StaticEventGroup_t, StaticQueue_t, - StaticStreamBuffer_t, StaticTimer_t and StaticTask_t) for data hiding - purposes. The internal object types and the corresponding external - aliases are guaranteed to have the same size and alignment which is - checked using configASSERT. #### Rule 11.5 -- MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to - void into pointer to object. - This rule prohibits conversion of a pointer to void into a pointer to - object because it may result in an incorrectly aligned pointer leading - to undefined behavior. +MISRA C:2012 Rule 11.5: A conversion should not be performed from pointer to +void into pointer to object. +This rule prohibits conversion of a pointer to void into a pointer to +object because it may result in an incorrectly aligned pointer leading +to undefined behavior. _Ref 11.5.1_ - The memory blocks returned by pvPortMalloc() are guaranteed to meet the - architecture alignment requirements specified by portBYTE_ALIGNMENT. - The casting of the pointer to void returned by pvPortMalloc() is, - therefore, safe because it is guaranteed to be aligned. + - The memory blocks returned by pvPortMalloc() are guaranteed to meet the + architecture alignment requirements specified by portBYTE_ALIGNMENT. + The casting of the pointer to void returned by pvPortMalloc() is, + therefore, safe because it is guaranteed to be aligned. _Ref 11.5.2_ - The conversion from a pointer to void into a pointer to EventGroup_t is - safe because it is a pointer to EventGroup_t, which is returned to the - application at the time of event group creation for data hiding - purposes. + - The conversion from a pointer to void into a pointer to EventGroup_t is + safe because it is a pointer to EventGroup_t, which is returned to the + application at the time of event group creation for data hiding + purposes. _Ref 11.5.3_ - The conversion from a pointer to void in list macros for list item owner - is safe because the type of the pointer stored and retrieved is the - same. + - The conversion from a pointer to void in list macros for list item owner + is safe because the type of the pointer stored and retrieved is the + same. _Ref 11.5.4_ - The conversion from a pointer to void into a pointer to EventGroup_t is - safe because it is a pointer to EventGroup_t, which is passed as a - parameter to the xTimerPendFunctionCallFromISR API when the callback is - pended. + - The conversion from a pointer to void into a pointer to EventGroup_t is + safe because it is a pointer to EventGroup_t, which is passed as a + parameter to the xTimerPendFunctionCallFromISR API when the callback is + pended. _Ref 11.5.5_ - The conversion from a pointer to void into a pointer to uint8_t is safe - because data storage buffers are implemented as uint8_t arrays for the - ease of sizing, alignment and access. + - The conversion from a pointer to void into a pointer to uint8_t is safe + because data storage buffers are implemented as uint8_t arrays for the + ease of sizing, alignment and access. ### MISRA configuration