]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS/Source/event_groups.c
If tickless idle mode is in use then ensure prvResetNextTaskUnblockTime() is called...
[freertos] / FreeRTOS / Source / event_groups.c
index 42579507f14b1dd35939c69f8f3ff3ecd8854516..81c1965f92e6e24f4b8c8bccd8abec31dcc1c33d 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- * FreeRTOS Kernel V10.0.1\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
  *\r
  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
  * this software and associated documentation files (the "Software"), to deal in\r
@@ -39,11 +39,11 @@ task.h is included from an application file. */
 #include "timers.h"\r
 #include "event_groups.h"\r
 \r
-/* Lint e961 and e750 are suppressed as a MISRA exception justified because the\r
-MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined for the\r
-header files above, but not in this file, in order to generate the correct\r
-privileged Vs unprivileged linkage and placement. */\r
-#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */\r
+/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified\r
+because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined\r
+for the header files above, but not in this file, in order to generate the\r
+correct privileged Vs unprivileged linkage and placement. */\r
+#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */\r
 \r
 /* The following bit fields convey control information in a task's event list\r
 item value.  It is important they don't clash with the\r
@@ -60,7 +60,7 @@ taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
        #define eventEVENT_BITS_CONTROL_BYTES   0xff000000UL\r
 #endif\r
 \r
-typedef struct xEventGroupDefinition\r
+typedef struct EventGroupDef_t\r
 {\r
        EventBits_t uxEventBits;\r
        List_t xTasksWaitingForBits;            /*< List of tasks waiting for a bit to be set. */\r
@@ -104,11 +104,11 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
                        event group structure. */\r
                        volatile size_t xSize = sizeof( StaticEventGroup_t );\r
                        configASSERT( xSize == sizeof( EventGroup_t ) );\r
-               }\r
+               } /*lint !e529 xSize is referenced if configASSERT() is defined. */\r
                #endif /* configASSERT_DEFINED */\r
 \r
                /* The user has provided a statically allocated event group - use it. */\r
-               pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 EventGroup_t and StaticEventGroup_t are guaranteed to have the same size and alignment requirement - checked by configASSERT(). */\r
+               pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */\r
 \r
                if( pxEventBits != NULL )\r
                {\r
@@ -128,10 +128,13 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
                }\r
                else\r
                {\r
+                       /* xEventGroupCreateStatic should only ever be called with\r
+                       pxEventGroupBuffer pointing to a pre-allocated (compile time\r
+                       allocated) StaticEventGroup_t variable. */\r
                        traceEVENT_GROUP_CREATE_FAILED();\r
                }\r
 \r
-               return ( EventGroupHandle_t ) pxEventBits;\r
+               return pxEventBits;\r
        }\r
 \r
 #endif /* configSUPPORT_STATIC_ALLOCATION */\r
@@ -143,8 +146,20 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
        {\r
        EventGroup_t *pxEventBits;\r
 \r
-               /* Allocate the event group. */\r
-               pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );\r
+               /* Allocate the event group.  Justification for MISRA deviation as\r
+               follows:  pvPortMalloc() always ensures returned memory blocks are\r
+               aligned per the requirements of the MCU stack.  In this case\r
+               pvPortMalloc() must return a pointer that is guaranteed to meet the\r
+               alignment requirements of the EventGroup_t structure - which (if you\r
+               follow it through) is the alignment requirements of the TickType_t type\r
+               (EventBits_t being of TickType_t itself).  Therefore, whenever the\r
+               stack alignment requirements are greater than or equal to the\r
+               TickType_t alignment requirements the cast is safe.  In other cases,\r
+               where the natural word size of the architecture is less than\r
+               sizeof( TickType_t ), the TickType_t variables will be accessed in two\r
+               or more reads operations, and the alignment requirements is only that\r
+               of each individual read. */\r
+               pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */\r
 \r
                if( pxEventBits != NULL )\r
                {\r
@@ -164,10 +179,10 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
                }\r
                else\r
                {\r
-                       traceEVENT_GROUP_CREATE_FAILED();\r
+                       traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */\r
                }\r
 \r
-               return ( EventGroupHandle_t ) pxEventBits;\r
+               return pxEventBits;\r
        }\r
 \r
 #endif /* configSUPPORT_DYNAMIC_ALLOCATION */\r
@@ -176,7 +191,7 @@ static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, co
 EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )\r
 {\r
 EventBits_t uxOriginalBitValue, uxReturn;\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t *pxEventBits = xEventGroup;\r
 BaseType_t xAlreadyYielded;\r
 BaseType_t xTimeoutOccurred = pdFALSE;\r
 \r
@@ -295,7 +310,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 \r
 EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )\r
 {\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t *pxEventBits = xEventGroup;\r
 EventBits_t uxReturn, uxControlBits = 0;\r
 BaseType_t xWaitConditionMet, xAlreadyYielded;\r
 BaseType_t xTimeoutOccurred = pdFALSE;\r
@@ -445,7 +460,7 @@ BaseType_t xTimeoutOccurred = pdFALSE;
 \r
 EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )\r
 {\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t *pxEventBits = xEventGroup;\r
 EventBits_t uxReturn;\r
 \r
        /* Check the user is not attempting to clear the bits used by the kernel\r
@@ -477,7 +492,7 @@ EventBits_t uxReturn;
                BaseType_t xReturn;\r
 \r
                traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );\r
-               xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );\r
+               xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */\r
 \r
                return xReturn;\r
        }\r
@@ -488,7 +503,7 @@ EventBits_t uxReturn;
 EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )\r
 {\r
 UBaseType_t uxSavedInterruptStatus;\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t const * const pxEventBits = xEventGroup;\r
 EventBits_t uxReturn;\r
 \r
        uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();\r
@@ -498,16 +513,16 @@ EventBits_t uxReturn;
        portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );\r
 \r
        return uxReturn;\r
-}\r
+} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */\r
 /*-----------------------------------------------------------*/\r
 \r
 EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )\r
 {\r
 ListItem_t *pxListItem, *pxNext;\r
 ListItem_t const *pxListEnd;\r
-List_t *pxList;\r
+List_t const * pxList;\r
 EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t *pxEventBits = xEventGroup;\r
 BaseType_t xMatchFound = pdFALSE;\r
 \r
        /* Check the user is not attempting to set the bits used by the kernel\r
@@ -516,7 +531,7 @@ BaseType_t xMatchFound = pdFALSE;
        configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );\r
 \r
        pxList = &( pxEventBits->xTasksWaitingForBits );\r
-       pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. */\r
+       pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM.  This is checked and valid. */\r
        vTaskSuspendAll();\r
        {\r
                traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );\r
@@ -597,7 +612,7 @@ BaseType_t xMatchFound = pdFALSE;
 \r
 void vEventGroupDelete( EventGroupHandle_t xEventGroup )\r
 {\r
-EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+EventGroup_t *pxEventBits = xEventGroup;\r
 const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );\r
 \r
        vTaskSuspendAll();\r
@@ -641,7 +656,7 @@ const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
 an interrupt. */\r
 void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )\r
 {\r
-       ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );\r
+       ( 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. */\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -649,7 +664,7 @@ void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet
 an interrupt. */\r
 void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear )\r
 {\r
-       ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear );\r
+       ( 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. */\r
 }\r
 /*-----------------------------------------------------------*/\r
 \r
@@ -695,7 +710,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
        BaseType_t xReturn;\r
 \r
                traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );\r
-               xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );\r
+               xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */\r
 \r
                return xReturn;\r
        }\r
@@ -708,7 +723,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
        UBaseType_t uxEventGroupGetNumber( void* xEventGroup )\r
        {\r
        UBaseType_t xReturn;\r
-       EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;\r
+       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. */\r
 \r
                if( xEventGroup == NULL )\r
                {\r
@@ -729,7 +744,7 @@ BaseType_t xWaitConditionMet = pdFALSE;
 \r
        void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber )\r
        {\r
-               ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber;\r
+               ( ( 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. */\r
        }\r
 \r
 #endif /* configUSE_TRACE_FACILITY */\r