feat: initial
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
.DS_Store
 | 
			
		||||
							
								
								
									
										45
									
								
								README.md
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										45
									
								
								README.md
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							@@ -1,3 +1,44 @@
 | 
			
		||||
# zh_avr_free_rtos
 | 
			
		||||
# FreeRTOS (v11.1) port for AVR 8bit microcontrollers
 | 
			
		||||
 | 
			
		||||
FreeRTOS (v11.1) port for AVR 8bit microcontrollers.
 | 
			
		||||
## Using
 | 
			
		||||
 | 
			
		||||
In an existing project, run the following command to install the component:
 | 
			
		||||
 | 
			
		||||
```text
 | 
			
		||||
cd ../your_project/lib
 | 
			
		||||
git clone http://git.zh.com.ru/alexey.zholtikov/zh_avr_free_rtos
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In the application, add the component:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Example
 | 
			
		||||
 | 
			
		||||
Led blink:
 | 
			
		||||
 | 
			
		||||
```c
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "avr/io.h"
 | 
			
		||||
 | 
			
		||||
void led_flash_task(void *pvParameters)
 | 
			
		||||
{
 | 
			
		||||
    DDRB |= (1 << PORTB5);
 | 
			
		||||
    for (;;)
 | 
			
		||||
    {
 | 
			
		||||
        PORTB ^= (1 << PORTB5);
 | 
			
		||||
        vTaskDelay(1000 / portTICK_PERIOD_MS);
 | 
			
		||||
    }
 | 
			
		||||
    vTaskDelete(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
    xTaskCreate(led_flash_task, "led flash task", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
 | 
			
		||||
    vTaskStartScheduler();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										405
									
								
								croutine.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								croutine.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,405 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "croutine.h"
 | 
			
		||||
 | 
			
		||||
/* Remove the whole file if co-routines are not being used. */
 | 
			
		||||
#if ( configUSE_CO_ROUTINES != 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Some kernel aware debuggers require data to be viewed to be global, rather
 | 
			
		||||
 * than file scope.
 | 
			
		||||
 */
 | 
			
		||||
    #ifdef portREMOVE_STATIC_QUALIFIER
 | 
			
		||||
        #define static
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Lists for ready and blocked co-routines. --------------------*/
 | 
			
		||||
    static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /**< Prioritised ready co-routines. */
 | 
			
		||||
    static List_t xDelayedCoRoutineList1;                                   /**< Delayed co-routines. */
 | 
			
		||||
    static List_t xDelayedCoRoutineList2;                                   /**< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
 | 
			
		||||
    static List_t * pxDelayedCoRoutineList = NULL;                          /**< Points to the delayed co-routine list currently being used. */
 | 
			
		||||
    static List_t * pxOverflowDelayedCoRoutineList = NULL;                  /**< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
 | 
			
		||||
    static List_t xPendingReadyCoRoutineList;                               /**< Holds co-routines that have been readied by an external event.  They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
 | 
			
		||||
 | 
			
		||||
/* Other file private variables. --------------------------------*/
 | 
			
		||||
    CRCB_t * pxCurrentCoRoutine = NULL;
 | 
			
		||||
    static UBaseType_t uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
 | 
			
		||||
    static TickType_t xCoRoutineTickCount = ( TickType_t ) 0U;
 | 
			
		||||
    static TickType_t xLastTickCount = ( TickType_t ) 0U;
 | 
			
		||||
    static TickType_t xPassedTicks = ( TickType_t ) 0U;
 | 
			
		||||
 | 
			
		||||
/* The initial state of the co-routine when it is created. */
 | 
			
		||||
    #define corINITIAL_STATE    ( 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Place the co-routine represented by pxCRCB into the appropriate ready queue
 | 
			
		||||
 * for the priority.  It is inserted at the end of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * This macro accesses the co-routine ready lists and therefore must not be
 | 
			
		||||
 * used from within an ISR.
 | 
			
		||||
 */
 | 
			
		||||
    #define prvAddCoRoutineToReadyQueue( pxCRCB )                                                                               \
 | 
			
		||||
    do {                                                                                                                        \
 | 
			
		||||
        if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority )                                                              \
 | 
			
		||||
        {                                                                                                                       \
 | 
			
		||||
            uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority;                                                               \
 | 
			
		||||
        }                                                                                                                       \
 | 
			
		||||
        vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Utility to ready all the lists used by the scheduler.  This is called
 | 
			
		||||
 * automatically upon the creation of the first co-routine.
 | 
			
		||||
 */
 | 
			
		||||
    static void prvInitialiseCoRoutineLists( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Co-routines that are readied by an interrupt cannot be placed directly into
 | 
			
		||||
 * the ready lists (there is no mutual exclusion).  Instead they are placed in
 | 
			
		||||
 * in the pending ready list in order that they can later be moved to the ready
 | 
			
		||||
 * list by the co-routine scheduler.
 | 
			
		||||
 */
 | 
			
		||||
    static void prvCheckPendingReadyList( void );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Macro that looks at the list of co-routines that are currently delayed to
 | 
			
		||||
 * see if any require waking.
 | 
			
		||||
 *
 | 
			
		||||
 * Co-routines are stored in the queue in the order of their wake time -
 | 
			
		||||
 * meaning once one co-routine has been found whose timer has not expired
 | 
			
		||||
 * we need not look any further down the list.
 | 
			
		||||
 */
 | 
			
		||||
    static void prvCheckDelayedList( void );
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
 | 
			
		||||
                                 UBaseType_t uxPriority,
 | 
			
		||||
                                 UBaseType_t uxIndex )
 | 
			
		||||
    {
 | 
			
		||||
        BaseType_t xReturn;
 | 
			
		||||
        CRCB_t * pxCoRoutine;
 | 
			
		||||
 | 
			
		||||
        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 )
 | 
			
		||||
        {
 | 
			
		||||
            /* If pxCurrentCoRoutine is NULL then this is the first co-routine to
 | 
			
		||||
            * be created and the co-routine data structures need initialising. */
 | 
			
		||||
            if( pxCurrentCoRoutine == NULL )
 | 
			
		||||
            {
 | 
			
		||||
                pxCurrentCoRoutine = pxCoRoutine;
 | 
			
		||||
                prvInitialiseCoRoutineLists();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Check the priority is within limits. */
 | 
			
		||||
            if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
 | 
			
		||||
            {
 | 
			
		||||
                uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Fill out the co-routine control block from the function parameters. */
 | 
			
		||||
            pxCoRoutine->uxState = corINITIAL_STATE;
 | 
			
		||||
            pxCoRoutine->uxPriority = uxPriority;
 | 
			
		||||
            pxCoRoutine->uxIndex = uxIndex;
 | 
			
		||||
            pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
 | 
			
		||||
 | 
			
		||||
            /* Initialise all the other co-routine control block parameters. */
 | 
			
		||||
            vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
 | 
			
		||||
            vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
            /* Set the co-routine control block as a link back from the ListItem_t.
 | 
			
		||||
             * This is so we can get back to the containing CRCB from a generic item
 | 
			
		||||
             * in a list. */
 | 
			
		||||
            listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
 | 
			
		||||
            listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
 | 
			
		||||
 | 
			
		||||
            /* Event lists are always in priority order. */
 | 
			
		||||
            listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
 | 
			
		||||
 | 
			
		||||
            /* Now the co-routine has been initialised it can be added to the ready
 | 
			
		||||
             * list at the correct priority. */
 | 
			
		||||
            prvAddCoRoutineToReadyQueue( pxCoRoutine );
 | 
			
		||||
 | 
			
		||||
            xReturn = pdPASS;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xCoRoutineCreate( xReturn );
 | 
			
		||||
 | 
			
		||||
        return xReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
 | 
			
		||||
                                     List_t * pxEventList )
 | 
			
		||||
    {
 | 
			
		||||
        TickType_t xTimeToWake;
 | 
			
		||||
 | 
			
		||||
        traceENTER_vCoRoutineAddToDelayedList( xTicksToDelay, pxEventList );
 | 
			
		||||
 | 
			
		||||
        /* Calculate the time to wake - this may overflow but this is
 | 
			
		||||
         * not a problem. */
 | 
			
		||||
        xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
 | 
			
		||||
 | 
			
		||||
        /* We must remove ourselves from the ready list before adding
 | 
			
		||||
         * ourselves to the blocked list as the same list item is used for
 | 
			
		||||
         * both lists. */
 | 
			
		||||
        ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
 | 
			
		||||
        /* The list item will be inserted in wake time order. */
 | 
			
		||||
        listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
 | 
			
		||||
 | 
			
		||||
        if( xTimeToWake < xCoRoutineTickCount )
 | 
			
		||||
        {
 | 
			
		||||
            /* Wake time has overflowed.  Place this item in the
 | 
			
		||||
             * overflow list. */
 | 
			
		||||
            vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* The wake time has not overflowed, so we can use the
 | 
			
		||||
             * current block list. */
 | 
			
		||||
            vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( pxEventList )
 | 
			
		||||
        {
 | 
			
		||||
            /* Also add the co-routine to an event list.  If this is done then the
 | 
			
		||||
             * function must be called with interrupts disabled. */
 | 
			
		||||
            vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceRETURN_vCoRoutineAddToDelayedList();
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    static void prvCheckPendingReadyList( void )
 | 
			
		||||
    {
 | 
			
		||||
        /* Are there any co-routines waiting to get moved to the ready list?  These
 | 
			
		||||
         * are co-routines that have been readied by an ISR.  The ISR cannot access
 | 
			
		||||
         * the ready lists itself. */
 | 
			
		||||
        while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
 | 
			
		||||
        {
 | 
			
		||||
            CRCB_t * pxUnblockedCRCB;
 | 
			
		||||
 | 
			
		||||
            /* The pending ready list can be accessed by an ISR. */
 | 
			
		||||
            portDISABLE_INTERRUPTS();
 | 
			
		||||
            {
 | 
			
		||||
                pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyCoRoutineList ) );
 | 
			
		||||
                ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
            }
 | 
			
		||||
            portENABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
            ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
 | 
			
		||||
            prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    static void prvCheckDelayedList( void )
 | 
			
		||||
    {
 | 
			
		||||
        CRCB_t * pxCRCB;
 | 
			
		||||
 | 
			
		||||
        xPassedTicks = xTaskGetTickCount() - xLastTickCount;
 | 
			
		||||
 | 
			
		||||
        while( xPassedTicks )
 | 
			
		||||
        {
 | 
			
		||||
            xCoRoutineTickCount++;
 | 
			
		||||
            xPassedTicks--;
 | 
			
		||||
 | 
			
		||||
            /* If the tick count has overflowed we need to swap the ready lists. */
 | 
			
		||||
            if( xCoRoutineTickCount == 0 )
 | 
			
		||||
            {
 | 
			
		||||
                List_t * pxTemp;
 | 
			
		||||
 | 
			
		||||
                /* Tick count has overflowed so we need to swap the delay lists.  If there are
 | 
			
		||||
                 * any items in pxDelayedCoRoutineList here then there is an error! */
 | 
			
		||||
                pxTemp = pxDelayedCoRoutineList;
 | 
			
		||||
                pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
 | 
			
		||||
                pxOverflowDelayedCoRoutineList = pxTemp;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* See if this tick has made a timeout expire. */
 | 
			
		||||
            while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
 | 
			
		||||
            {
 | 
			
		||||
                pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
 | 
			
		||||
 | 
			
		||||
                if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Timeout not yet expired. */
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                portDISABLE_INTERRUPTS();
 | 
			
		||||
                {
 | 
			
		||||
                    /* The event could have occurred just before this critical
 | 
			
		||||
                     *  section.  If this is the case then the generic list item will
 | 
			
		||||
                     *  have been moved to the pending ready list and the following
 | 
			
		||||
                     *  line is still valid.  Also the pvContainer parameter will have
 | 
			
		||||
                     *  been set to NULL so the following lines are also valid. */
 | 
			
		||||
                    ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
 | 
			
		||||
 | 
			
		||||
                    /* Is the co-routine waiting on an event also? */
 | 
			
		||||
                    if( pxCRCB->xEventListItem.pxContainer )
 | 
			
		||||
                    {
 | 
			
		||||
                        ( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                portENABLE_INTERRUPTS();
 | 
			
		||||
 | 
			
		||||
                prvAddCoRoutineToReadyQueue( pxCRCB );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xLastTickCount = xCoRoutineTickCount;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    void vCoRoutineSchedule( void )
 | 
			
		||||
    {
 | 
			
		||||
        traceENTER_vCoRoutineSchedule();
 | 
			
		||||
 | 
			
		||||
        /* Only run a co-routine after prvInitialiseCoRoutineLists() has been
 | 
			
		||||
         * called.  prvInitialiseCoRoutineLists() is called automatically when a
 | 
			
		||||
         * co-routine is created. */
 | 
			
		||||
        if( pxDelayedCoRoutineList != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            /* See if any co-routines readied by events need moving to the ready lists. */
 | 
			
		||||
            prvCheckPendingReadyList();
 | 
			
		||||
 | 
			
		||||
            /* See if any delayed co-routines have timed out. */
 | 
			
		||||
            prvCheckDelayedList();
 | 
			
		||||
 | 
			
		||||
            /* Find the highest priority queue that contains ready co-routines. */
 | 
			
		||||
            while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
 | 
			
		||||
            {
 | 
			
		||||
                if( uxTopCoRoutineReadyPriority == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* No more co-routines to check. */
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                --uxTopCoRoutineReadyPriority;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
 | 
			
		||||
             * of the same priority get an equal share of the processor time. */
 | 
			
		||||
            listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
 | 
			
		||||
 | 
			
		||||
            /* Call the co-routine. */
 | 
			
		||||
            ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceRETURN_vCoRoutineSchedule();
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    static void prvInitialiseCoRoutineLists( void )
 | 
			
		||||
    {
 | 
			
		||||
        UBaseType_t uxPriority;
 | 
			
		||||
 | 
			
		||||
        for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
 | 
			
		||||
        {
 | 
			
		||||
            vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
 | 
			
		||||
        vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
 | 
			
		||||
        vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
 | 
			
		||||
 | 
			
		||||
        /* Start with pxDelayedCoRoutineList using list1 and the
 | 
			
		||||
         * pxOverflowDelayedCoRoutineList using list2. */
 | 
			
		||||
        pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
 | 
			
		||||
        pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList )
 | 
			
		||||
    {
 | 
			
		||||
        CRCB_t * pxUnblockedCRCB;
 | 
			
		||||
        BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xCoRoutineRemoveFromEventList( pxEventList );
 | 
			
		||||
 | 
			
		||||
        /* This function is called from within an interrupt.  It can only access
 | 
			
		||||
         * event lists and the pending ready list.  This function assumes that a
 | 
			
		||||
         * check has already been made to ensure pxEventList is not empty. */
 | 
			
		||||
        pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
 | 
			
		||||
        ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
        vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );
 | 
			
		||||
 | 
			
		||||
        if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority )
 | 
			
		||||
        {
 | 
			
		||||
            xReturn = pdTRUE;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            xReturn = pdFALSE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xCoRoutineRemoveFromEventList( xReturn );
 | 
			
		||||
 | 
			
		||||
        return xReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
    void vCoRoutineResetState( void )
 | 
			
		||||
    {
 | 
			
		||||
        /* Lists for ready and blocked co-routines. */
 | 
			
		||||
        pxDelayedCoRoutineList = NULL;
 | 
			
		||||
        pxOverflowDelayedCoRoutineList = NULL;
 | 
			
		||||
 | 
			
		||||
        /* Other file private variables. */
 | 
			
		||||
        pxCurrentCoRoutine = NULL;
 | 
			
		||||
        uxTopCoRoutineReadyPriority = ( UBaseType_t ) 0U;
 | 
			
		||||
        xCoRoutineTickCount = ( TickType_t ) 0U;
 | 
			
		||||
        xLastTickCount = ( TickType_t ) 0U;
 | 
			
		||||
        xPassedTicks = ( TickType_t ) 0U;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#endif /* configUSE_CO_ROUTINES == 0 */
 | 
			
		||||
							
								
								
									
										884
									
								
								event_groups.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										884
									
								
								event_groups.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,884 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Standard includes. */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers. That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/* FreeRTOS includes. */
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
#include "event_groups.h"
 | 
			
		||||
 | 
			
		||||
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined
 | 
			
		||||
 * for the header files above, but not in this file, in order to generate the
 | 
			
		||||
 * correct privileged Vs unprivileged linkage and placement. */
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/* This entire source file will be skipped if the application is not configured
 | 
			
		||||
 * to include event groups functionality. This #if is closed at the very bottom
 | 
			
		||||
 * of this file. If you want to include event groups then ensure
 | 
			
		||||
 * configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */
 | 
			
		||||
#if ( configUSE_EVENT_GROUPS == 1 )
 | 
			
		||||
 | 
			
		||||
    typedef struct EventGroupDef_t
 | 
			
		||||
    {
 | 
			
		||||
        EventBits_t uxEventBits;
 | 
			
		||||
        List_t xTasksWaitingForBits; /**< List of tasks waiting for a bit to be set. */
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
            UBaseType_t uxEventGroupNumber;
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
 | 
			
		||||
            uint8_t ucStaticallyAllocated; /**< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */
 | 
			
		||||
        #endif
 | 
			
		||||
    } EventGroup_t;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Test the bits set in uxCurrentEventBits to see if the wait condition is met.
 | 
			
		||||
 * The wait condition is defined by xWaitForAllBits.  If xWaitForAllBits is
 | 
			
		||||
 * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor
 | 
			
		||||
 * are also set in uxCurrentEventBits.  If xWaitForAllBits is pdFALSE then the
 | 
			
		||||
 * wait condition is met if any of the bits set in uxBitsToWait for are also set
 | 
			
		||||
 * in uxCurrentEventBits.
 | 
			
		||||
 */
 | 
			
		||||
    static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
 | 
			
		||||
                                            const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                            const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
 | 
			
		||||
        EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer )
 | 
			
		||||
        {
 | 
			
		||||
            EventGroup_t * pxEventBits;
 | 
			
		||||
 | 
			
		||||
            traceENTER_xEventGroupCreateStatic( pxEventGroupBuffer );
 | 
			
		||||
 | 
			
		||||
            /* A StaticEventGroup_t object must be provided. */
 | 
			
		||||
            configASSERT( pxEventGroupBuffer );
 | 
			
		||||
 | 
			
		||||
            #if ( configASSERT_DEFINED == 1 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Sanity check that the size of the structure used to declare a
 | 
			
		||||
                 * variable of type StaticEventGroup_t equals the size of the real
 | 
			
		||||
                 * event group structure. */
 | 
			
		||||
                volatile size_t xSize = sizeof( StaticEventGroup_t );
 | 
			
		||||
                configASSERT( xSize == sizeof( EventGroup_t ) );
 | 
			
		||||
            }
 | 
			
		||||
            #endif /* configASSERT_DEFINED */
 | 
			
		||||
 | 
			
		||||
            /* The user has provided a statically allocated event group - use it. */
 | 
			
		||||
            /* MISRA Ref 11.3.1 [Misaligned access] */
 | 
			
		||||
            /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
 | 
			
		||||
            /* coverity[misra_c_2012_rule_11_3_violation] */
 | 
			
		||||
            pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer;
 | 
			
		||||
 | 
			
		||||
            if( pxEventBits != NULL )
 | 
			
		||||
            {
 | 
			
		||||
                pxEventBits->uxEventBits = 0;
 | 
			
		||||
                vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
 | 
			
		||||
 | 
			
		||||
                #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Both static and dynamic allocation can be used, so note that
 | 
			
		||||
                     * this event group was created statically in case the event group
 | 
			
		||||
                     * is later deleted. */
 | 
			
		||||
                    pxEventBits->ucStaticallyAllocated = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
                #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
                traceEVENT_GROUP_CREATE( pxEventBits );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* xEventGroupCreateStatic should only ever be called with
 | 
			
		||||
                 * pxEventGroupBuffer pointing to a pre-allocated (compile time
 | 
			
		||||
                 * allocated) StaticEventGroup_t variable. */
 | 
			
		||||
                traceEVENT_GROUP_CREATE_FAILED();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            traceRETURN_xEventGroupCreateStatic( pxEventBits );
 | 
			
		||||
 | 
			
		||||
            return pxEventBits;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* configSUPPORT_STATIC_ALLOCATION */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 | 
			
		||||
 | 
			
		||||
        EventGroupHandle_t xEventGroupCreate( void )
 | 
			
		||||
        {
 | 
			
		||||
            EventGroup_t * pxEventBits;
 | 
			
		||||
 | 
			
		||||
            traceENTER_xEventGroupCreate();
 | 
			
		||||
 | 
			
		||||
            /* 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 ) );
 | 
			
		||||
 | 
			
		||||
            if( pxEventBits != NULL )
 | 
			
		||||
            {
 | 
			
		||||
                pxEventBits->uxEventBits = 0;
 | 
			
		||||
                vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );
 | 
			
		||||
 | 
			
		||||
                #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Both static and dynamic allocation can be used, so note this
 | 
			
		||||
                     * event group was allocated statically in case the event group is
 | 
			
		||||
                     * later deleted. */
 | 
			
		||||
                    pxEventBits->ucStaticallyAllocated = pdFALSE;
 | 
			
		||||
                }
 | 
			
		||||
                #endif /* configSUPPORT_STATIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
                traceEVENT_GROUP_CREATE( pxEventBits );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                traceEVENT_GROUP_CREATE_FAILED();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            traceRETURN_xEventGroupCreate( pxEventBits );
 | 
			
		||||
 | 
			
		||||
            return pxEventBits;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                 const EventBits_t uxBitsToSet,
 | 
			
		||||
                                 const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                 TickType_t xTicksToWait )
 | 
			
		||||
    {
 | 
			
		||||
        EventBits_t uxOriginalBitValue, uxReturn;
 | 
			
		||||
        EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
        BaseType_t xAlreadyYielded;
 | 
			
		||||
        BaseType_t xTimeoutOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait );
 | 
			
		||||
 | 
			
		||||
        configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
        configASSERT( uxBitsToWaitFor != 0 );
 | 
			
		||||
        #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
 | 
			
		||||
        }
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        vTaskSuspendAll();
 | 
			
		||||
        {
 | 
			
		||||
            uxOriginalBitValue = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
            ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
            if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
            {
 | 
			
		||||
                /* All the rendezvous bits are now set - no need to block. */
 | 
			
		||||
                uxReturn = ( uxOriginalBitValue | uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
                /* Rendezvous always clear the bits.  They will have been cleared
 | 
			
		||||
                 * already unless this is the only task in the rendezvous. */
 | 
			
		||||
                pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
 | 
			
		||||
                xTicksToWait = 0;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor );
 | 
			
		||||
 | 
			
		||||
                    /* Store the bits that the calling task is waiting for in the
 | 
			
		||||
                     * task's event list item so the kernel knows when a match is
 | 
			
		||||
                     * found.  Then enter the blocked state. */
 | 
			
		||||
                    vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait );
 | 
			
		||||
 | 
			
		||||
                    /* This assignment is obsolete as uxReturn will get set after
 | 
			
		||||
                     * the task unblocks, but some compilers mistakenly generate a
 | 
			
		||||
                     * warning about uxReturn being returned without being set if the
 | 
			
		||||
                     * assignment is omitted. */
 | 
			
		||||
                    uxReturn = 0;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    /* The rendezvous bits were not set, but no block time was
 | 
			
		||||
                     * specified - just return the current event bit value. */
 | 
			
		||||
                    uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
                    xTimeoutOccurred = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        xAlreadyYielded = xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
        if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( xAlreadyYielded == pdFALSE )
 | 
			
		||||
            {
 | 
			
		||||
                taskYIELD_WITHIN_API();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* The task blocked to wait for its required bits to be set - at this
 | 
			
		||||
             * point either the required bits were set or the block time expired.  If
 | 
			
		||||
             * the required bits were set they will have been stored in the task's
 | 
			
		||||
             * event list item, and they should now be retrieved then cleared. */
 | 
			
		||||
            uxReturn = uxTaskResetEventItemValue();
 | 
			
		||||
 | 
			
		||||
            if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
 | 
			
		||||
            {
 | 
			
		||||
                /* The task timed out, just return the current event bit value. */
 | 
			
		||||
                taskENTER_CRITICAL();
 | 
			
		||||
                {
 | 
			
		||||
                    uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
                    /* Although the task got here because it timed out before the
 | 
			
		||||
                     * bits it was waiting for were set, it is possible that since it
 | 
			
		||||
                     * unblocked another task has set the bits.  If this is the case
 | 
			
		||||
                     * then it needs to clear the bits before exiting. */
 | 
			
		||||
                    if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
                    {
 | 
			
		||||
                        pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
                xTimeoutOccurred = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* The task unblocked because the bits were set. */
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Control bits might be set as the task had blocked should not be
 | 
			
		||||
             * returned. */
 | 
			
		||||
            uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred );
 | 
			
		||||
 | 
			
		||||
        /* Prevent compiler warnings when trace macros are not used. */
 | 
			
		||||
        ( void ) xTimeoutOccurred;
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xEventGroupSync( uxReturn );
 | 
			
		||||
 | 
			
		||||
        return uxReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                     const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                     const BaseType_t xClearOnExit,
 | 
			
		||||
                                     const BaseType_t xWaitForAllBits,
 | 
			
		||||
                                     TickType_t xTicksToWait )
 | 
			
		||||
    {
 | 
			
		||||
        EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
        EventBits_t uxReturn, uxControlBits = 0;
 | 
			
		||||
        BaseType_t xWaitConditionMet, xAlreadyYielded;
 | 
			
		||||
        BaseType_t xTimeoutOccurred = pdFALSE;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait );
 | 
			
		||||
 | 
			
		||||
        /* Check the user is not attempting to wait on the bits used by the kernel
 | 
			
		||||
         * itself, and that at least one bit is being requested. */
 | 
			
		||||
        configASSERT( xEventGroup );
 | 
			
		||||
        configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
        configASSERT( uxBitsToWaitFor != 0 );
 | 
			
		||||
        #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
 | 
			
		||||
        }
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        vTaskSuspendAll();
 | 
			
		||||
        {
 | 
			
		||||
            const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
            /* Check to see if the wait condition is already met or not. */
 | 
			
		||||
            xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );
 | 
			
		||||
 | 
			
		||||
            if( xWaitConditionMet != pdFALSE )
 | 
			
		||||
            {
 | 
			
		||||
                /* The wait condition has already been met so there is no need to
 | 
			
		||||
                 * block. */
 | 
			
		||||
                uxReturn = uxCurrentEventBits;
 | 
			
		||||
                xTicksToWait = ( TickType_t ) 0;
 | 
			
		||||
 | 
			
		||||
                /* Clear the wait bits if requested to do so. */
 | 
			
		||||
                if( xClearOnExit != pdFALSE )
 | 
			
		||||
                {
 | 
			
		||||
                    pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if( xTicksToWait == ( TickType_t ) 0 )
 | 
			
		||||
            {
 | 
			
		||||
                /* The wait condition has not been met, but no block time was
 | 
			
		||||
                 * specified, so just return the current value. */
 | 
			
		||||
                uxReturn = uxCurrentEventBits;
 | 
			
		||||
                xTimeoutOccurred = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* The task is going to block to wait for its required bits to be
 | 
			
		||||
                 * set.  uxControlBits are used to remember the specified behaviour of
 | 
			
		||||
                 * this call to xEventGroupWaitBits() - for use when the event bits
 | 
			
		||||
                 * unblock the task. */
 | 
			
		||||
                if( xClearOnExit != pdFALSE )
 | 
			
		||||
                {
 | 
			
		||||
                    uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( xWaitForAllBits != pdFALSE )
 | 
			
		||||
                {
 | 
			
		||||
                    uxControlBits |= eventWAIT_FOR_ALL_BITS;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Store the bits that the calling task is waiting for in the
 | 
			
		||||
                 * task's event list item so the kernel knows when a match is
 | 
			
		||||
                 * found.  Then enter the blocked state. */
 | 
			
		||||
                vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );
 | 
			
		||||
 | 
			
		||||
                /* This is obsolete as it will get set after the task unblocks, but
 | 
			
		||||
                 * some compilers mistakenly generate a warning about the variable
 | 
			
		||||
                 * being returned without being set if it is not done. */
 | 
			
		||||
                uxReturn = 0;
 | 
			
		||||
 | 
			
		||||
                traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        xAlreadyYielded = xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
        if( xTicksToWait != ( TickType_t ) 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( xAlreadyYielded == pdFALSE )
 | 
			
		||||
            {
 | 
			
		||||
                taskYIELD_WITHIN_API();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* The task blocked to wait for its required bits to be set - at this
 | 
			
		||||
             * point either the required bits were set or the block time expired.  If
 | 
			
		||||
             * the required bits were set they will have been stored in the task's
 | 
			
		||||
             * event list item, and they should now be retrieved then cleared. */
 | 
			
		||||
            uxReturn = uxTaskResetEventItemValue();
 | 
			
		||||
 | 
			
		||||
            if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
 | 
			
		||||
            {
 | 
			
		||||
                taskENTER_CRITICAL();
 | 
			
		||||
                {
 | 
			
		||||
                    /* The task timed out, just return the current event bit value. */
 | 
			
		||||
                    uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
                    /* It is possible that the event bits were updated between this
 | 
			
		||||
                     * task leaving the Blocked state and running again. */
 | 
			
		||||
                    if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
 | 
			
		||||
                    {
 | 
			
		||||
                        if( xClearOnExit != pdFALSE )
 | 
			
		||||
                        {
 | 
			
		||||
                            pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    xTimeoutOccurred = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
                taskEXIT_CRITICAL();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                /* The task unblocked because the bits were set. */
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* The task blocked so control bits may have been set. */
 | 
			
		||||
            uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );
 | 
			
		||||
 | 
			
		||||
        /* Prevent compiler warnings when trace macros are not used. */
 | 
			
		||||
        ( void ) xTimeoutOccurred;
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xEventGroupWaitBits( uxReturn );
 | 
			
		||||
 | 
			
		||||
        return uxReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                      const EventBits_t uxBitsToClear )
 | 
			
		||||
    {
 | 
			
		||||
        EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
        EventBits_t uxReturn;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xEventGroupClearBits( xEventGroup, uxBitsToClear );
 | 
			
		||||
 | 
			
		||||
        /* Check the user is not attempting to clear the bits used by the kernel
 | 
			
		||||
         * itself. */
 | 
			
		||||
        configASSERT( xEventGroup );
 | 
			
		||||
        configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
 | 
			
		||||
        taskENTER_CRITICAL();
 | 
			
		||||
        {
 | 
			
		||||
            traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear );
 | 
			
		||||
 | 
			
		||||
            /* The value returned is the event group value prior to the bits being
 | 
			
		||||
             * cleared. */
 | 
			
		||||
            uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
 | 
			
		||||
            /* Clear the bits. */
 | 
			
		||||
            pxEventBits->uxEventBits &= ~uxBitsToClear;
 | 
			
		||||
        }
 | 
			
		||||
        taskEXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xEventGroupClearBits( uxReturn );
 | 
			
		||||
 | 
			
		||||
        return uxReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
 | 
			
		||||
        BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                                const EventBits_t uxBitsToClear )
 | 
			
		||||
        {
 | 
			
		||||
            BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
            traceENTER_xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear );
 | 
			
		||||
 | 
			
		||||
            traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear );
 | 
			
		||||
            xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL );
 | 
			
		||||
 | 
			
		||||
            traceRETURN_xEventGroupClearBitsFromISR( xReturn );
 | 
			
		||||
 | 
			
		||||
            return xReturn;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
 | 
			
		||||
    {
 | 
			
		||||
        UBaseType_t uxSavedInterruptStatus;
 | 
			
		||||
        EventGroup_t const * const pxEventBits = xEventGroup;
 | 
			
		||||
        EventBits_t uxReturn;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xEventGroupGetBitsFromISR( xEventGroup );
 | 
			
		||||
 | 
			
		||||
        /* MISRA Ref 4.7.1 [Return value shall be checked] */
 | 
			
		||||
        /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#dir-47 */
 | 
			
		||||
        /* coverity[misra_c_2012_directive_4_7_violation] */
 | 
			
		||||
        uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
 | 
			
		||||
        {
 | 
			
		||||
            uxReturn = pxEventBits->uxEventBits;
 | 
			
		||||
        }
 | 
			
		||||
        taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus );
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xEventGroupGetBitsFromISR( uxReturn );
 | 
			
		||||
 | 
			
		||||
        return uxReturn;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                    const EventBits_t uxBitsToSet )
 | 
			
		||||
    {
 | 
			
		||||
        ListItem_t * pxListItem;
 | 
			
		||||
        ListItem_t * pxNext;
 | 
			
		||||
        ListItem_t const * pxListEnd;
 | 
			
		||||
        List_t const * pxList;
 | 
			
		||||
        EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
 | 
			
		||||
        EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
        BaseType_t xMatchFound = pdFALSE;
 | 
			
		||||
 | 
			
		||||
        traceENTER_xEventGroupSetBits( xEventGroup, uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
        /* Check the user is not attempting to set the bits used by the kernel
 | 
			
		||||
         * itself. */
 | 
			
		||||
        configASSERT( xEventGroup );
 | 
			
		||||
        configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );
 | 
			
		||||
 | 
			
		||||
        pxList = &( pxEventBits->xTasksWaitingForBits );
 | 
			
		||||
        pxListEnd = listGET_END_MARKER( pxList );
 | 
			
		||||
        vTaskSuspendAll();
 | 
			
		||||
        {
 | 
			
		||||
            traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet );
 | 
			
		||||
 | 
			
		||||
            pxListItem = listGET_HEAD_ENTRY( pxList );
 | 
			
		||||
 | 
			
		||||
            /* Set the bits. */
 | 
			
		||||
            pxEventBits->uxEventBits |= uxBitsToSet;
 | 
			
		||||
 | 
			
		||||
            /* See if the new bit value should unblock any tasks. */
 | 
			
		||||
            while( pxListItem != pxListEnd )
 | 
			
		||||
            {
 | 
			
		||||
                pxNext = listGET_NEXT( pxListItem );
 | 
			
		||||
                uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
 | 
			
		||||
                xMatchFound = pdFALSE;
 | 
			
		||||
 | 
			
		||||
                /* Split the bits waited for from the control bits. */
 | 
			
		||||
                uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
                uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;
 | 
			
		||||
 | 
			
		||||
                if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Just looking for single bit being set. */
 | 
			
		||||
                    if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
 | 
			
		||||
                    {
 | 
			
		||||
                        xMatchFound = pdTRUE;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
 | 
			
		||||
                {
 | 
			
		||||
                    /* All bits are set. */
 | 
			
		||||
                    xMatchFound = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    /* Need all bits to be set, but not all the bits were set. */
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( xMatchFound != pdFALSE )
 | 
			
		||||
                {
 | 
			
		||||
                    /* The bits match.  Should the bits be cleared on exit? */
 | 
			
		||||
                    if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
 | 
			
		||||
                    {
 | 
			
		||||
                        uxBitsToClear |= uxBitsWaitedFor;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* Store the actual event flag value in the task's event list
 | 
			
		||||
                     * item before removing the task from the event list.  The
 | 
			
		||||
                     * eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows
 | 
			
		||||
                     * that is was unblocked due to its required bits matching, rather
 | 
			
		||||
                     * than because it timed out. */
 | 
			
		||||
                    vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Move onto the next list item.  Note pxListItem->pxNext is not
 | 
			
		||||
                 * used here as the list item may have been removed from the event list
 | 
			
		||||
                 * and inserted into the ready/pending reading list. */
 | 
			
		||||
                pxListItem = pxNext;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT
 | 
			
		||||
             * bit was set in the control word. */
 | 
			
		||||
            pxEventBits->uxEventBits &= ~uxBitsToClear;
 | 
			
		||||
        }
 | 
			
		||||
        ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
        traceRETURN_xEventGroupSetBits( pxEventBits->uxEventBits );
 | 
			
		||||
 | 
			
		||||
        return pxEventBits->uxEventBits;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    void vEventGroupDelete( EventGroupHandle_t xEventGroup )
 | 
			
		||||
    {
 | 
			
		||||
        EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
        const List_t * pxTasksWaitingForBits;
 | 
			
		||||
 | 
			
		||||
        traceENTER_vEventGroupDelete( xEventGroup );
 | 
			
		||||
 | 
			
		||||
        configASSERT( pxEventBits );
 | 
			
		||||
 | 
			
		||||
        pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits );
 | 
			
		||||
 | 
			
		||||
        vTaskSuspendAll();
 | 
			
		||||
        {
 | 
			
		||||
            traceEVENT_GROUP_DELETE( xEventGroup );
 | 
			
		||||
 | 
			
		||||
            while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Unblock the task, returning 0 as the event list is being deleted
 | 
			
		||||
                 * and cannot therefore have any bits set. */
 | 
			
		||||
                configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) );
 | 
			
		||||
                vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
        #if ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) )
 | 
			
		||||
        {
 | 
			
		||||
            /* The event group can only have been allocated dynamically - free
 | 
			
		||||
             * it again. */
 | 
			
		||||
            vPortFree( pxEventBits );
 | 
			
		||||
        }
 | 
			
		||||
        #elif ( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) )
 | 
			
		||||
        {
 | 
			
		||||
            /* The event group could have been allocated statically or
 | 
			
		||||
             * dynamically, so check before attempting to free the memory. */
 | 
			
		||||
            if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE )
 | 
			
		||||
            {
 | 
			
		||||
                vPortFree( pxEventBits );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
        traceRETURN_vEventGroupDelete();
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
        BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                               StaticEventGroup_t ** ppxEventGroupBuffer )
 | 
			
		||||
        {
 | 
			
		||||
            BaseType_t xReturn;
 | 
			
		||||
            EventGroup_t * pxEventBits = xEventGroup;
 | 
			
		||||
 | 
			
		||||
            traceENTER_xEventGroupGetStaticBuffer( xEventGroup, ppxEventGroupBuffer );
 | 
			
		||||
 | 
			
		||||
            configASSERT( pxEventBits );
 | 
			
		||||
            configASSERT( ppxEventGroupBuffer );
 | 
			
		||||
 | 
			
		||||
            #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Check if the event group was statically allocated. */
 | 
			
		||||
                if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdTRUE )
 | 
			
		||||
                {
 | 
			
		||||
                    /* MISRA Ref 11.3.1 [Misaligned access] */
 | 
			
		||||
                    /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
 | 
			
		||||
                    /* coverity[misra_c_2012_rule_11_3_violation] */
 | 
			
		||||
                    *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
 | 
			
		||||
                    xReturn = pdTRUE;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    xReturn = pdFALSE;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            #else /* configSUPPORT_DYNAMIC_ALLOCATION */
 | 
			
		||||
            {
 | 
			
		||||
                /* Event group must have been statically allocated. */
 | 
			
		||||
                /* MISRA Ref 11.3.1 [Misaligned access] */
 | 
			
		||||
                /* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-113 */
 | 
			
		||||
                /* coverity[misra_c_2012_rule_11_3_violation] */
 | 
			
		||||
                *ppxEventGroupBuffer = ( StaticEventGroup_t * ) pxEventBits;
 | 
			
		||||
                xReturn = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
            #endif /* configSUPPORT_DYNAMIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
            traceRETURN_xEventGroupGetStaticBuffer( xReturn );
 | 
			
		||||
 | 
			
		||||
            return xReturn;
 | 
			
		||||
        }
 | 
			
		||||
    #endif /* configSUPPORT_STATIC_ALLOCATION */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* For internal use only - execute a 'set bits' command that was pended from
 | 
			
		||||
 * an interrupt. */
 | 
			
		||||
    void vEventGroupSetBitsCallback( void * pvEventGroup,
 | 
			
		||||
                                     uint32_t ulBitsToSet )
 | 
			
		||||
    {
 | 
			
		||||
        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 );
 | 
			
		||||
 | 
			
		||||
        traceRETURN_vEventGroupSetBitsCallback();
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* For internal use only - execute a 'clear bits' command that was pended from
 | 
			
		||||
 * an interrupt. */
 | 
			
		||||
    void vEventGroupClearBitsCallback( void * pvEventGroup,
 | 
			
		||||
                                       uint32_t ulBitsToClear )
 | 
			
		||||
    {
 | 
			
		||||
        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 );
 | 
			
		||||
 | 
			
		||||
        traceRETURN_vEventGroupClearBitsCallback();
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits,
 | 
			
		||||
                                            const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                            const BaseType_t xWaitForAllBits )
 | 
			
		||||
    {
 | 
			
		||||
        BaseType_t xWaitConditionMet = pdFALSE;
 | 
			
		||||
 | 
			
		||||
        if( xWaitForAllBits == pdFALSE )
 | 
			
		||||
        {
 | 
			
		||||
            /* Task only has to wait for one bit within uxBitsToWaitFor to be
 | 
			
		||||
             * set.  Is one already set? */
 | 
			
		||||
            if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 )
 | 
			
		||||
            {
 | 
			
		||||
                xWaitConditionMet = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Task has to wait for all the bits in uxBitsToWaitFor to be set.
 | 
			
		||||
             * Are they set already? */
 | 
			
		||||
            if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor )
 | 
			
		||||
            {
 | 
			
		||||
                xWaitConditionMet = pdTRUE;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return xWaitConditionMet;
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) )
 | 
			
		||||
 | 
			
		||||
        BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                              const EventBits_t uxBitsToSet,
 | 
			
		||||
                                              BaseType_t * pxHigherPriorityTaskWoken )
 | 
			
		||||
        {
 | 
			
		||||
            BaseType_t xReturn;
 | 
			
		||||
 | 
			
		||||
            traceENTER_xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken );
 | 
			
		||||
 | 
			
		||||
            traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet );
 | 
			
		||||
            xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );
 | 
			
		||||
 | 
			
		||||
            traceRETURN_xEventGroupSetBitsFromISR( xReturn );
 | 
			
		||||
 | 
			
		||||
            return xReturn;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
            traceENTER_uxEventGroupGetNumber( xEventGroup );
 | 
			
		||||
 | 
			
		||||
            if( xEventGroup == NULL )
 | 
			
		||||
            {
 | 
			
		||||
                xReturn = 0;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                xReturn = pxEventBits->uxEventGroupNumber;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            traceRETURN_uxEventGroupGetNumber( xReturn );
 | 
			
		||||
 | 
			
		||||
            return xReturn;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* configUSE_TRACE_FACILITY */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
 | 
			
		||||
        void vEventGroupSetNumber( void * xEventGroup,
 | 
			
		||||
                                   UBaseType_t uxEventGroupNumber )
 | 
			
		||||
        {
 | 
			
		||||
            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;
 | 
			
		||||
 | 
			
		||||
            traceRETURN_vEventGroupSetNumber();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    #endif /* configUSE_TRACE_FACILITY */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* This entire source file will be skipped if the application is not configured
 | 
			
		||||
 * to include event groups functionality. If you want to include event groups
 | 
			
		||||
 * then ensure configUSE_EVENT_GROUPS is set to 1 in FreeRTOSConfig.h. */
 | 
			
		||||
#endif /* configUSE_EVENT_GROUPS == 1 */
 | 
			
		||||
							
								
								
									
										5
									
								
								heap/ReadMe.url
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								heap/ReadMe.url
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
[{000214A0-0000-0000-C000-000000000046}]
 | 
			
		||||
Prop3=19,2
 | 
			
		||||
[InternetShortcut]
 | 
			
		||||
URL=https://www.FreeRTOS.org/a00111.html
 | 
			
		||||
IDList=
 | 
			
		||||
							
								
								
									
										165
									
								
								heap/heap_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								heap/heap_1.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The simplest possible implementation of pvPortMalloc().  Note that this
 | 
			
		||||
 * implementation does NOT allow allocated memory to be freed again.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the
 | 
			
		||||
 * memory management pages of https://www.FreeRTOS.org for more information.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* A few bytes might be lost to byte aligning the heap start address. */
 | 
			
		||||
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
 | 
			
		||||
 | 
			
		||||
/* Allocate the memory for the heap. */
 | 
			
		||||
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
 | 
			
		||||
 | 
			
		||||
/* The application writer has already defined the array used for the RTOS
 | 
			
		||||
* heap - probably so it can be placed in a special segment or address. */
 | 
			
		||||
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#else
 | 
			
		||||
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
 | 
			
		||||
 | 
			
		||||
/* Index into the ucHeap array. */
 | 
			
		||||
static size_t xNextFreeByte = ( size_t ) 0U;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pvReturn = NULL;
 | 
			
		||||
    static uint8_t * pucAlignedHeap = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Ensure that blocks are always aligned. */
 | 
			
		||||
    #if ( portBYTE_ALIGNMENT != 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( xWantedSize & portBYTE_ALIGNMENT_MASK )
 | 
			
		||||
        {
 | 
			
		||||
            /* Byte alignment required. Check for overflow. */
 | 
			
		||||
            if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) > xWantedSize )
 | 
			
		||||
            {
 | 
			
		||||
                xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                xWantedSize = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* if ( portBYTE_ALIGNMENT != 1 ) */
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        if( pucAlignedHeap == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            /* Ensure the heap starts on a correctly aligned boundary. */
 | 
			
		||||
            pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check there is enough room left for the allocation and. */
 | 
			
		||||
        if( ( xWantedSize > 0 ) &&                                /* valid size */
 | 
			
		||||
            ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
 | 
			
		||||
            ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */
 | 
			
		||||
        {
 | 
			
		||||
            /* Return the next free byte then increment the index past this
 | 
			
		||||
             * block. */
 | 
			
		||||
            pvReturn = pucAlignedHeap + xNextFreeByte;
 | 
			
		||||
            xNextFreeByte += xWantedSize;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    /* Memory cannot be freed using this scheme.  See heap_2.c, heap_3.c and
 | 
			
		||||
     * heap_4.c for alternative implementations, and the memory management pages of
 | 
			
		||||
     * https://www.FreeRTOS.org for more information. */
 | 
			
		||||
    ( void ) pv;
 | 
			
		||||
 | 
			
		||||
    /* Force an assert as it is invalid to call this function. */
 | 
			
		||||
    configASSERT( pv == NULL );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortInitialiseBlocks( void )
 | 
			
		||||
{
 | 
			
		||||
    /* Only required when static memory is not cleared. */
 | 
			
		||||
    xNextFreeByte = ( size_t ) 0;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return( configADJUSTED_HEAP_SIZE - xNextFreeByte );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    xNextFreeByte = ( size_t ) 0U;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										401
									
								
								heap/heap_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										401
									
								
								heap/heap_2.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,401 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A sample implementation of pvPortMalloc() and vPortFree() that permits
 | 
			
		||||
 * allocated blocks to be freed, but does not combine adjacent free blocks
 | 
			
		||||
 * into a single larger block (and so will fragment memory).  See heap_4.c for
 | 
			
		||||
 * an equivalent that does combine adjacent blocks into single larger blocks.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the
 | 
			
		||||
 * memory management pages of https://www.FreeRTOS.org for more information.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configHEAP_CLEAR_MEMORY_ON_FREE
 | 
			
		||||
    #define configHEAP_CLEAR_MEMORY_ON_FREE    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* A few bytes might be lost to byte aligning the heap start address. */
 | 
			
		||||
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
 | 
			
		||||
 | 
			
		||||
/* Assumes 8bit bytes! */
 | 
			
		||||
#define heapBITS_PER_BYTE           ( ( size_t ) 8 )
 | 
			
		||||
 | 
			
		||||
/* Max value that fits in a size_t type. */
 | 
			
		||||
#define heapSIZE_MAX                ( ~( ( size_t ) 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Check if multiplying a and b will result in overflow. */
 | 
			
		||||
#define heapMULTIPLY_WILL_OVERFLOW( a, b )    ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) )
 | 
			
		||||
 | 
			
		||||
/* Check if adding a and b will result in overflow. */
 | 
			
		||||
#define heapADD_WILL_OVERFLOW( a, b )         ( ( a ) > ( heapSIZE_MAX - ( b ) ) )
 | 
			
		||||
 | 
			
		||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
 | 
			
		||||
 * the allocation status of a block.  When MSB of the xBlockSize member of
 | 
			
		||||
 * an BlockLink_t structure is set then the block belongs to the application.
 | 
			
		||||
 * When the bit is free the block is still part of the free heap space. */
 | 
			
		||||
#define heapBLOCK_ALLOCATED_BITMASK    ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) )
 | 
			
		||||
#define heapBLOCK_SIZE_IS_VALID( xBlockSize )    ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 )
 | 
			
		||||
#define heapBLOCK_IS_ALLOCATED( pxBlock )        ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 )
 | 
			
		||||
#define heapALLOCATE_BLOCK( pxBlock )            ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
#define heapFREE_BLOCK( pxBlock )                ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Allocate the memory for the heap. */
 | 
			
		||||
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
 | 
			
		||||
 | 
			
		||||
/* The application writer has already defined the array used for the RTOS
 | 
			
		||||
* heap - probably so it can be placed in a special segment or address. */
 | 
			
		||||
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#else
 | 
			
		||||
    PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Define the linked list structure.  This is used to link free blocks in order
 | 
			
		||||
 * of their size. */
 | 
			
		||||
typedef struct A_BLOCK_LINK
 | 
			
		||||
{
 | 
			
		||||
    struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */
 | 
			
		||||
    size_t xBlockSize;                     /*<< The size of the free block. */
 | 
			
		||||
} BlockLink_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const size_t xHeapStructSize = ( ( sizeof( BlockLink_t ) + ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ) );
 | 
			
		||||
#define heapMINIMUM_BLOCK_SIZE    ( ( size_t ) ( xHeapStructSize * 2 ) )
 | 
			
		||||
 | 
			
		||||
/* Create a couple of list links to mark the start and end of the list. */
 | 
			
		||||
PRIVILEGED_DATA static BlockLink_t xStart, xEnd;
 | 
			
		||||
 | 
			
		||||
/* Keeps track of the number of free bytes remaining, but says nothing about
 | 
			
		||||
 * fragmentation. */
 | 
			
		||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
 | 
			
		||||
 | 
			
		||||
/* Indicates whether the heap has been initialised or not. */
 | 
			
		||||
PRIVILEGED_DATA static BaseType_t xHeapHasBeenInitialised = pdFALSE;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialises the heap structures before their first use.
 | 
			
		||||
 */
 | 
			
		||||
static void prvHeapInit( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a block into the list of free blocks - which is ordered by size of
 | 
			
		||||
 * the block.  Small blocks at the start of the list and large blocks at the end
 | 
			
		||||
 * of the list.
 | 
			
		||||
 */
 | 
			
		||||
#define prvInsertBlockIntoFreeList( pxBlockToInsert )                                                                               \
 | 
			
		||||
    {                                                                                                                               \
 | 
			
		||||
        BlockLink_t * pxIterator;                                                                                                   \
 | 
			
		||||
        size_t xBlockSize;                                                                                                          \
 | 
			
		||||
                                                                                                                                    \
 | 
			
		||||
        xBlockSize = pxBlockToInsert->xBlockSize;                                                                                   \
 | 
			
		||||
                                                                                                                                    \
 | 
			
		||||
        /* Iterate through the list until a block is found that has a larger size */                                                \
 | 
			
		||||
        /* than the block we are inserting. */                                                                                      \
 | 
			
		||||
        for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \
 | 
			
		||||
        {                                                                                                                           \
 | 
			
		||||
            /* There is nothing to do here - just iterate to the correct position. */                                               \
 | 
			
		||||
        }                                                                                                                           \
 | 
			
		||||
                                                                                                                                    \
 | 
			
		||||
        /* Update the list to include the block being inserted in the correct */                                                    \
 | 
			
		||||
        /* position. */                                                                                                             \
 | 
			
		||||
        pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;                                                             \
 | 
			
		||||
        pxIterator->pxNextFreeBlock = pxBlockToInsert;                                                                              \
 | 
			
		||||
    }
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxBlock;
 | 
			
		||||
    BlockLink_t * pxPreviousBlock;
 | 
			
		||||
    BlockLink_t * pxNewBlockLink;
 | 
			
		||||
    void * pvReturn = NULL;
 | 
			
		||||
    size_t xAdditionalRequiredSize;
 | 
			
		||||
 | 
			
		||||
    if( xWantedSize > 0 )
 | 
			
		||||
    {
 | 
			
		||||
        /* The wanted size must be increased so it can contain a BlockLink_t
 | 
			
		||||
         * structure in addition to the requested amount of bytes. */
 | 
			
		||||
        if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize += xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
            /* Ensure that blocks are always aligned to the required number
 | 
			
		||||
             * of bytes. */
 | 
			
		||||
            if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Byte alignment required. */
 | 
			
		||||
                xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
                if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize += xAdditionalRequiredSize;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        /* If this is the first call to malloc then the heap will require
 | 
			
		||||
         * initialisation to setup the list of free blocks. */
 | 
			
		||||
        if( xHeapHasBeenInitialised == pdFALSE )
 | 
			
		||||
        {
 | 
			
		||||
            prvHeapInit();
 | 
			
		||||
            xHeapHasBeenInitialised = pdTRUE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check the block size we are trying to allocate is not so large that the
 | 
			
		||||
         * top bit is set.  The top bit of the block size member of the BlockLink_t
 | 
			
		||||
         * structure is used to determine who owns the block - the application or
 | 
			
		||||
         * the kernel, so it must be free. */
 | 
			
		||||
        if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
 | 
			
		||||
            {
 | 
			
		||||
                /* Blocks are stored in byte order - traverse the list from the start
 | 
			
		||||
                 * (smallest) block until one of adequate size is found. */
 | 
			
		||||
                pxPreviousBlock = &xStart;
 | 
			
		||||
                pxBlock = xStart.pxNextFreeBlock;
 | 
			
		||||
 | 
			
		||||
                while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
 | 
			
		||||
                {
 | 
			
		||||
                    pxPreviousBlock = pxBlock;
 | 
			
		||||
                    pxBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* If we found the end marker then a block of adequate size was not found. */
 | 
			
		||||
                if( pxBlock != &xEnd )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Return the memory space - jumping over the BlockLink_t structure
 | 
			
		||||
                     * at its start. */
 | 
			
		||||
                    pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
 | 
			
		||||
 | 
			
		||||
                    /* This block is being returned for use so must be taken out of the
 | 
			
		||||
                     * list of free blocks. */
 | 
			
		||||
                    pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
 | 
			
		||||
                    /* If the block is larger than required it can be split into two. */
 | 
			
		||||
                    if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
 | 
			
		||||
                    {
 | 
			
		||||
                        /* This block is to be split into two.  Create a new block
 | 
			
		||||
                         * following the number of bytes requested. The void cast is
 | 
			
		||||
                         * used to prevent byte alignment warnings from the compiler. */
 | 
			
		||||
                        pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
 | 
			
		||||
 | 
			
		||||
                        /* Calculate the sizes of two blocks split from the single
 | 
			
		||||
                         * block. */
 | 
			
		||||
                        pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
 | 
			
		||||
                        pxBlock->xBlockSize = xWantedSize;
 | 
			
		||||
 | 
			
		||||
                        /* Insert the new block into the list of free blocks.
 | 
			
		||||
                         * The list of free blocks is sorted by their size, we have to
 | 
			
		||||
                         * iterate to find the right place to insert new block. */
 | 
			
		||||
                        prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    xFreeBytesRemaining -= pxBlock->xBlockSize;
 | 
			
		||||
 | 
			
		||||
                    /* The block is being returned - it is allocated and owned
 | 
			
		||||
                     * by the application and has no "next" block. */
 | 
			
		||||
                    heapALLOCATE_BLOCK( pxBlock );
 | 
			
		||||
                    pxBlock->pxNextFreeBlock = NULL;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    uint8_t * puc = ( uint8_t * ) pv;
 | 
			
		||||
    BlockLink_t * pxLink;
 | 
			
		||||
 | 
			
		||||
    if( pv != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        /* The memory being freed will have an BlockLink_t structure immediately
 | 
			
		||||
         * before it. */
 | 
			
		||||
        puc -= xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
        /* This unexpected casting is to keep some compilers from issuing
 | 
			
		||||
         * byte alignment warnings. */
 | 
			
		||||
        pxLink = ( void * ) puc;
 | 
			
		||||
 | 
			
		||||
        configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
 | 
			
		||||
        configASSERT( pxLink->pxNextFreeBlock == NULL );
 | 
			
		||||
 | 
			
		||||
        if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( pxLink->pxNextFreeBlock == NULL )
 | 
			
		||||
            {
 | 
			
		||||
                /* The block is being returned to the heap - it is no longer
 | 
			
		||||
                 * allocated. */
 | 
			
		||||
                heapFREE_BLOCK( pxLink );
 | 
			
		||||
                #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
 | 
			
		||||
                {
 | 
			
		||||
                    ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
 | 
			
		||||
                }
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                vTaskSuspendAll();
 | 
			
		||||
                {
 | 
			
		||||
                    /* Add this block to the list of free blocks. */
 | 
			
		||||
                    prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
 | 
			
		||||
                    xFreeBytesRemaining += pxLink->xBlockSize;
 | 
			
		||||
                    traceFREE( pv, pxLink->xBlockSize );
 | 
			
		||||
                }
 | 
			
		||||
                ( void ) xTaskResumeAll();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return xFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortInitialiseBlocks( void )
 | 
			
		||||
{
 | 
			
		||||
    /* This just exists to keep the linker quiet. */
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortCalloc( size_t xNum,
 | 
			
		||||
                     size_t xSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pv = NULL;
 | 
			
		||||
 | 
			
		||||
    if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pv = pvPortMalloc( xNum * xSize );
 | 
			
		||||
 | 
			
		||||
        if( pv != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            ( void ) memset( pv, 0, xNum * xSize );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return pv;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxFirstFreeBlock;
 | 
			
		||||
    uint8_t * pucAlignedHeap;
 | 
			
		||||
 | 
			
		||||
    /* Ensure the heap starts on a correctly aligned boundary. */
 | 
			
		||||
    pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
 | 
			
		||||
 | 
			
		||||
    /* xStart is used to hold a pointer to the first item in the list of free
 | 
			
		||||
     * blocks.  The void cast is used to prevent compiler warnings. */
 | 
			
		||||
    xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap;
 | 
			
		||||
    xStart.xBlockSize = ( size_t ) 0;
 | 
			
		||||
 | 
			
		||||
    /* xEnd is used to mark the end of the list of free blocks. */
 | 
			
		||||
    xEnd.xBlockSize = configADJUSTED_HEAP_SIZE;
 | 
			
		||||
    xEnd.pxNextFreeBlock = NULL;
 | 
			
		||||
 | 
			
		||||
    /* To start with there is a single free block that is sized to take up the
 | 
			
		||||
     * entire heap space. */
 | 
			
		||||
    pxFirstFreeBlock = ( BlockLink_t * ) pucAlignedHeap;
 | 
			
		||||
    pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE;
 | 
			
		||||
    pxFirstFreeBlock->pxNextFreeBlock = &xEnd;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    xFreeBytesRemaining = configADJUSTED_HEAP_SIZE;
 | 
			
		||||
 | 
			
		||||
    xHeapHasBeenInitialised = pdFALSE;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										106
									
								
								heap/heap_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								heap/heap_3.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Implementation of pvPortMalloc() and vPortFree() that relies on the
 | 
			
		||||
 * compilers own malloc() and free() implementations.
 | 
			
		||||
 *
 | 
			
		||||
 * This file can only be used if the linker is configured to to generate
 | 
			
		||||
 * a heap memory area.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the
 | 
			
		||||
 * memory management pages of https://www.FreeRTOS.org for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pvReturn;
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        pvReturn = malloc( xWantedSize );
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    if( pv != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        vTaskSuspendAll();
 | 
			
		||||
        {
 | 
			
		||||
            free( pv );
 | 
			
		||||
            traceFREE( pv, 0 );
 | 
			
		||||
        }
 | 
			
		||||
        ( void ) xTaskResumeAll();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    /* No state needs to be re-initialised in heap_3. */
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										626
									
								
								heap/heap_4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										626
									
								
								heap/heap_4.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,626 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A sample implementation of pvPortMalloc() and vPortFree() that combines
 | 
			
		||||
 * (coalescences) adjacent memory blocks as they are freed, and in so doing
 | 
			
		||||
 * limits memory fragmentation.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the
 | 
			
		||||
 * memory management pages of https://www.FreeRTOS.org for more information.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configHEAP_CLEAR_MEMORY_ON_FREE
 | 
			
		||||
    #define configHEAP_CLEAR_MEMORY_ON_FREE    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Block sizes must not get too small. */
 | 
			
		||||
#define heapMINIMUM_BLOCK_SIZE    ( ( size_t ) ( xHeapStructSize << 1 ) )
 | 
			
		||||
 | 
			
		||||
/* Assumes 8bit bytes! */
 | 
			
		||||
#define heapBITS_PER_BYTE         ( ( size_t ) 8 )
 | 
			
		||||
 | 
			
		||||
/* Max value that fits in a size_t type. */
 | 
			
		||||
#define heapSIZE_MAX              ( ~( ( size_t ) 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Check if multiplying a and b will result in overflow. */
 | 
			
		||||
#define heapMULTIPLY_WILL_OVERFLOW( a, b )     ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) )
 | 
			
		||||
 | 
			
		||||
/* Check if adding a and b will result in overflow. */
 | 
			
		||||
#define heapADD_WILL_OVERFLOW( a, b )          ( ( a ) > ( heapSIZE_MAX - ( b ) ) )
 | 
			
		||||
 | 
			
		||||
/* Check if the subtraction operation ( a - b ) will result in underflow. */
 | 
			
		||||
#define heapSUBTRACT_WILL_UNDERFLOW( a, b )    ( ( a ) < ( b ) )
 | 
			
		||||
 | 
			
		||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
 | 
			
		||||
 * the allocation status of a block.  When MSB of the xBlockSize member of
 | 
			
		||||
 * an BlockLink_t structure is set then the block belongs to the application.
 | 
			
		||||
 * When the bit is free the block is still part of the free heap space. */
 | 
			
		||||
#define heapBLOCK_ALLOCATED_BITMASK    ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) )
 | 
			
		||||
#define heapBLOCK_SIZE_IS_VALID( xBlockSize )    ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 )
 | 
			
		||||
#define heapBLOCK_IS_ALLOCATED( pxBlock )        ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 )
 | 
			
		||||
#define heapALLOCATE_BLOCK( pxBlock )            ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
#define heapFREE_BLOCK( pxBlock )                ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Allocate the memory for the heap. */
 | 
			
		||||
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
 | 
			
		||||
 | 
			
		||||
/* The application writer has already defined the array used for the RTOS
 | 
			
		||||
* heap - probably so it can be placed in a special segment or address. */
 | 
			
		||||
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#else
 | 
			
		||||
    PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
 | 
			
		||||
 | 
			
		||||
/* Define the linked list structure.  This is used to link free blocks in order
 | 
			
		||||
 * of their memory address. */
 | 
			
		||||
typedef struct A_BLOCK_LINK
 | 
			
		||||
{
 | 
			
		||||
    struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
 | 
			
		||||
    size_t xBlockSize;                     /**< The size of the free block. */
 | 
			
		||||
} BlockLink_t;
 | 
			
		||||
 | 
			
		||||
/* Setting configENABLE_HEAP_PROTECTOR to 1 enables heap block pointers
 | 
			
		||||
 * protection using an application supplied canary value to catch heap
 | 
			
		||||
 * corruption should a heap buffer overflow occur.
 | 
			
		||||
 */
 | 
			
		||||
#if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Application provided function to get a random value to be used as canary.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHeapCanary [out] Output parameter to return the canary value.
 | 
			
		||||
 */
 | 
			
		||||
    extern void vApplicationGetRandomHeapCanary( portPOINTER_SIZE_TYPE * pxHeapCanary );
 | 
			
		||||
 | 
			
		||||
/* Canary value for protecting internal heap pointers. */
 | 
			
		||||
    PRIVILEGED_DATA static portPOINTER_SIZE_TYPE xHeapCanary;
 | 
			
		||||
 | 
			
		||||
/* Macro to load/store BlockLink_t pointers to memory. By XORing the
 | 
			
		||||
 * pointers with a random canary value, heap overflows will result
 | 
			
		||||
 * in randomly unpredictable pointer values which will be caught by
 | 
			
		||||
 * heapVALIDATE_BLOCK_POINTER assert. */
 | 
			
		||||
    #define heapPROTECT_BLOCK_POINTER( pxBlock )    ( ( BlockLink_t * ) ( ( ( portPOINTER_SIZE_TYPE ) ( pxBlock ) ) ^ xHeapCanary ) )
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    #define heapPROTECT_BLOCK_POINTER( pxBlock )    ( pxBlock )
 | 
			
		||||
 | 
			
		||||
#endif /* configENABLE_HEAP_PROTECTOR */
 | 
			
		||||
 | 
			
		||||
/* Assert that a heap block pointer is within the heap bounds. */
 | 
			
		||||
#define heapVALIDATE_BLOCK_POINTER( pxBlock )                          \
 | 
			
		||||
    configASSERT( ( ( uint8_t * ) ( pxBlock ) >= &( ucHeap[ 0 ] ) ) && \
 | 
			
		||||
                  ( ( uint8_t * ) ( pxBlock ) <= &( ucHeap[ configTOTAL_HEAP_SIZE - 1 ] ) ) )
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Inserts a block of memory that is being freed into the correct position in
 | 
			
		||||
 * the list of free memory blocks.  The block being freed will be merged with
 | 
			
		||||
 * the block in front it and/or the block behind it if the memory blocks are
 | 
			
		||||
 * adjacent to each other.
 | 
			
		||||
 */
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Called automatically to setup the required heap structures the first time
 | 
			
		||||
 * pvPortMalloc() is called.
 | 
			
		||||
 */
 | 
			
		||||
static void prvHeapInit( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* The size of the structure placed at the beginning of each allocated memory
 | 
			
		||||
 * block must by correctly byte aligned. */
 | 
			
		||||
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
/* Create a couple of list links to mark the start and end of the list. */
 | 
			
		||||
PRIVILEGED_DATA static BlockLink_t xStart;
 | 
			
		||||
PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL;
 | 
			
		||||
 | 
			
		||||
/* Keeps track of the number of calls to allocate and free memory as well as the
 | 
			
		||||
 * number of free bytes remaining, but says nothing about fragmentation. */
 | 
			
		||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxBlock;
 | 
			
		||||
    BlockLink_t * pxPreviousBlock;
 | 
			
		||||
    BlockLink_t * pxNewBlockLink;
 | 
			
		||||
    void * pvReturn = NULL;
 | 
			
		||||
    size_t xAdditionalRequiredSize;
 | 
			
		||||
 | 
			
		||||
    if( xWantedSize > 0 )
 | 
			
		||||
    {
 | 
			
		||||
        /* The wanted size must be increased so it can contain a BlockLink_t
 | 
			
		||||
         * structure in addition to the requested amount of bytes. */
 | 
			
		||||
        if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize += xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
            /* Ensure that blocks are always aligned to the required number
 | 
			
		||||
             * of bytes. */
 | 
			
		||||
            if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Byte alignment required. */
 | 
			
		||||
                xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
                if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize += xAdditionalRequiredSize;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        /* If this is the first call to malloc then the heap will require
 | 
			
		||||
         * initialisation to setup the list of free blocks. */
 | 
			
		||||
        if( pxEnd == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            prvHeapInit();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check the block size we are trying to allocate is not so large that the
 | 
			
		||||
         * top bit is set.  The top bit of the block size member of the BlockLink_t
 | 
			
		||||
         * structure is used to determine who owns the block - the application or
 | 
			
		||||
         * the kernel, so it must be free. */
 | 
			
		||||
        if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
 | 
			
		||||
            {
 | 
			
		||||
                /* Traverse the list from the start (lowest address) block until
 | 
			
		||||
                 * one of adequate size is found. */
 | 
			
		||||
                pxPreviousBlock = &xStart;
 | 
			
		||||
                pxBlock = heapPROTECT_BLOCK_POINTER( xStart.pxNextFreeBlock );
 | 
			
		||||
                heapVALIDATE_BLOCK_POINTER( pxBlock );
 | 
			
		||||
 | 
			
		||||
                while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != heapPROTECT_BLOCK_POINTER( NULL ) ) )
 | 
			
		||||
                {
 | 
			
		||||
                    pxPreviousBlock = pxBlock;
 | 
			
		||||
                    pxBlock = heapPROTECT_BLOCK_POINTER( pxBlock->pxNextFreeBlock );
 | 
			
		||||
                    heapVALIDATE_BLOCK_POINTER( pxBlock );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* If the end marker was reached then a block of adequate size
 | 
			
		||||
                 * was not found. */
 | 
			
		||||
                if( pxBlock != pxEnd )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Return the memory space pointed to - jumping over the
 | 
			
		||||
                     * BlockLink_t structure at its start. */
 | 
			
		||||
                    pvReturn = ( void * ) ( ( ( uint8_t * ) heapPROTECT_BLOCK_POINTER( pxPreviousBlock->pxNextFreeBlock ) ) + xHeapStructSize );
 | 
			
		||||
                    heapVALIDATE_BLOCK_POINTER( pvReturn );
 | 
			
		||||
 | 
			
		||||
                    /* This block is being returned for use so must be taken out
 | 
			
		||||
                     * of the list of free blocks. */
 | 
			
		||||
                    pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
 | 
			
		||||
                    /* If the block is larger than required it can be split into
 | 
			
		||||
                     * two. */
 | 
			
		||||
                    configASSERT( heapSUBTRACT_WILL_UNDERFLOW( pxBlock->xBlockSize, xWantedSize ) == 0 );
 | 
			
		||||
 | 
			
		||||
                    if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
 | 
			
		||||
                    {
 | 
			
		||||
                        /* This block is to be split into two.  Create a new
 | 
			
		||||
                         * block following the number of bytes requested. The void
 | 
			
		||||
                         * cast is used to prevent byte alignment warnings from the
 | 
			
		||||
                         * compiler. */
 | 
			
		||||
                        pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
 | 
			
		||||
                        configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
 | 
			
		||||
 | 
			
		||||
                        /* Calculate the sizes of two blocks split from the
 | 
			
		||||
                         * single block. */
 | 
			
		||||
                        pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
 | 
			
		||||
                        pxBlock->xBlockSize = xWantedSize;
 | 
			
		||||
 | 
			
		||||
                        /* Insert the new block into the list of free blocks. */
 | 
			
		||||
                        pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
 | 
			
		||||
                        pxPreviousBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxNewBlockLink );
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    xFreeBytesRemaining -= pxBlock->xBlockSize;
 | 
			
		||||
 | 
			
		||||
                    if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
 | 
			
		||||
                    {
 | 
			
		||||
                        xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* The block is being returned - it is allocated and owned
 | 
			
		||||
                     * by the application and has no "next" block. */
 | 
			
		||||
                    heapALLOCATE_BLOCK( pxBlock );
 | 
			
		||||
                    pxBlock->pxNextFreeBlock = NULL;
 | 
			
		||||
                    xNumberOfSuccessfulAllocations++;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
 | 
			
		||||
 | 
			
		||||
    configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    uint8_t * puc = ( uint8_t * ) pv;
 | 
			
		||||
    BlockLink_t * pxLink;
 | 
			
		||||
 | 
			
		||||
    if( pv != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        /* The memory being freed will have an BlockLink_t structure immediately
 | 
			
		||||
         * before it. */
 | 
			
		||||
        puc -= xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
        /* This casting is to keep the compiler from issuing warnings. */
 | 
			
		||||
        pxLink = ( void * ) puc;
 | 
			
		||||
 | 
			
		||||
        heapVALIDATE_BLOCK_POINTER( pxLink );
 | 
			
		||||
        configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
 | 
			
		||||
        configASSERT( pxLink->pxNextFreeBlock == NULL );
 | 
			
		||||
 | 
			
		||||
        if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( pxLink->pxNextFreeBlock == NULL )
 | 
			
		||||
            {
 | 
			
		||||
                /* The block is being returned to the heap - it is no longer
 | 
			
		||||
                 * allocated. */
 | 
			
		||||
                heapFREE_BLOCK( pxLink );
 | 
			
		||||
                #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Check for underflow as this can occur if xBlockSize is
 | 
			
		||||
                     * overwritten in a heap block. */
 | 
			
		||||
                    if( heapSUBTRACT_WILL_UNDERFLOW( pxLink->xBlockSize, xHeapStructSize ) == 0 )
 | 
			
		||||
                    {
 | 
			
		||||
                        ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                vTaskSuspendAll();
 | 
			
		||||
                {
 | 
			
		||||
                    /* Add this block to the list of free blocks. */
 | 
			
		||||
                    xFreeBytesRemaining += pxLink->xBlockSize;
 | 
			
		||||
                    traceFREE( pv, pxLink->xBlockSize );
 | 
			
		||||
                    prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
 | 
			
		||||
                    xNumberOfSuccessfulFrees++;
 | 
			
		||||
                }
 | 
			
		||||
                ( void ) xTaskResumeAll();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return xFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetMinimumEverFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return xMinimumEverFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortInitialiseBlocks( void )
 | 
			
		||||
{
 | 
			
		||||
    /* This just exists to keep the linker quiet. */
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortCalloc( size_t xNum,
 | 
			
		||||
                     size_t xSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pv = NULL;
 | 
			
		||||
 | 
			
		||||
    if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pv = pvPortMalloc( xNum * xSize );
 | 
			
		||||
 | 
			
		||||
        if( pv != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            ( void ) memset( pv, 0, xNum * xSize );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return pv;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxFirstFreeBlock;
 | 
			
		||||
    portPOINTER_SIZE_TYPE uxStartAddress, uxEndAddress;
 | 
			
		||||
    size_t xTotalHeapSize = configTOTAL_HEAP_SIZE;
 | 
			
		||||
 | 
			
		||||
    /* Ensure the heap starts on a correctly aligned boundary. */
 | 
			
		||||
    uxStartAddress = ( portPOINTER_SIZE_TYPE ) ucHeap;
 | 
			
		||||
 | 
			
		||||
    if( ( uxStartAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        uxStartAddress += ( portBYTE_ALIGNMENT - 1 );
 | 
			
		||||
        uxStartAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
        xTotalHeapSize -= ( size_t ) ( uxStartAddress - ( portPOINTER_SIZE_TYPE ) ucHeap );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        vApplicationGetRandomHeapCanary( &( xHeapCanary ) );
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    /* xStart is used to hold a pointer to the first item in the list of free
 | 
			
		||||
     * blocks.  The void cast is used to prevent compiler warnings. */
 | 
			
		||||
    xStart.pxNextFreeBlock = ( void * ) heapPROTECT_BLOCK_POINTER( uxStartAddress );
 | 
			
		||||
    xStart.xBlockSize = ( size_t ) 0;
 | 
			
		||||
 | 
			
		||||
    /* pxEnd is used to mark the end of the list of free blocks and is inserted
 | 
			
		||||
     * at the end of the heap space. */
 | 
			
		||||
    uxEndAddress = uxStartAddress + ( portPOINTER_SIZE_TYPE ) xTotalHeapSize;
 | 
			
		||||
    uxEndAddress -= ( portPOINTER_SIZE_TYPE ) xHeapStructSize;
 | 
			
		||||
    uxEndAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
    pxEnd = ( BlockLink_t * ) uxEndAddress;
 | 
			
		||||
    pxEnd->xBlockSize = 0;
 | 
			
		||||
    pxEnd->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( NULL );
 | 
			
		||||
 | 
			
		||||
    /* To start with there is a single free block that is sized to take up the
 | 
			
		||||
     * entire heap space, minus the space taken by pxEnd. */
 | 
			
		||||
    pxFirstFreeBlock = ( BlockLink_t * ) uxStartAddress;
 | 
			
		||||
    pxFirstFreeBlock->xBlockSize = ( size_t ) ( uxEndAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlock );
 | 
			
		||||
    pxFirstFreeBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxEnd );
 | 
			
		||||
 | 
			
		||||
    /* Only one block exists - and it covers the entire usable heap space. */
 | 
			
		||||
    xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
 | 
			
		||||
    xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxIterator;
 | 
			
		||||
    uint8_t * puc;
 | 
			
		||||
 | 
			
		||||
    /* Iterate through the list until a block is found that has a higher address
 | 
			
		||||
     * than the block being inserted. */
 | 
			
		||||
    for( pxIterator = &xStart; heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) < pxBlockToInsert; pxIterator = heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) )
 | 
			
		||||
    {
 | 
			
		||||
        /* Nothing to do here, just iterate to the right position. */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( pxIterator != &xStart )
 | 
			
		||||
    {
 | 
			
		||||
        heapVALIDATE_BLOCK_POINTER( pxIterator );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do the block being inserted, and the block it is being inserted after
 | 
			
		||||
     * make a contiguous block of memory? */
 | 
			
		||||
    puc = ( uint8_t * ) pxIterator;
 | 
			
		||||
 | 
			
		||||
    if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
 | 
			
		||||
    {
 | 
			
		||||
        pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
 | 
			
		||||
        pxBlockToInsert = pxIterator;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do the block being inserted, and the block it is being inserted before
 | 
			
		||||
     * make a contiguous block of memory? */
 | 
			
		||||
    puc = ( uint8_t * ) pxBlockToInsert;
 | 
			
		||||
 | 
			
		||||
    if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) )
 | 
			
		||||
    {
 | 
			
		||||
        if( heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) != pxEnd )
 | 
			
		||||
        {
 | 
			
		||||
            /* Form one big block from the two blocks. */
 | 
			
		||||
            pxBlockToInsert->xBlockSize += heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock )->xBlockSize;
 | 
			
		||||
            pxBlockToInsert->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock )->pxNextFreeBlock;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            pxBlockToInsert->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxEnd );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the block being inserted plugged a gab, so was merged with the block
 | 
			
		||||
     * before and the block after, then it's pxNextFreeBlock pointer will have
 | 
			
		||||
     * already been set, and should not be set here as that would make it point
 | 
			
		||||
     * to itself. */
 | 
			
		||||
    if( pxIterator != pxBlockToInsert )
 | 
			
		||||
    {
 | 
			
		||||
        pxIterator->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxBlockToInsert );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortGetHeapStats( HeapStats_t * pxHeapStats )
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxBlock;
 | 
			
		||||
    size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        pxBlock = heapPROTECT_BLOCK_POINTER( xStart.pxNextFreeBlock );
 | 
			
		||||
 | 
			
		||||
        /* pxBlock will be NULL if the heap has not been initialised.  The heap
 | 
			
		||||
         * is initialised automatically when the first allocation is made. */
 | 
			
		||||
        if( pxBlock != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            while( pxBlock != pxEnd )
 | 
			
		||||
            {
 | 
			
		||||
                /* Increment the number of blocks and record the largest block seen
 | 
			
		||||
                 * so far. */
 | 
			
		||||
                xBlocks++;
 | 
			
		||||
 | 
			
		||||
                if( pxBlock->xBlockSize > xMaxSize )
 | 
			
		||||
                {
 | 
			
		||||
                    xMaxSize = pxBlock->xBlockSize;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if( pxBlock->xBlockSize < xMinSize )
 | 
			
		||||
                {
 | 
			
		||||
                    xMinSize = pxBlock->xBlockSize;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Move to the next block in the chain until the last block is
 | 
			
		||||
                 * reached. */
 | 
			
		||||
                pxBlock = heapPROTECT_BLOCK_POINTER( pxBlock->pxNextFreeBlock );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
 | 
			
		||||
    pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
 | 
			
		||||
    pxHeapStats->xNumberOfFreeBlocks = xBlocks;
 | 
			
		||||
 | 
			
		||||
    taskENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
 | 
			
		||||
        pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
 | 
			
		||||
        pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
 | 
			
		||||
        pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
 | 
			
		||||
    }
 | 
			
		||||
    taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    pxEnd = NULL;
 | 
			
		||||
 | 
			
		||||
    xFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
    xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
    xNumberOfSuccessfulAllocations = ( size_t ) 0U;
 | 
			
		||||
    xNumberOfSuccessfulFrees = ( size_t ) 0U;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										730
									
								
								heap/heap_5.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										730
									
								
								heap/heap_5.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,730 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * A sample implementation of pvPortMalloc() that allows the heap to be defined
 | 
			
		||||
 * across multiple non-contiguous blocks and combines (coalescences) adjacent
 | 
			
		||||
 * memory blocks as they are freed.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative
 | 
			
		||||
 * implementations, and the memory management pages of https://www.FreeRTOS.org
 | 
			
		||||
 * for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Usage notes:
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc().
 | 
			
		||||
 * pvPortMalloc() will be called if any task objects (tasks, queues, event
 | 
			
		||||
 * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be
 | 
			
		||||
 * called before any other objects are defined.
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions() takes a single parameter.  The parameter is an array
 | 
			
		||||
 * of HeapRegion_t structures.  HeapRegion_t is defined in portable.h as
 | 
			
		||||
 *
 | 
			
		||||
 * typedef struct HeapRegion
 | 
			
		||||
 * {
 | 
			
		||||
 *  uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap.
 | 
			
		||||
 *  size_t xSizeInBytes;      << Size of the block of memory.
 | 
			
		||||
 * } HeapRegion_t;
 | 
			
		||||
 *
 | 
			
		||||
 * The array is terminated using a NULL zero sized region definition, and the
 | 
			
		||||
 * memory regions defined in the array ***must*** appear in address order from
 | 
			
		||||
 * low address to high address.  So the following is a valid example of how
 | 
			
		||||
 * to use the function.
 | 
			
		||||
 *
 | 
			
		||||
 * HeapRegion_t xHeapRegions[] =
 | 
			
		||||
 * {
 | 
			
		||||
 *  { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000
 | 
			
		||||
 *  { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000
 | 
			
		||||
 *  { NULL, 0 }                << Terminates the array.
 | 
			
		||||
 * };
 | 
			
		||||
 *
 | 
			
		||||
 * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions().
 | 
			
		||||
 *
 | 
			
		||||
 * Note 0x80000000 is the lower address so appears in the array first.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configHEAP_CLEAR_MEMORY_ON_FREE
 | 
			
		||||
    #define configHEAP_CLEAR_MEMORY_ON_FREE    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Block sizes must not get too small. */
 | 
			
		||||
#define heapMINIMUM_BLOCK_SIZE    ( ( size_t ) ( xHeapStructSize << 1 ) )
 | 
			
		||||
 | 
			
		||||
/* Assumes 8bit bytes! */
 | 
			
		||||
#define heapBITS_PER_BYTE         ( ( size_t ) 8 )
 | 
			
		||||
 | 
			
		||||
/* Max value that fits in a size_t type. */
 | 
			
		||||
#define heapSIZE_MAX              ( ~( ( size_t ) 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Check if multiplying a and b will result in overflow. */
 | 
			
		||||
#define heapMULTIPLY_WILL_OVERFLOW( a, b )     ( ( ( a ) > 0 ) && ( ( b ) > ( heapSIZE_MAX / ( a ) ) ) )
 | 
			
		||||
 | 
			
		||||
/* Check if adding a and b will result in overflow. */
 | 
			
		||||
#define heapADD_WILL_OVERFLOW( a, b )          ( ( a ) > ( heapSIZE_MAX - ( b ) ) )
 | 
			
		||||
 | 
			
		||||
/* Check if the subtraction operation ( a - b ) will result in underflow. */
 | 
			
		||||
#define heapSUBTRACT_WILL_UNDERFLOW( a, b )    ( ( a ) < ( b ) )
 | 
			
		||||
 | 
			
		||||
/* MSB of the xBlockSize member of an BlockLink_t structure is used to track
 | 
			
		||||
 * the allocation status of a block.  When MSB of the xBlockSize member of
 | 
			
		||||
 * an BlockLink_t structure is set then the block belongs to the application.
 | 
			
		||||
 * When the bit is free the block is still part of the free heap space. */
 | 
			
		||||
#define heapBLOCK_ALLOCATED_BITMASK    ( ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ) )
 | 
			
		||||
#define heapBLOCK_SIZE_IS_VALID( xBlockSize )    ( ( ( xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) == 0 )
 | 
			
		||||
#define heapBLOCK_IS_ALLOCATED( pxBlock )        ( ( ( pxBlock->xBlockSize ) & heapBLOCK_ALLOCATED_BITMASK ) != 0 )
 | 
			
		||||
#define heapALLOCATE_BLOCK( pxBlock )            ( ( pxBlock->xBlockSize ) |= heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
#define heapFREE_BLOCK( pxBlock )                ( ( pxBlock->xBlockSize ) &= ~heapBLOCK_ALLOCATED_BITMASK )
 | 
			
		||||
 | 
			
		||||
/* Setting configENABLE_HEAP_PROTECTOR to 1 enables heap block pointers
 | 
			
		||||
 * protection using an application supplied canary value to catch heap
 | 
			
		||||
 * corruption should a heap buffer overflow occur.
 | 
			
		||||
 */
 | 
			
		||||
#if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
 | 
			
		||||
/* Macro to load/store BlockLink_t pointers to memory. By XORing the
 | 
			
		||||
 * pointers with a random canary value, heap overflows will result
 | 
			
		||||
 * in randomly unpredictable pointer values which will be caught by
 | 
			
		||||
 * heapVALIDATE_BLOCK_POINTER assert. */
 | 
			
		||||
    #define heapPROTECT_BLOCK_POINTER( pxBlock )    ( ( BlockLink_t * ) ( ( ( portPOINTER_SIZE_TYPE ) ( pxBlock ) ) ^ xHeapCanary ) )
 | 
			
		||||
 | 
			
		||||
/* Assert that a heap block pointer is within the heap bounds. */
 | 
			
		||||
    #define heapVALIDATE_BLOCK_POINTER( pxBlock )                       \
 | 
			
		||||
    configASSERT( ( pucHeapHighAddress != NULL ) &&                     \
 | 
			
		||||
                  ( pucHeapLowAddress != NULL ) &&                      \
 | 
			
		||||
                  ( ( uint8_t * ) ( pxBlock ) >= pucHeapLowAddress ) && \
 | 
			
		||||
                  ( ( uint8_t * ) ( pxBlock ) < pucHeapHighAddress ) )
 | 
			
		||||
 | 
			
		||||
#else /* if ( configENABLE_HEAP_PROTECTOR == 1 ) */
 | 
			
		||||
 | 
			
		||||
    #define heapPROTECT_BLOCK_POINTER( pxBlock )    ( pxBlock )
 | 
			
		||||
 | 
			
		||||
    #define heapVALIDATE_BLOCK_POINTER( pxBlock )
 | 
			
		||||
 | 
			
		||||
#endif /* configENABLE_HEAP_PROTECTOR */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Define the linked list structure.  This is used to link free blocks in order
 | 
			
		||||
 * of their memory address. */
 | 
			
		||||
typedef struct A_BLOCK_LINK
 | 
			
		||||
{
 | 
			
		||||
    struct A_BLOCK_LINK * pxNextFreeBlock; /**< The next free block in the list. */
 | 
			
		||||
    size_t xBlockSize;                     /**< The size of the free block. */
 | 
			
		||||
} BlockLink_t;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Inserts a block of memory that is being freed into the correct position in
 | 
			
		||||
 * the list of free memory blocks.  The block being freed will be merged with
 | 
			
		||||
 * the block in front it and/or the block behind it if the memory blocks are
 | 
			
		||||
 * adjacent to each other.
 | 
			
		||||
 */
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
#if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Application provided function to get a random value to be used as canary.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHeapCanary [out] Output parameter to return the canary value.
 | 
			
		||||
 */
 | 
			
		||||
    extern void vApplicationGetRandomHeapCanary( portPOINTER_SIZE_TYPE * pxHeapCanary );
 | 
			
		||||
#endif /* configENABLE_HEAP_PROTECTOR */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* The size of the structure placed at the beginning of each allocated memory
 | 
			
		||||
 * block must by correctly byte aligned. */
 | 
			
		||||
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
/* Create a couple of list links to mark the start and end of the list. */
 | 
			
		||||
PRIVILEGED_DATA static BlockLink_t xStart;
 | 
			
		||||
PRIVILEGED_DATA static BlockLink_t * pxEnd = NULL;
 | 
			
		||||
 | 
			
		||||
/* Keeps track of the number of calls to allocate and free memory as well as the
 | 
			
		||||
 * number of free bytes remaining, but says nothing about fragmentation. */
 | 
			
		||||
PRIVILEGED_DATA static size_t xFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = ( size_t ) 0U;
 | 
			
		||||
PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = ( size_t ) 0U;
 | 
			
		||||
 | 
			
		||||
#if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
 | 
			
		||||
/* Canary value for protecting internal heap pointers. */
 | 
			
		||||
    PRIVILEGED_DATA static portPOINTER_SIZE_TYPE xHeapCanary;
 | 
			
		||||
 | 
			
		||||
/* Highest and lowest heap addresses used for heap block bounds checking. */
 | 
			
		||||
    PRIVILEGED_DATA static uint8_t * pucHeapHighAddress = NULL;
 | 
			
		||||
    PRIVILEGED_DATA static uint8_t * pucHeapLowAddress = NULL;
 | 
			
		||||
 | 
			
		||||
#endif /* configENABLE_HEAP_PROTECTOR */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxBlock;
 | 
			
		||||
    BlockLink_t * pxPreviousBlock;
 | 
			
		||||
    BlockLink_t * pxNewBlockLink;
 | 
			
		||||
    void * pvReturn = NULL;
 | 
			
		||||
    size_t xAdditionalRequiredSize;
 | 
			
		||||
 | 
			
		||||
    /* The heap must be initialised before the first call to
 | 
			
		||||
     * pvPortMalloc(). */
 | 
			
		||||
    configASSERT( pxEnd );
 | 
			
		||||
 | 
			
		||||
    if( xWantedSize > 0 )
 | 
			
		||||
    {
 | 
			
		||||
        /* The wanted size must be increased so it can contain a BlockLink_t
 | 
			
		||||
         * structure in addition to the requested amount of bytes. */
 | 
			
		||||
        if( heapADD_WILL_OVERFLOW( xWantedSize, xHeapStructSize ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize += xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
            /* Ensure that blocks are always aligned to the required number
 | 
			
		||||
             * of bytes. */
 | 
			
		||||
            if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
 | 
			
		||||
            {
 | 
			
		||||
                /* Byte alignment required. */
 | 
			
		||||
                xAdditionalRequiredSize = portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
 | 
			
		||||
                if( heapADD_WILL_OVERFLOW( xWantedSize, xAdditionalRequiredSize ) == 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize += xAdditionalRequiredSize;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    xWantedSize = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            xWantedSize = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        /* Check the block size we are trying to allocate is not so large that the
 | 
			
		||||
         * top bit is set.  The top bit of the block size member of the BlockLink_t
 | 
			
		||||
         * structure is used to determine who owns the block - the application or
 | 
			
		||||
         * the kernel, so it must be free. */
 | 
			
		||||
        if( heapBLOCK_SIZE_IS_VALID( xWantedSize ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
 | 
			
		||||
            {
 | 
			
		||||
                /* Traverse the list from the start (lowest address) block until
 | 
			
		||||
                 * one of adequate size is found. */
 | 
			
		||||
                pxPreviousBlock = &xStart;
 | 
			
		||||
                pxBlock = heapPROTECT_BLOCK_POINTER( xStart.pxNextFreeBlock );
 | 
			
		||||
                heapVALIDATE_BLOCK_POINTER( pxBlock );
 | 
			
		||||
 | 
			
		||||
                while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != heapPROTECT_BLOCK_POINTER( NULL ) ) )
 | 
			
		||||
                {
 | 
			
		||||
                    pxPreviousBlock = pxBlock;
 | 
			
		||||
                    pxBlock = heapPROTECT_BLOCK_POINTER( pxBlock->pxNextFreeBlock );
 | 
			
		||||
                    heapVALIDATE_BLOCK_POINTER( pxBlock );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* If the end marker was reached then a block of adequate size
 | 
			
		||||
                 * was not found. */
 | 
			
		||||
                if( pxBlock != pxEnd )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Return the memory space pointed to - jumping over the
 | 
			
		||||
                     * BlockLink_t structure at its start. */
 | 
			
		||||
                    pvReturn = ( void * ) ( ( ( uint8_t * ) heapPROTECT_BLOCK_POINTER( pxPreviousBlock->pxNextFreeBlock ) ) + xHeapStructSize );
 | 
			
		||||
                    heapVALIDATE_BLOCK_POINTER( pvReturn );
 | 
			
		||||
 | 
			
		||||
                    /* This block is being returned for use so must be taken out
 | 
			
		||||
                     * of the list of free blocks. */
 | 
			
		||||
                    pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
 | 
			
		||||
 | 
			
		||||
                    /* If the block is larger than required it can be split into
 | 
			
		||||
                     * two. */
 | 
			
		||||
                    configASSERT( heapSUBTRACT_WILL_UNDERFLOW( pxBlock->xBlockSize, xWantedSize ) == 0 );
 | 
			
		||||
 | 
			
		||||
                    if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
 | 
			
		||||
                    {
 | 
			
		||||
                        /* This block is to be split into two.  Create a new
 | 
			
		||||
                         * block following the number of bytes requested. The void
 | 
			
		||||
                         * cast is used to prevent byte alignment warnings from the
 | 
			
		||||
                         * compiler. */
 | 
			
		||||
                        pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
 | 
			
		||||
                        configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 );
 | 
			
		||||
 | 
			
		||||
                        /* Calculate the sizes of two blocks split from the
 | 
			
		||||
                         * single block. */
 | 
			
		||||
                        pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
 | 
			
		||||
                        pxBlock->xBlockSize = xWantedSize;
 | 
			
		||||
 | 
			
		||||
                        /* Insert the new block into the list of free blocks. */
 | 
			
		||||
                        pxNewBlockLink->pxNextFreeBlock = pxPreviousBlock->pxNextFreeBlock;
 | 
			
		||||
                        pxPreviousBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxNewBlockLink );
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    xFreeBytesRemaining -= pxBlock->xBlockSize;
 | 
			
		||||
 | 
			
		||||
                    if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
 | 
			
		||||
                    {
 | 
			
		||||
                        xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    /* The block is being returned - it is allocated and owned
 | 
			
		||||
                     * by the application and has no "next" block. */
 | 
			
		||||
                    heapALLOCATE_BLOCK( pxBlock );
 | 
			
		||||
                    pxBlock->pxNextFreeBlock = NULL;
 | 
			
		||||
                    xNumberOfSuccessfulAllocations++;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */
 | 
			
		||||
 | 
			
		||||
    configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 );
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    uint8_t * puc = ( uint8_t * ) pv;
 | 
			
		||||
    BlockLink_t * pxLink;
 | 
			
		||||
 | 
			
		||||
    if( pv != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        /* The memory being freed will have an BlockLink_t structure immediately
 | 
			
		||||
         * before it. */
 | 
			
		||||
        puc -= xHeapStructSize;
 | 
			
		||||
 | 
			
		||||
        /* This casting is to keep the compiler from issuing warnings. */
 | 
			
		||||
        pxLink = ( void * ) puc;
 | 
			
		||||
 | 
			
		||||
        heapVALIDATE_BLOCK_POINTER( pxLink );
 | 
			
		||||
        configASSERT( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 );
 | 
			
		||||
        configASSERT( pxLink->pxNextFreeBlock == NULL );
 | 
			
		||||
 | 
			
		||||
        if( heapBLOCK_IS_ALLOCATED( pxLink ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if( pxLink->pxNextFreeBlock == NULL )
 | 
			
		||||
            {
 | 
			
		||||
                /* The block is being returned to the heap - it is no longer
 | 
			
		||||
                 * allocated. */
 | 
			
		||||
                heapFREE_BLOCK( pxLink );
 | 
			
		||||
                #if ( configHEAP_CLEAR_MEMORY_ON_FREE == 1 )
 | 
			
		||||
                {
 | 
			
		||||
                    /* Check for underflow as this can occur if xBlockSize is
 | 
			
		||||
                     * overwritten in a heap block. */
 | 
			
		||||
                    if( heapSUBTRACT_WILL_UNDERFLOW( pxLink->xBlockSize, xHeapStructSize ) == 0 )
 | 
			
		||||
                    {
 | 
			
		||||
                        ( void ) memset( puc + xHeapStructSize, 0, pxLink->xBlockSize - xHeapStructSize );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                #endif
 | 
			
		||||
 | 
			
		||||
                vTaskSuspendAll();
 | 
			
		||||
                {
 | 
			
		||||
                    /* Add this block to the list of free blocks. */
 | 
			
		||||
                    xFreeBytesRemaining += pxLink->xBlockSize;
 | 
			
		||||
                    traceFREE( pv, pxLink->xBlockSize );
 | 
			
		||||
                    prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
 | 
			
		||||
                    xNumberOfSuccessfulFrees++;
 | 
			
		||||
                }
 | 
			
		||||
                ( void ) xTaskResumeAll();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return xFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetMinimumEverFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return xMinimumEverFreeBytesRemaining;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortCalloc( size_t xNum,
 | 
			
		||||
                     size_t xSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pv = NULL;
 | 
			
		||||
 | 
			
		||||
    if( heapMULTIPLY_WILL_OVERFLOW( xNum, xSize ) == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pv = pvPortMalloc( xNum * xSize );
 | 
			
		||||
 | 
			
		||||
        if( pv != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            ( void ) memset( pv, 0, xNum * xSize );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return pv;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxIterator;
 | 
			
		||||
    uint8_t * puc;
 | 
			
		||||
 | 
			
		||||
    /* Iterate through the list until a block is found that has a higher address
 | 
			
		||||
     * than the block being inserted. */
 | 
			
		||||
    for( pxIterator = &xStart; heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) < pxBlockToInsert; pxIterator = heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) )
 | 
			
		||||
    {
 | 
			
		||||
        /* Nothing to do here, just iterate to the right position. */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( pxIterator != &xStart )
 | 
			
		||||
    {
 | 
			
		||||
        heapVALIDATE_BLOCK_POINTER( pxIterator );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do the block being inserted, and the block it is being inserted after
 | 
			
		||||
     * make a contiguous block of memory? */
 | 
			
		||||
    puc = ( uint8_t * ) pxIterator;
 | 
			
		||||
 | 
			
		||||
    if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
 | 
			
		||||
    {
 | 
			
		||||
        pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
 | 
			
		||||
        pxBlockToInsert = pxIterator;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Do the block being inserted, and the block it is being inserted before
 | 
			
		||||
     * make a contiguous block of memory? */
 | 
			
		||||
    puc = ( uint8_t * ) pxBlockToInsert;
 | 
			
		||||
 | 
			
		||||
    if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) )
 | 
			
		||||
    {
 | 
			
		||||
        if( heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock ) != pxEnd )
 | 
			
		||||
        {
 | 
			
		||||
            /* Form one big block from the two blocks. */
 | 
			
		||||
            pxBlockToInsert->xBlockSize += heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock )->xBlockSize;
 | 
			
		||||
            pxBlockToInsert->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxIterator->pxNextFreeBlock )->pxNextFreeBlock;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            pxBlockToInsert->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxEnd );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the block being inserted plugged a gap, so was merged with the block
 | 
			
		||||
     * before and the block after, then it's pxNextFreeBlock pointer will have
 | 
			
		||||
     * already been set, and should not be set here as that would make it point
 | 
			
		||||
     * to itself. */
 | 
			
		||||
    if( pxIterator != pxBlockToInsert )
 | 
			
		||||
    {
 | 
			
		||||
        pxIterator->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxBlockToInsert );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) /* PRIVILEGED_FUNCTION */
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxFirstFreeBlockInRegion = NULL;
 | 
			
		||||
    BlockLink_t * pxPreviousFreeBlock;
 | 
			
		||||
    portPOINTER_SIZE_TYPE xAlignedHeap;
 | 
			
		||||
    size_t xTotalRegionSize, xTotalHeapSize = 0;
 | 
			
		||||
    BaseType_t xDefinedRegions = 0;
 | 
			
		||||
    portPOINTER_SIZE_TYPE xAddress;
 | 
			
		||||
    const HeapRegion_t * pxHeapRegion;
 | 
			
		||||
 | 
			
		||||
    /* Can only call once! */
 | 
			
		||||
    configASSERT( pxEnd == NULL );
 | 
			
		||||
 | 
			
		||||
    #if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        vApplicationGetRandomHeapCanary( &( xHeapCanary ) );
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
 | 
			
		||||
 | 
			
		||||
    while( pxHeapRegion->xSizeInBytes > 0 )
 | 
			
		||||
    {
 | 
			
		||||
        xTotalRegionSize = pxHeapRegion->xSizeInBytes;
 | 
			
		||||
 | 
			
		||||
        /* Ensure the heap region starts on a correctly aligned boundary. */
 | 
			
		||||
        xAddress = ( portPOINTER_SIZE_TYPE ) pxHeapRegion->pucStartAddress;
 | 
			
		||||
 | 
			
		||||
        if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            xAddress += ( portBYTE_ALIGNMENT - 1 );
 | 
			
		||||
            xAddress &= ~( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK;
 | 
			
		||||
 | 
			
		||||
            /* Adjust the size for the bytes lost to alignment. */
 | 
			
		||||
            xTotalRegionSize -= ( size_t ) ( xAddress - ( portPOINTER_SIZE_TYPE ) pxHeapRegion->pucStartAddress );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xAlignedHeap = xAddress;
 | 
			
		||||
 | 
			
		||||
        /* Set xStart if it has not already been set. */
 | 
			
		||||
        if( xDefinedRegions == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            /* xStart is used to hold a pointer to the first item in the list of
 | 
			
		||||
             *  free blocks.  The void cast is used to prevent compiler warnings. */
 | 
			
		||||
            xStart.pxNextFreeBlock = ( BlockLink_t * ) heapPROTECT_BLOCK_POINTER( xAlignedHeap );
 | 
			
		||||
            xStart.xBlockSize = ( size_t ) 0;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            /* Should only get here if one region has already been added to the
 | 
			
		||||
             * heap. */
 | 
			
		||||
            configASSERT( pxEnd != heapPROTECT_BLOCK_POINTER( NULL ) );
 | 
			
		||||
 | 
			
		||||
            /* Check blocks are passed in with increasing start addresses. */
 | 
			
		||||
            configASSERT( ( size_t ) xAddress > ( size_t ) pxEnd );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            if( ( pucHeapLowAddress == NULL ) ||
 | 
			
		||||
                ( ( uint8_t * ) xAlignedHeap < pucHeapLowAddress ) )
 | 
			
		||||
            {
 | 
			
		||||
                pucHeapLowAddress = ( uint8_t * ) xAlignedHeap;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endif /* configENABLE_HEAP_PROTECTOR */
 | 
			
		||||
 | 
			
		||||
        /* Remember the location of the end marker in the previous region, if
 | 
			
		||||
         * any. */
 | 
			
		||||
        pxPreviousFreeBlock = pxEnd;
 | 
			
		||||
 | 
			
		||||
        /* pxEnd is used to mark the end of the list of free blocks and is
 | 
			
		||||
         * inserted at the end of the region space. */
 | 
			
		||||
        xAddress = xAlignedHeap + ( portPOINTER_SIZE_TYPE ) xTotalRegionSize;
 | 
			
		||||
        xAddress -= ( portPOINTER_SIZE_TYPE ) xHeapStructSize;
 | 
			
		||||
        xAddress &= ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK );
 | 
			
		||||
        pxEnd = ( BlockLink_t * ) xAddress;
 | 
			
		||||
        pxEnd->xBlockSize = 0;
 | 
			
		||||
        pxEnd->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( NULL );
 | 
			
		||||
 | 
			
		||||
        /* To start with there is a single free block in this region that is
 | 
			
		||||
         * sized to take up the entire heap region minus the space taken by the
 | 
			
		||||
         * free block structure. */
 | 
			
		||||
        pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;
 | 
			
		||||
        pxFirstFreeBlockInRegion->xBlockSize = ( size_t ) ( xAddress - ( portPOINTER_SIZE_TYPE ) pxFirstFreeBlockInRegion );
 | 
			
		||||
        pxFirstFreeBlockInRegion->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxEnd );
 | 
			
		||||
 | 
			
		||||
        /* If this is not the first region that makes up the entire heap space
 | 
			
		||||
         * then link the previous region to this region. */
 | 
			
		||||
        if( pxPreviousFreeBlock != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            pxPreviousFreeBlock->pxNextFreeBlock = heapPROTECT_BLOCK_POINTER( pxFirstFreeBlockInRegion );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
 | 
			
		||||
 | 
			
		||||
        #if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
        {
 | 
			
		||||
            if( ( pucHeapHighAddress == NULL ) ||
 | 
			
		||||
                ( ( ( ( uint8_t * ) pxFirstFreeBlockInRegion ) + pxFirstFreeBlockInRegion->xBlockSize ) > pucHeapHighAddress ) )
 | 
			
		||||
            {
 | 
			
		||||
                pucHeapHighAddress = ( ( uint8_t * ) pxFirstFreeBlockInRegion ) + pxFirstFreeBlockInRegion->xBlockSize;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        #endif
 | 
			
		||||
 | 
			
		||||
        /* Move onto the next HeapRegion_t structure. */
 | 
			
		||||
        xDefinedRegions++;
 | 
			
		||||
        pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    xMinimumEverFreeBytesRemaining = xTotalHeapSize;
 | 
			
		||||
    xFreeBytesRemaining = xTotalHeapSize;
 | 
			
		||||
 | 
			
		||||
    /* Check something was actually defined before it is accessed. */
 | 
			
		||||
    configASSERT( xTotalHeapSize );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortGetHeapStats( HeapStats_t * pxHeapStats )
 | 
			
		||||
{
 | 
			
		||||
    BlockLink_t * pxBlock;
 | 
			
		||||
    size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        pxBlock = heapPROTECT_BLOCK_POINTER( xStart.pxNextFreeBlock );
 | 
			
		||||
 | 
			
		||||
        /* pxBlock will be NULL if the heap has not been initialised.  The heap
 | 
			
		||||
         * is initialised automatically when the first allocation is made. */
 | 
			
		||||
        if( pxBlock != NULL )
 | 
			
		||||
        {
 | 
			
		||||
            while( pxBlock != pxEnd )
 | 
			
		||||
            {
 | 
			
		||||
                /* Increment the number of blocks and record the largest block seen
 | 
			
		||||
                 * so far. */
 | 
			
		||||
                xBlocks++;
 | 
			
		||||
 | 
			
		||||
                if( pxBlock->xBlockSize > xMaxSize )
 | 
			
		||||
                {
 | 
			
		||||
                    xMaxSize = pxBlock->xBlockSize;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Heap five will have a zero sized block at the end of each
 | 
			
		||||
                 * each region - the block is only used to link to the next
 | 
			
		||||
                 * heap region so it not a real block. */
 | 
			
		||||
                if( pxBlock->xBlockSize != 0 )
 | 
			
		||||
                {
 | 
			
		||||
                    if( pxBlock->xBlockSize < xMinSize )
 | 
			
		||||
                    {
 | 
			
		||||
                        xMinSize = pxBlock->xBlockSize;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* Move to the next block in the chain until the last block is
 | 
			
		||||
                 * reached. */
 | 
			
		||||
                pxBlock = heapPROTECT_BLOCK_POINTER( pxBlock->pxNextFreeBlock );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize;
 | 
			
		||||
    pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize;
 | 
			
		||||
    pxHeapStats->xNumberOfFreeBlocks = xBlocks;
 | 
			
		||||
 | 
			
		||||
    taskENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining;
 | 
			
		||||
        pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations;
 | 
			
		||||
        pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees;
 | 
			
		||||
        pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining;
 | 
			
		||||
    }
 | 
			
		||||
    taskEXIT_CRITICAL();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    pxEnd = NULL;
 | 
			
		||||
 | 
			
		||||
    xFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
    xMinimumEverFreeBytesRemaining = ( size_t ) 0U;
 | 
			
		||||
    xNumberOfSuccessfulAllocations = ( size_t ) 0U;
 | 
			
		||||
    xNumberOfSuccessfulFrees = ( size_t ) 0U;
 | 
			
		||||
 | 
			
		||||
    #if ( configENABLE_HEAP_PROTECTOR == 1 )
 | 
			
		||||
        pucHeapHighAddress = NULL;
 | 
			
		||||
        pucHeapLowAddress = NULL;
 | 
			
		||||
    #endif /* #if ( configENABLE_HEAP_PROTECTOR == 1 ) */
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										165
									
								
								heap_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								heap_1.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The simplest possible implementation of pvPortMalloc().  Note that this
 | 
			
		||||
 * implementation does NOT allow allocated memory to be freed again.
 | 
			
		||||
 *
 | 
			
		||||
 * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the
 | 
			
		||||
 * memory management pages of https://www.FreeRTOS.org for more information.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 )
 | 
			
		||||
    #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* A few bytes might be lost to byte aligning the heap start address. */
 | 
			
		||||
#define configADJUSTED_HEAP_SIZE    ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT )
 | 
			
		||||
 | 
			
		||||
/* Allocate the memory for the heap. */
 | 
			
		||||
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
 | 
			
		||||
 | 
			
		||||
/* The application writer has already defined the array used for the RTOS
 | 
			
		||||
* heap - probably so it can be placed in a special segment or address. */
 | 
			
		||||
    extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#else
 | 
			
		||||
    static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
 | 
			
		||||
#endif /* configAPPLICATION_ALLOCATED_HEAP */
 | 
			
		||||
 | 
			
		||||
/* Index into the ucHeap array. */
 | 
			
		||||
static size_t xNextFreeByte = ( size_t ) 0U;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize )
 | 
			
		||||
{
 | 
			
		||||
    void * pvReturn = NULL;
 | 
			
		||||
    static uint8_t * pucAlignedHeap = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Ensure that blocks are always aligned. */
 | 
			
		||||
    #if ( portBYTE_ALIGNMENT != 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( xWantedSize & portBYTE_ALIGNMENT_MASK )
 | 
			
		||||
        {
 | 
			
		||||
            /* Byte alignment required. Check for overflow. */
 | 
			
		||||
            if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) > xWantedSize )
 | 
			
		||||
            {
 | 
			
		||||
                xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                xWantedSize = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif /* if ( portBYTE_ALIGNMENT != 1 ) */
 | 
			
		||||
 | 
			
		||||
    vTaskSuspendAll();
 | 
			
		||||
    {
 | 
			
		||||
        if( pucAlignedHeap == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            /* Ensure the heap starts on a correctly aligned boundary. */
 | 
			
		||||
            pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Check there is enough room left for the allocation and. */
 | 
			
		||||
        if( ( xWantedSize > 0 ) &&                                /* valid size */
 | 
			
		||||
            ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
 | 
			
		||||
            ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */
 | 
			
		||||
        {
 | 
			
		||||
            /* Return the next free byte then increment the index past this
 | 
			
		||||
             * block. */
 | 
			
		||||
            pvReturn = pucAlignedHeap + xNextFreeByte;
 | 
			
		||||
            xNextFreeByte += xWantedSize;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        traceMALLOC( pvReturn, xWantedSize );
 | 
			
		||||
    }
 | 
			
		||||
    ( void ) xTaskResumeAll();
 | 
			
		||||
 | 
			
		||||
    #if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
    {
 | 
			
		||||
        if( pvReturn == NULL )
 | 
			
		||||
        {
 | 
			
		||||
            vApplicationMallocFailedHook();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    return pvReturn;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortFree( void * pv )
 | 
			
		||||
{
 | 
			
		||||
    /* Memory cannot be freed using this scheme.  See heap_2.c, heap_3.c and
 | 
			
		||||
     * heap_4.c for alternative implementations, and the memory management pages of
 | 
			
		||||
     * https://www.FreeRTOS.org for more information. */
 | 
			
		||||
    ( void ) pv;
 | 
			
		||||
 | 
			
		||||
    /* Force an assert as it is invalid to call this function. */
 | 
			
		||||
    configASSERT( pv == NULL );
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vPortInitialiseBlocks( void )
 | 
			
		||||
{
 | 
			
		||||
    /* Only required when static memory is not cleared. */
 | 
			
		||||
    xNextFreeByte = ( size_t ) 0;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
size_t xPortGetFreeHeapSize( void )
 | 
			
		||||
{
 | 
			
		||||
    return( configADJUSTED_HEAP_SIZE - xNextFreeByte );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Reset the state in this file. This state is normally initialized at start up.
 | 
			
		||||
 * This function must be called by the application before restarting the
 | 
			
		||||
 * scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void )
 | 
			
		||||
{
 | 
			
		||||
    xNextFreeByte = ( size_t ) 0U;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										3334
									
								
								include/FreeRTOS.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3334
									
								
								include/FreeRTOS.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										148
									
								
								include/FreeRTOSConfig.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								include/FreeRTOSConfig.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,148 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef FREERTOS_CONFIG_H
 | 
			
		||||
#define FREERTOS_CONFIG_H
 | 
			
		||||
 | 
			
		||||
#include <avr/io.h>
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
 * Application specific definitions.
 | 
			
		||||
 *
 | 
			
		||||
 * These definitions should be adjusted for your particular hardware and
 | 
			
		||||
 * application requirements.
 | 
			
		||||
 *
 | 
			
		||||
 * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
 | 
			
		||||
 * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
 | 
			
		||||
 *
 | 
			
		||||
 * See http://www.freertos.org/a00110.html.
 | 
			
		||||
 *----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#define configUSE_PREEMPTION                                            1
 | 
			
		||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION                         0
 | 
			
		||||
#define configUSE_TICKLESS_IDLE                                         0
 | 
			
		||||
#define configCPU_CLOCK_HZ                                              F_CPU
 | 
			
		||||
#define configTICK_RATE_HZ                                              1000
 | 
			
		||||
#define configMAX_PRIORITIES                                            4
 | 
			
		||||
#define configMINIMAL_STACK_SIZE                                        64
 | 
			
		||||
#define configMAX_TASK_NAME_LEN                                         16
 | 
			
		||||
#define configUSE_16_BIT_TICKS                                          1
 | 
			
		||||
#define configIDLE_SHOULD_YIELD                                         1
 | 
			
		||||
#define configUSE_TASK_NOTIFICATIONS                                    1
 | 
			
		||||
#define configTASK_NOTIFICATION_ARRAY_ENTRIES                           3
 | 
			
		||||
#define configUSE_MUTEXES                                               1
 | 
			
		||||
#define configUSE_RECURSIVE_MUTEXES                                     1 
 | 
			
		||||
#define configUSE_COUNTING_SEMAPHORES                                   1
 | 
			
		||||
#define configQUEUE_REGISTRY_SIZE                                       0
 | 
			
		||||
#define configUSE_QUEUE_SETS                                            0
 | 
			
		||||
#define configUSE_TIME_SLICING                                          1
 | 
			
		||||
#define configUSE_NEWLIB_REENTRANT                                      0
 | 
			
		||||
#define configENABLE_BACKWARD_COMPATIBILITY                             1
 | 
			
		||||
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS                         5
 | 
			
		||||
#define configUSE_MINI_LIST_ITEM                                        1
 | 
			
		||||
#define configSTACK_DEPTH_TYPE                                          uint16_t
 | 
			
		||||
#define configMESSAGE_BUFFER_LENGTH_TYPE                                size_t
 | 
			
		||||
#define configHEAP_CLEAR_MEMORY_ON_FREE                                 1
 | 
			
		||||
 | 
			
		||||
/* Memory allocation related definitions. */
 | 
			
		||||
#define configSUPPORT_STATIC_ALLOCATION                                 0
 | 
			
		||||
#define configSUPPORT_DYNAMIC_ALLOCATION                                1
 | 
			
		||||
#define configTOTAL_HEAP_SIZE                                           762
 | 
			
		||||
#define configAPPLICATION_ALLOCATED_HEAP                                0
 | 
			
		||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP                       0
 | 
			
		||||
 | 
			
		||||
/* Hook function related definitions. */
 | 
			
		||||
#define configUSE_IDLE_HOOK                                             0
 | 
			
		||||
#define configUSE_TICK_HOOK                                             0
 | 
			
		||||
#define configCHECK_FOR_STACK_OVERFLOW                                  0
 | 
			
		||||
#define configUSE_MALLOC_FAILED_HOOK                                    0
 | 
			
		||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK                              0
 | 
			
		||||
#define configUSE_SB_COMPLETED_CALLBACK                                 0
 | 
			
		||||
 | 
			
		||||
/* Run time and task stats gathering related definitions. */
 | 
			
		||||
#define configGENERATE_RUN_TIME_STATS                                   0
 | 
			
		||||
#define configUSE_TRACE_FACILITY                                        0
 | 
			
		||||
#define configUSE_STATS_FORMATTING_FUNCTIONS                            0
 | 
			
		||||
 | 
			
		||||
/* Co-routine related definitions. */
 | 
			
		||||
#define configUSE_CO_ROUTINES                                           0
 | 
			
		||||
#define configMAX_CO_ROUTINE_PRIORITIES                                 1
 | 
			
		||||
 | 
			
		||||
/* Software timer related definitions. */
 | 
			
		||||
#define configUSE_TIMERS                                                1
 | 
			
		||||
#define configTIMER_TASK_PRIORITY                                       configMAX_PRIORITIES - 1
 | 
			
		||||
#define configTIMER_QUEUE_LENGTH                                        10
 | 
			
		||||
#define configTIMER_TASK_STACK_DEPTH                                    configMINIMAL_STACK_SIZE
 | 
			
		||||
 | 
			
		||||
/* Set the following INCLUDE_* constants to 1 to incldue the named API function,
 | 
			
		||||
 * or 0 to exclude the named API function.  Most linkers will remove unused
 | 
			
		||||
 * functions even when the constant is 1. */
 | 
			
		||||
#define INCLUDE_vTaskPrioritySet                                        1
 | 
			
		||||
#define INCLUDE_uxTaskPriorityGet                                       1
 | 
			
		||||
#define INCLUDE_vTaskDelete                                             1
 | 
			
		||||
#define INCLUDE_vTaskSuspend                                            1
 | 
			
		||||
#define INCLUDE_xTaskResumeFromISR                                      1
 | 
			
		||||
#define INCLUDE_xTaskDelayUntil                                         1
 | 
			
		||||
#define INCLUDE_vTaskDelay                                              1
 | 
			
		||||
#define INCLUDE_xTaskGetSchedulerState                                  1
 | 
			
		||||
#define INCLUDE_xTaskGetCurrentTaskHandle                               1
 | 
			
		||||
#define INCLUDE_uxTaskGetStackHighWaterMark                             1
 | 
			
		||||
#define INCLUDE_xTaskGetIdleTaskHandle                                  1
 | 
			
		||||
#define INCLUDE_eTaskGetState                                           1
 | 
			
		||||
#define INCLUDE_xEventGroupSetBitFromISR                                1
 | 
			
		||||
#define INCLUDE_xTimerPendFunctionCall                                  1
 | 
			
		||||
#define INCLUDE_xTaskAbortDelay                                         1
 | 
			
		||||
#define INCLUDE_xTaskGetHandle                                          1
 | 
			
		||||
 | 
			
		||||
#define configMAX(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a > _b ? _a : _b; })
 | 
			
		||||
#define configMIN(a, b) ({ __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); _a < _b ? _a : _b; })
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * configASSERT macro: https://www.freertos.org/a00110.html#configASSERT
 | 
			
		||||
 */
 | 
			
		||||
#ifndef configASSERT
 | 
			
		||||
    #define configDEFAULT_ASSERT 0
 | 
			
		||||
#else
 | 
			
		||||
    /**
 | 
			
		||||
     * Enable configASSERT macro if it is defined.
 | 
			
		||||
     */
 | 
			
		||||
    #ifndef configDEFAULT_ASSERT
 | 
			
		||||
        #define configDEFAULT_ASSERT 1
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Define a hook method for configASSERT macro if configASSERT is enabled.
 | 
			
		||||
     */
 | 
			
		||||
    #if configDEFAULT_ASSERT == 1
 | 
			
		||||
        extern void vApplicationAssertHook();
 | 
			
		||||
        #define configASSERT( x ) if (( x ) == 0) { vApplicationAssertHook(); }
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* FREERTOS_CONFIG_H */
 | 
			
		||||
							
								
								
									
										427
									
								
								include/atomic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								include/atomic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,427 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file atomic.h
 | 
			
		||||
 * @brief FreeRTOS atomic operation support.
 | 
			
		||||
 *
 | 
			
		||||
 * This file implements atomic functions by disabling interrupts globally.
 | 
			
		||||
 * Implementations with architecture specific atomic instructions can be
 | 
			
		||||
 * provided under each compiler directory.
 | 
			
		||||
 *
 | 
			
		||||
 * The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It
 | 
			
		||||
 * can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that
 | 
			
		||||
 * support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The
 | 
			
		||||
 * atomic interface must not be used in ISRs on FreeRTOS ports that do not
 | 
			
		||||
 * support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
 | 
			
		||||
 * because ISRs on these ports cannot be interrupted and therefore, do not need
 | 
			
		||||
 * atomics in ISRs.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef ATOMIC_H
 | 
			
		||||
#define ATOMIC_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
    #error "include FreeRTOS.h must appear in source files before include atomic.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Standard includes. */
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Port specific definitions -- entering/exiting critical section.
 | 
			
		||||
 * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
 | 
			
		||||
 *
 | 
			
		||||
 * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
 | 
			
		||||
 * ATOMIC_ENTER_CRITICAL().
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#if ( portHAS_NESTED_INTERRUPTS == 1 )
 | 
			
		||||
 | 
			
		||||
/* Nested interrupt scheme is supported in this port. */
 | 
			
		||||
    #define ATOMIC_ENTER_CRITICAL() \
 | 
			
		||||
    UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
 | 
			
		||||
 | 
			
		||||
    #define ATOMIC_EXIT_CRITICAL() \
 | 
			
		||||
    portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
/* Nested interrupt scheme is NOT supported in this port. */
 | 
			
		||||
    #define ATOMIC_ENTER_CRITICAL()    portENTER_CRITICAL()
 | 
			
		||||
    #define ATOMIC_EXIT_CRITICAL()     portEXIT_CRITICAL()
 | 
			
		||||
 | 
			
		||||
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Port specific definition -- "always inline".
 | 
			
		||||
 * Inline is compiler specific, and may not always get inlined depending on your
 | 
			
		||||
 * optimization level.  Also, inline is considered as performance optimization
 | 
			
		||||
 * for atomic.  Thus, if portFORCE_INLINE is not provided by portmacro.h,
 | 
			
		||||
 * instead of resulting error, simply define it away.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef portFORCE_INLINE
 | 
			
		||||
    #define portFORCE_INLINE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define ATOMIC_COMPARE_AND_SWAP_SUCCESS    0x1U     /**< Compare and swap succeeded, swapped. */
 | 
			
		||||
#define ATOMIC_COMPARE_AND_SWAP_FAILURE    0x0U     /**< Compare and swap failed, did not swap. */
 | 
			
		||||
 | 
			
		||||
/*----------------------------- Swap && CAS ------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic compare-and-swap
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic compare-and-swap operation on the specified values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in, out] pulDestination  Pointer to memory location from where value is
 | 
			
		||||
 *                               to be loaded and checked.
 | 
			
		||||
 * @param[in] ulExchange         If condition meets, write this value to memory.
 | 
			
		||||
 * @param[in] ulComparand        Swap condition.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function only swaps *pulDestination with ulExchange, if previous
 | 
			
		||||
 *       *pulDestination value equals ulComparand.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32( uint32_t volatile * pulDestination,
 | 
			
		||||
                                                            uint32_t ulExchange,
 | 
			
		||||
                                                            uint32_t ulComparand )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulReturnValue;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        if( *pulDestination == ulComparand )
 | 
			
		||||
        {
 | 
			
		||||
            *pulDestination = ulExchange;
 | 
			
		||||
            ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulReturnValue;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic swap (pointers)
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Atomically sets the address pointed to by *ppvDestination to the value
 | 
			
		||||
 *        of *pvExchange.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in, out] ppvDestination  Pointer to memory location from where a pointer
 | 
			
		||||
 *                                 value is to be loaded and written back to.
 | 
			
		||||
 * @param[in] pvExchange           Pointer value to be written to *ppvDestination.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The initial value of *ppvDestination.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE void * Atomic_SwapPointers_p32( void * volatile * ppvDestination,
 | 
			
		||||
                                                        void * pvExchange )
 | 
			
		||||
{
 | 
			
		||||
    void * pReturnValue;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        pReturnValue = *ppvDestination;
 | 
			
		||||
        *ppvDestination = pvExchange;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return pReturnValue;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic compare-and-swap (pointers)
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic compare-and-swap operation on the specified pointer
 | 
			
		||||
 *        values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in, out] ppvDestination  Pointer to memory location from where a pointer
 | 
			
		||||
 *                                 value is to be loaded and checked.
 | 
			
		||||
 * @param[in] pvExchange           If condition meets, write this value to memory.
 | 
			
		||||
 * @param[in] pvComparand          Swap condition.
 | 
			
		||||
 *
 | 
			
		||||
 * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
 | 
			
		||||
 *
 | 
			
		||||
 * @note This function only swaps *ppvDestination with pvExchange, if previous
 | 
			
		||||
 *       *ppvDestination value equals pvComparand.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32( void * volatile * ppvDestination,
 | 
			
		||||
                                                                    void * pvExchange,
 | 
			
		||||
                                                                    void * pvComparand )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        if( *ppvDestination == pvComparand )
 | 
			
		||||
        {
 | 
			
		||||
            *ppvDestination = pvExchange;
 | 
			
		||||
            ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulReturnValue;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*----------------------------- Arithmetic ------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic add
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Atomically adds count to the value of the specified pointer points to.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 | 
			
		||||
 *                         loaded and written back to.
 | 
			
		||||
 * @param[in] ulCount      Value to be added to *pulAddend.
 | 
			
		||||
 *
 | 
			
		||||
 * @return previous *pulAddend value.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_Add_u32( uint32_t volatile * pulAddend,
 | 
			
		||||
                                                 uint32_t ulCount )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulAddend;
 | 
			
		||||
        *pulAddend += ulCount;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic subtract
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Atomically subtracts count from the value of the specified pointer
 | 
			
		||||
 *        pointers to.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 | 
			
		||||
 *                         loaded and written back to.
 | 
			
		||||
 * @param[in] ulCount      Value to be subtract from *pulAddend.
 | 
			
		||||
 *
 | 
			
		||||
 * @return previous *pulAddend value.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_Subtract_u32( uint32_t volatile * pulAddend,
 | 
			
		||||
                                                      uint32_t ulCount )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulAddend;
 | 
			
		||||
        *pulAddend -= ulCount;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic increment
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Atomically increments the value of the specified pointer points to.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 | 
			
		||||
 *                         loaded and written back to.
 | 
			
		||||
 *
 | 
			
		||||
 * @return *pulAddend value before increment.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pulAddend )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulAddend;
 | 
			
		||||
        *pulAddend += 1;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic decrement
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Atomically decrements the value of the specified pointer points to
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in,out] pulAddend  Pointer to memory location from where value is to be
 | 
			
		||||
 *                         loaded and written back to.
 | 
			
		||||
 *
 | 
			
		||||
 * @return *pulAddend value before decrement.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pulAddend )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulAddend;
 | 
			
		||||
        *pulAddend -= 1;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*----------------------------- Bitwise Logical ------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic OR
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic OR operation on the specified values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 | 
			
		||||
 *                                to be loaded and written back to.
 | 
			
		||||
 * @param [in] ulValue            Value to be ORed with *pulDestination.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The original value of *pulDestination.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_OR_u32( uint32_t volatile * pulDestination,
 | 
			
		||||
                                                uint32_t ulValue )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulDestination;
 | 
			
		||||
        *pulDestination |= ulValue;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic AND
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic AND operation on the specified values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 | 
			
		||||
 *                                to be loaded and written back to.
 | 
			
		||||
 * @param [in] ulValue            Value to be ANDed with *pulDestination.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The original value of *pulDestination.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_AND_u32( uint32_t volatile * pulDestination,
 | 
			
		||||
                                                 uint32_t ulValue )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulDestination;
 | 
			
		||||
        *pulDestination &= ulValue;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic NAND
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic NAND operation on the specified values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 | 
			
		||||
 *                                to be loaded and written back to.
 | 
			
		||||
 * @param [in] ulValue            Value to be NANDed with *pulDestination.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The original value of *pulDestination.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_NAND_u32( uint32_t volatile * pulDestination,
 | 
			
		||||
                                                  uint32_t ulValue )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulDestination;
 | 
			
		||||
        *pulDestination = ~( ulCurrent & ulValue );
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Atomic XOR
 | 
			
		||||
 *
 | 
			
		||||
 * @brief Performs an atomic XOR operation on the specified values.
 | 
			
		||||
 *
 | 
			
		||||
 * @param [in, out] pulDestination  Pointer to memory location from where value is
 | 
			
		||||
 *                                to be loaded and written back to.
 | 
			
		||||
 * @param [in] ulValue            Value to be XORed with *pulDestination.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The original value of *pulDestination.
 | 
			
		||||
 */
 | 
			
		||||
static portFORCE_INLINE uint32_t Atomic_XOR_u32( uint32_t volatile * pulDestination,
 | 
			
		||||
                                                 uint32_t ulValue )
 | 
			
		||||
{
 | 
			
		||||
    uint32_t ulCurrent;
 | 
			
		||||
 | 
			
		||||
    ATOMIC_ENTER_CRITICAL();
 | 
			
		||||
    {
 | 
			
		||||
        ulCurrent = *pulDestination;
 | 
			
		||||
        *pulDestination ^= ulValue;
 | 
			
		||||
    }
 | 
			
		||||
    ATOMIC_EXIT_CRITICAL();
 | 
			
		||||
 | 
			
		||||
    return ulCurrent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* ATOMIC_H */
 | 
			
		||||
							
								
								
									
										762
									
								
								include/croutine.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										762
									
								
								include/croutine.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,762 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef CO_ROUTINE_H
 | 
			
		||||
#define CO_ROUTINE_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
    #error "include FreeRTOS.h must appear in source files before include croutine.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "list.h"
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
/* Used to hide the implementation of the co-routine control block.  The
 | 
			
		||||
 * control block structure however has to be included in the header due to
 | 
			
		||||
 * the macro implementation of the co-routine functionality. */
 | 
			
		||||
typedef void * CoRoutineHandle_t;
 | 
			
		||||
 | 
			
		||||
/* Defines the prototype to which co-routine functions must conform. */
 | 
			
		||||
typedef void (* crCOROUTINE_CODE)( CoRoutineHandle_t xHandle,
 | 
			
		||||
                                   UBaseType_t uxIndex );
 | 
			
		||||
 | 
			
		||||
typedef struct corCoRoutineControlBlock
 | 
			
		||||
{
 | 
			
		||||
    crCOROUTINE_CODE pxCoRoutineFunction;
 | 
			
		||||
    ListItem_t xGenericListItem; /**< List item used to place the CRCB in ready and blocked queues. */
 | 
			
		||||
    ListItem_t xEventListItem;   /**< List item used to place the CRCB in event lists. */
 | 
			
		||||
    UBaseType_t uxPriority;      /**< The priority of the co-routine in relation to other co-routines. */
 | 
			
		||||
    UBaseType_t uxIndex;         /**< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */
 | 
			
		||||
    uint16_t uxState;            /**< Used internally by the co-routine implementation. */
 | 
			
		||||
} CRCB_t;                        /* Co-routine control block.  Note must be identical in size down to uxPriority with TCB_t. */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xCoRoutineCreate(
 | 
			
		||||
 *                               crCOROUTINE_CODE pxCoRoutineCode,
 | 
			
		||||
 *                               UBaseType_t uxPriority,
 | 
			
		||||
 *                               UBaseType_t uxIndex
 | 
			
		||||
 *                             );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new co-routine and add it to the list of co-routines that are
 | 
			
		||||
 * ready to run.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxCoRoutineCode Pointer to the co-routine function.  Co-routine
 | 
			
		||||
 * functions require special syntax - see the co-routine section of the WEB
 | 
			
		||||
 * documentation for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxPriority The priority with respect to other co-routines at which
 | 
			
		||||
 *  the co-routine will run.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxIndex Used to distinguish between different co-routines that
 | 
			
		||||
 * execute the same function.  See the example below and the co-routine section
 | 
			
		||||
 * of the WEB documentation for further information.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdPASS if the co-routine was successfully created and added to a ready
 | 
			
		||||
 * list, otherwise an error code defined with ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Co-routine to be created.
 | 
			
		||||
 * void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * // This may not be necessary for const variables.
 | 
			
		||||
 * static const char cLedToFlash[ 2 ] = { 5, 6 };
 | 
			
		||||
 * static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must start every co-routine with a call to crSTART();
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       // This co-routine just delays for a fixed period, then toggles
 | 
			
		||||
 *       // an LED.  Two co-routines are created using this function, so
 | 
			
		||||
 *       // the uxIndex parameter is used to tell the co-routine which
 | 
			
		||||
 *       // LED to flash and how int32_t to delay.  This assumes xQueue has
 | 
			
		||||
 *       // already been created.
 | 
			
		||||
 *       vParTestToggleLED( cLedToFlash[ uxIndex ] );
 | 
			
		||||
 *       crDELAY( xHandle, uxFlashRates[ uxIndex ] );
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must end every co-routine with a call to crEND();
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * // Function that creates two co-routines.
 | 
			
		||||
 * void vOtherFunction( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * uint8_t ucParameterToPass;
 | 
			
		||||
 * TaskHandle_t xHandle;
 | 
			
		||||
 *
 | 
			
		||||
 *   // Create two co-routines at priority 0.  The first is given index 0
 | 
			
		||||
 *   // so (from the code above) toggles LED 5 every 200 ticks.  The second
 | 
			
		||||
 *   // is given index 1 so toggles LED 6 every 400 ticks.
 | 
			
		||||
 *   for( uxIndex = 0; uxIndex < 2; uxIndex++ )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xCoRoutineCreate xCoRoutineCreate
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode,
 | 
			
		||||
                             UBaseType_t uxPriority,
 | 
			
		||||
                             UBaseType_t uxIndex );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * void vCoRoutineSchedule( void );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Run a co-routine.
 | 
			
		||||
 *
 | 
			
		||||
 * vCoRoutineSchedule() executes the highest priority co-routine that is able
 | 
			
		||||
 * to run.  The co-routine will execute until it either blocks, yields or is
 | 
			
		||||
 * preempted by a task.  Co-routines execute cooperatively so one
 | 
			
		||||
 * co-routine cannot be preempted by another, but can be preempted by a task.
 | 
			
		||||
 *
 | 
			
		||||
 * If an application comprises of both tasks and co-routines then
 | 
			
		||||
 * vCoRoutineSchedule should be called from the idle task (in an idle task
 | 
			
		||||
 * hook).
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // This idle task hook will schedule a co-routine each time it is called.
 | 
			
		||||
 * // The rest of the idle task will execute between co-routine calls.
 | 
			
		||||
 * void vApplicationIdleHook( void )
 | 
			
		||||
 * {
 | 
			
		||||
 *  vCoRoutineSchedule();
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * // Alternatively, if you do not require any other part of the idle task to
 | 
			
		||||
 * // execute, the idle task hook can call vCoRoutineSchedule() within an
 | 
			
		||||
 * // infinite loop.
 | 
			
		||||
 * void vApplicationIdleHook( void )
 | 
			
		||||
 * {
 | 
			
		||||
 *  for( ;; )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      vCoRoutineSchedule();
 | 
			
		||||
 *  }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup vCoRoutineSchedule vCoRoutineSchedule
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
void vCoRoutineSchedule( void );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crSTART( CoRoutineHandle_t xHandle );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * This macro MUST always be called at the start of a co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Co-routine to be created.
 | 
			
		||||
 * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * static int32_t ulAVariable;
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must start every co-routine with a call to crSTART();
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *        // Co-routine functionality goes here.
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must end every co-routine with a call to crEND();
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crSTART crSTART
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crSTART( pxCRCB )                            \
 | 
			
		||||
    switch( ( ( CRCB_t * ) ( pxCRCB ) )->uxState ) { \
 | 
			
		||||
        case 0:
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crEND();
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * This macro MUST always be called at the end of a co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Co-routine to be created.
 | 
			
		||||
 * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * static int32_t ulAVariable;
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must start every co-routine with a call to crSTART();
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *        // Co-routine functionality goes here.
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must end every co-routine with a call to crEND();
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crSTART crSTART
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crEND()    }
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These macros are intended for internal use by the co-routine implementation
 | 
			
		||||
 * only.  The macros should not be used directly by application writers.
 | 
			
		||||
 */
 | 
			
		||||
#define crSET_STATE0( xHandle )                                       \
 | 
			
		||||
    ( ( CRCB_t * ) ( xHandle ) )->uxState = ( __LINE__ * 2 ); return; \
 | 
			
		||||
    case ( __LINE__ * 2 ):
 | 
			
		||||
#define crSET_STATE1( xHandle )                                               \
 | 
			
		||||
    ( ( CRCB_t * ) ( xHandle ) )->uxState = ( ( __LINE__ * 2 ) + 1 ); return; \
 | 
			
		||||
    case ( ( __LINE__ * 2 ) + 1 ):
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Delay a co-routine for a fixed period of time.
 | 
			
		||||
 *
 | 
			
		||||
 * crDELAY can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the co-routine to delay.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should delay
 | 
			
		||||
 * for.  The actual amount of time this equates to is defined by
 | 
			
		||||
 * configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant portTICK_PERIOD_MS
 | 
			
		||||
 * can be used to convert ticks to milliseconds.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Co-routine to be created.
 | 
			
		||||
 * void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * // This may not be necessary for const variables.
 | 
			
		||||
 * // We are to delay for 200ms.
 | 
			
		||||
 * static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must start every co-routine with a call to crSTART();
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *      // Delay for 200ms.
 | 
			
		||||
 *      crDELAY( xHandle, xDelayTime );
 | 
			
		||||
 *
 | 
			
		||||
 *      // Do something here.
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // Must end every co-routine with a call to crEND();
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crDELAY crDELAY
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crDELAY( xHandle, xTicksToDelay )                          \
 | 
			
		||||
    do {                                                           \
 | 
			
		||||
        if( ( xTicksToDelay ) > 0 )                                \
 | 
			
		||||
        {                                                          \
 | 
			
		||||
            vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \
 | 
			
		||||
        }                                                          \
 | 
			
		||||
        crSET_STATE0( ( xHandle ) );                               \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crQUEUE_SEND(
 | 
			
		||||
 *                CoRoutineHandle_t xHandle,
 | 
			
		||||
 *                QueueHandle_t pxQueue,
 | 
			
		||||
 *                void *pvItemToQueue,
 | 
			
		||||
 *                TickType_t xTicksToWait,
 | 
			
		||||
 *                BaseType_t *pxResult
 | 
			
		||||
 *           )
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
 | 
			
		||||
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
 | 
			
		||||
 * xQueueSend() and xQueueReceive() can only be used from tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxQueue The handle of the queue on which the data will be posted.
 | 
			
		||||
 * The handle is obtained as the return value when the queue is created using
 | 
			
		||||
 * the xQueueCreate() API function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvItemToQueue A pointer to the data being posted onto the queue.
 | 
			
		||||
 * The number of bytes of each queued item is specified when the queue is
 | 
			
		||||
 * created.  This number of bytes is copied from pvItemToQueue into the queue
 | 
			
		||||
 * itself.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should block
 | 
			
		||||
 * to wait for space to become available on the queue, should space not be
 | 
			
		||||
 * available immediately. The actual amount of time this equates to is defined
 | 
			
		||||
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
 | 
			
		||||
 * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example
 | 
			
		||||
 * below).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
 | 
			
		||||
 * data was successfully posted onto the queue, otherwise it will be set to an
 | 
			
		||||
 * error defined within ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Co-routine function that blocks for a fixed period then posts a number onto
 | 
			
		||||
 * // a queue.
 | 
			
		||||
 * static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * static BaseType_t xNumberToPost = 0;
 | 
			
		||||
 * static BaseType_t xResult;
 | 
			
		||||
 *
 | 
			
		||||
 *  // Co-routines must begin with a call to crSTART().
 | 
			
		||||
 *  crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *  for( ;; )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // This assumes the queue has already been created.
 | 
			
		||||
 *      crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
 | 
			
		||||
 *
 | 
			
		||||
 *      if( xResult != pdPASS )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // The message was not posted!
 | 
			
		||||
 *      }
 | 
			
		||||
 *
 | 
			
		||||
 *      // Increment the number to be posted onto the queue.
 | 
			
		||||
 *      xNumberToPost++;
 | 
			
		||||
 *
 | 
			
		||||
 *      // Delay for 100 ticks.
 | 
			
		||||
 *      crDELAY( xHandle, 100 );
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 *  // Co-routines must end with a call to crEND().
 | 
			
		||||
 *  crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crQUEUE_SEND crQUEUE_SEND
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult )           \
 | 
			
		||||
    do {                                                                                  \
 | 
			
		||||
        *( pxResult ) = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), ( xTicksToWait ) ); \
 | 
			
		||||
        if( *( pxResult ) == errQUEUE_BLOCKED )                                           \
 | 
			
		||||
        {                                                                                 \
 | 
			
		||||
            crSET_STATE0( ( xHandle ) );                                                  \
 | 
			
		||||
            *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 );                \
 | 
			
		||||
        }                                                                                 \
 | 
			
		||||
        if( *pxResult == errQUEUE_YIELD )                                                 \
 | 
			
		||||
        {                                                                                 \
 | 
			
		||||
            crSET_STATE1( ( xHandle ) );                                                  \
 | 
			
		||||
            *pxResult = pdPASS;                                                           \
 | 
			
		||||
        }                                                                                 \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crQUEUE_RECEIVE(
 | 
			
		||||
 *                   CoRoutineHandle_t xHandle,
 | 
			
		||||
 *                   QueueHandle_t pxQueue,
 | 
			
		||||
 *                   void *pvBuffer,
 | 
			
		||||
 *                   TickType_t xTicksToWait,
 | 
			
		||||
 *                   BaseType_t *pxResult
 | 
			
		||||
 *               )
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine
 | 
			
		||||
 * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas
 | 
			
		||||
 * xQueueSend() and xQueueReceive() can only be used from tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_RECEIVE can only be called from the co-routine function itself - not
 | 
			
		||||
 * from within a function called by the co-routine function.  This is because
 | 
			
		||||
 * co-routines do not maintain their own stack.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xHandle The handle of the calling co-routine.  This is the xHandle
 | 
			
		||||
 * parameter of the co-routine function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxQueue The handle of the queue from which the data will be received.
 | 
			
		||||
 * The handle is obtained as the return value when the queue is created using
 | 
			
		||||
 * the xQueueCreate() API function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvBuffer The buffer into which the received item is to be copied.
 | 
			
		||||
 * The number of bytes of each queued item is specified when the queue is
 | 
			
		||||
 * created.  This number of bytes is copied into pvBuffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTickToDelay The number of ticks that the co-routine should block
 | 
			
		||||
 * to wait for data to become available from the queue, should data not be
 | 
			
		||||
 * available immediately. The actual amount of time this equates to is defined
 | 
			
		||||
 * by configTICK_RATE_HZ (set in FreeRTOSConfig.h).  The constant
 | 
			
		||||
 * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the
 | 
			
		||||
 * crQUEUE_SEND example).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxResult The variable pointed to by pxResult will be set to pdPASS if
 | 
			
		||||
 * data was successfully retrieved from the queue, otherwise it will be set to
 | 
			
		||||
 * an error code as defined within ProjDefs.h.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // A co-routine receives the number of an LED to flash from a queue.  It
 | 
			
		||||
 * // blocks on the queue until the number is received.
 | 
			
		||||
 * static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // Variables in co-routines must be declared static if they must maintain value across a blocking call.
 | 
			
		||||
 * static BaseType_t xResult;
 | 
			
		||||
 * static UBaseType_t uxLEDToFlash;
 | 
			
		||||
 *
 | 
			
		||||
 *  // All co-routines must start with a call to crSTART().
 | 
			
		||||
 *  crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *  for( ;; )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // Wait for data to become available on the queue.
 | 
			
		||||
 *      crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
 | 
			
		||||
 *
 | 
			
		||||
 *      if( xResult == pdPASS )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // We received the LED to flash - flash it!
 | 
			
		||||
 *          vParTestToggleLED( uxLEDToFlash );
 | 
			
		||||
 *      }
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 *  crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult )           \
 | 
			
		||||
    do {                                                                                \
 | 
			
		||||
        *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), ( xTicksToWait ) ); \
 | 
			
		||||
        if( *( pxResult ) == errQUEUE_BLOCKED )                                         \
 | 
			
		||||
        {                                                                               \
 | 
			
		||||
            crSET_STATE0( ( xHandle ) );                                                \
 | 
			
		||||
            *( pxResult ) = xQueueCRReceive( ( pxQueue ), ( pvBuffer ), 0 );            \
 | 
			
		||||
        }                                                                               \
 | 
			
		||||
        if( *( pxResult ) == errQUEUE_YIELD )                                           \
 | 
			
		||||
        {                                                                               \
 | 
			
		||||
            crSET_STATE1( ( xHandle ) );                                                \
 | 
			
		||||
            *( pxResult ) = pdPASS;                                                     \
 | 
			
		||||
        }                                                                               \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR(
 | 
			
		||||
 *                          QueueHandle_t pxQueue,
 | 
			
		||||
 *                          void *pvItemToQueue,
 | 
			
		||||
 *                          BaseType_t xCoRoutinePreviouslyWoken
 | 
			
		||||
 *                     )
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
 | 
			
		||||
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
 | 
			
		||||
 * functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
 | 
			
		||||
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
 | 
			
		||||
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
 | 
			
		||||
 * ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue
 | 
			
		||||
 * that is being used from within a co-routine.
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xQueue The handle to the queue on which the item is to be posted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvItemToQueue A pointer to the item that is to be placed on the
 | 
			
		||||
 * queue.  The size of the items the queue will hold was defined when the
 | 
			
		||||
 * queue was created, so this many bytes will be copied from pvItemToQueue
 | 
			
		||||
 * into the queue storage area.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto
 | 
			
		||||
 * the same queue multiple times from a single interrupt.  The first call
 | 
			
		||||
 * should always pass in pdFALSE.  Subsequent calls should pass in
 | 
			
		||||
 * the value returned from the previous call.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if a co-routine was woken by posting onto the queue.  This is
 | 
			
		||||
 * used by the ISR to determine if a context switch may be required following
 | 
			
		||||
 * the ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // A co-routine that blocks on a queue waiting for characters to be received.
 | 
			
		||||
 * static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * char cRxedChar;
 | 
			
		||||
 * BaseType_t xResult;
 | 
			
		||||
 *
 | 
			
		||||
 *   // All co-routines must start with a call to crSTART().
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       // Wait for data to become available on the queue.  This assumes the
 | 
			
		||||
 *       // queue xCommsRxQueue has already been created!
 | 
			
		||||
 *       crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
 | 
			
		||||
 *
 | 
			
		||||
 *       // Was a character received?
 | 
			
		||||
 *       if( xResult == pdPASS )
 | 
			
		||||
 *       {
 | 
			
		||||
 *           // Process the character here.
 | 
			
		||||
 *       }
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // All co-routines must end with a call to crEND().
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * // An ISR that uses a queue to send characters received on a serial port to
 | 
			
		||||
 * // a co-routine.
 | 
			
		||||
 * void vUART_ISR( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * char cRxedChar;
 | 
			
		||||
 * BaseType_t xCRWokenByPost = pdFALSE;
 | 
			
		||||
 *
 | 
			
		||||
 *   // We loop around reading characters until there are none left in the UART.
 | 
			
		||||
 *   while( UART_RX_REG_NOT_EMPTY() )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       // Obtain the character from the UART.
 | 
			
		||||
 *       cRxedChar = UART_RX_REG;
 | 
			
		||||
 *
 | 
			
		||||
 *       // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
 | 
			
		||||
 *       // the first time around the loop.  If the post causes a co-routine
 | 
			
		||||
 *       // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
 | 
			
		||||
 *       // In this manner we can ensure that if more than one co-routine is
 | 
			
		||||
 *       // blocked on the queue only one is woken by this ISR no matter how
 | 
			
		||||
 *       // many characters are posted to the queue.
 | 
			
		||||
 *       xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) \
 | 
			
		||||
    xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * croutine. h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR(
 | 
			
		||||
 *                          QueueHandle_t pxQueue,
 | 
			
		||||
 *                          void *pvBuffer,
 | 
			
		||||
 *                          BaseType_t * pxCoRoutineWoken
 | 
			
		||||
 *                     )
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the
 | 
			
		||||
 * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR()
 | 
			
		||||
 * functions used by tasks.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to
 | 
			
		||||
 * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and
 | 
			
		||||
 * xQueueReceiveFromISR() can only be used to pass data between a task and and
 | 
			
		||||
 * ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data
 | 
			
		||||
 * from a queue that is being used from within a co-routine (a co-routine
 | 
			
		||||
 * posted to the queue).
 | 
			
		||||
 *
 | 
			
		||||
 * See the co-routine section of the WEB documentation for information on
 | 
			
		||||
 * passing data between tasks and co-routines and between ISR's and
 | 
			
		||||
 * co-routines.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xQueue The handle to the queue on which the item is to be posted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvBuffer A pointer to a buffer into which the received item will be
 | 
			
		||||
 * placed.  The size of the items the queue will hold was defined when the
 | 
			
		||||
 * queue was created, so this many bytes will be copied from the queue into
 | 
			
		||||
 * pvBuffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become
 | 
			
		||||
 * available on the queue.  If crQUEUE_RECEIVE_FROM_ISR causes such a
 | 
			
		||||
 * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise
 | 
			
		||||
 * *pxCoRoutineWoken will remain unchanged.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE an item was successfully received from the queue, otherwise
 | 
			
		||||
 * pdFALSE.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // A co-routine that posts a character to a queue then blocks for a fixed
 | 
			
		||||
 * // period.  The character is incremented each time.
 | 
			
		||||
 * static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
 | 
			
		||||
 * {
 | 
			
		||||
 * // cChar holds its value while this co-routine is blocked and must therefore
 | 
			
		||||
 * // be declared static.
 | 
			
		||||
 * static char cCharToTx = 'a';
 | 
			
		||||
 * BaseType_t xResult;
 | 
			
		||||
 *
 | 
			
		||||
 *   // All co-routines must start with a call to crSTART().
 | 
			
		||||
 *   crSTART( xHandle );
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       // Send the next character to the queue.
 | 
			
		||||
 *       crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
 | 
			
		||||
 *
 | 
			
		||||
 *       if( xResult == pdPASS )
 | 
			
		||||
 *       {
 | 
			
		||||
 *           // The character was successfully posted to the queue.
 | 
			
		||||
 *       }
 | 
			
		||||
 *       else
 | 
			
		||||
 *       {
 | 
			
		||||
 *          // Could not post the character to the queue.
 | 
			
		||||
 *       }
 | 
			
		||||
 *
 | 
			
		||||
 *       // Enable the UART Tx interrupt to cause an interrupt in this
 | 
			
		||||
 *       // hypothetical UART.  The interrupt will obtain the character
 | 
			
		||||
 *       // from the queue and send it.
 | 
			
		||||
 *       ENABLE_RX_INTERRUPT();
 | 
			
		||||
 *
 | 
			
		||||
 *       // Increment to the next character then block for a fixed period.
 | 
			
		||||
 *       // cCharToTx will maintain its value across the delay as it is
 | 
			
		||||
 *       // declared static.
 | 
			
		||||
 *       cCharToTx++;
 | 
			
		||||
 *       if( cCharToTx > 'x' )
 | 
			
		||||
 *       {
 | 
			
		||||
 *          cCharToTx = 'a';
 | 
			
		||||
 *       }
 | 
			
		||||
 *       crDELAY( 100 );
 | 
			
		||||
 *   }
 | 
			
		||||
 *
 | 
			
		||||
 *   // All co-routines must end with a call to crEND().
 | 
			
		||||
 *   crEND();
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * // An ISR that uses a queue to receive characters to send on a UART.
 | 
			
		||||
 * void vUART_ISR( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * char cCharToTx;
 | 
			
		||||
 * BaseType_t xCRWokenByPost = pdFALSE;
 | 
			
		||||
 *
 | 
			
		||||
 *   while( UART_TX_REG_EMPTY() )
 | 
			
		||||
 *   {
 | 
			
		||||
 *       // Are there any characters in the queue waiting to be sent?
 | 
			
		||||
 *       // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
 | 
			
		||||
 *       // is woken by the post - ensuring that only a single co-routine is
 | 
			
		||||
 *       // woken no matter how many times we go around this loop.
 | 
			
		||||
 *       if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
 | 
			
		||||
 *       {
 | 
			
		||||
 *           SEND_CHARACTER( cCharToTx );
 | 
			
		||||
 *       }
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR
 | 
			
		||||
 * \ingroup Tasks
 | 
			
		||||
 */
 | 
			
		||||
#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) \
 | 
			
		||||
    xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function is intended for internal use by the co-routine macros only.
 | 
			
		||||
 * The macro nature of the co-routine implementation requires that the
 | 
			
		||||
 * prototype appears here.  The function should not be used by application
 | 
			
		||||
 * writers.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the current co-routine from its ready list and places it in the
 | 
			
		||||
 * appropriate delayed list.
 | 
			
		||||
 */
 | 
			
		||||
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay,
 | 
			
		||||
                                 List_t * pxEventList );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function is intended for internal use by the queue implementation only.
 | 
			
		||||
 * The function should not be used by application writers.
 | 
			
		||||
 *
 | 
			
		||||
 * Removes the highest priority co-routine from the event list and places it in
 | 
			
		||||
 * the pending ready list.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xCoRoutineRemoveFromEventList( const List_t * pxEventList );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function resets the internal state of the coroutine module. It must be
 | 
			
		||||
 * called by the application before restarting the scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vCoRoutineResetState( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* CO_ROUTINE_H */
 | 
			
		||||
							
								
								
									
										281
									
								
								include/deprecated_definitions.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								include/deprecated_definitions.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef DEPRECATED_DEFINITIONS_H
 | 
			
		||||
#define DEPRECATED_DEFINITIONS_H
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Each FreeRTOS port has a unique portmacro.h header file.  Originally a
 | 
			
		||||
 * pre-processor definition was used to ensure the pre-processor found the correct
 | 
			
		||||
 * portmacro.h file for the port being used.  That scheme was deprecated in favour
 | 
			
		||||
 * of setting the compiler's include path such that it found the correct
 | 
			
		||||
 * portmacro.h file - removing the need for the constant and allowing the
 | 
			
		||||
 * portmacro.h file to be located anywhere in relation to the port being used.  The
 | 
			
		||||
 * definitions below remain in the code for backward compatibility only.  New
 | 
			
		||||
 * projects should not use them. */
 | 
			
		||||
 | 
			
		||||
#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT
 | 
			
		||||
    #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far * pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT
 | 
			
		||||
    #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far * pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MEGA_AVR
 | 
			
		||||
    #include "../portable/GCC/ATMega323/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_MEGA_AVR
 | 
			
		||||
    #include "../portable/IAR/ATMega323/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC24_PORT
 | 
			
		||||
    #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_DSPIC_PORT
 | 
			
		||||
    #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC18F_PORT
 | 
			
		||||
    #include "../../Source/portable/MPLAB/PIC18F/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MPLAB_PIC32MX_PORT
 | 
			
		||||
    #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _FEDPICC
 | 
			
		||||
    #include "libFreeRTOS/Include/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SDCC_CYGNAL
 | 
			
		||||
    #include "../../Source/portable/SDCC/Cygnal/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARM7
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARM7_ECLIPSE
 | 
			
		||||
    #include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ROWLEY_LPC23xx
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_MSP430
 | 
			
		||||
    #include "..\..\Source\portable\IAR\MSP430\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MSP430
 | 
			
		||||
    #include "../../Source/portable/GCC/MSP430F449/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ROWLEY_MSP430
 | 
			
		||||
    #include "../../Source/portable/Rowley/MSP430F449/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ARM7_LPC21xx_KEIL_RVDS
 | 
			
		||||
    #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM7_GCC
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM7_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SAM9XE_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LPC2000_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\LPC2000\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR71X_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\STR71x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR75X_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\STR75x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR75X_GCC
 | 
			
		||||
    #include "..\..\Source\portable\GCC\STR75x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef STR91X_IAR
 | 
			
		||||
    #include "..\..\Source\portable\IAR\STR91x\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_H8S
 | 
			
		||||
    #include "../../Source/portable/GCC/H8S2329/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_AT91FR40008
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RVDS_ARMCM3_LM3S102
 | 
			
		||||
    #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARMCM3_LM3S102
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_ARMCM3
 | 
			
		||||
    #include "../../Source/portable/GCC/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_ARM_CM3
 | 
			
		||||
    #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IAR_ARMCM3_LM
 | 
			
		||||
    #include "../../Source/portable/IAR/ARM_CM3/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HCS12_CODE_WARRIOR
 | 
			
		||||
    #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MICROBLAZE_GCC
 | 
			
		||||
    #include "../../Source/portable/GCC/MicroBlaze/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef TERN_EE
 | 
			
		||||
    #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_HCS12
 | 
			
		||||
    #include "../../Source/portable/GCC/HCS12/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_MCF5235
 | 
			
		||||
    #include "../../Source/portable/GCC/MCF5235/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef COLDFIRE_V2_GCC
 | 
			
		||||
    #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef COLDFIRE_V2_CODEWARRIOR
 | 
			
		||||
    #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_PPC405
 | 
			
		||||
    #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef GCC_PPC440
 | 
			
		||||
    #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef _16FX_SOFTUNE
 | 
			
		||||
    #include "..\..\Source\portable\Softune\MB96340\portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BCC_INDUSTRIAL_PC_PORT
 | 
			
		||||
 | 
			
		||||
/* A short file name has to be used in place of the normal
 | 
			
		||||
 * FreeRTOSConfig.h when using the Borland compiler. */
 | 
			
		||||
    #include "frconfig.h"
 | 
			
		||||
    #include "..\portable\BCC\16BitDOS\PC\prtmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far * pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BCC_FLASH_LITE_186_PORT
 | 
			
		||||
 | 
			
		||||
/* A short file name has to be used in place of the normal
 | 
			
		||||
 * FreeRTOSConfig.h when using the Borland compiler. */
 | 
			
		||||
    #include "frconfig.h"
 | 
			
		||||
    #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h"
 | 
			
		||||
    typedef void ( __interrupt __far * pxISR )();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
    #ifdef __AVR32_AVR32A__
 | 
			
		||||
        #include "portmacro.h"
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __ICCAVR32__
 | 
			
		||||
    #ifdef __CORE__
 | 
			
		||||
        #if __CORE__ == __AVR32A__
 | 
			
		||||
            #include "portmacro.h"
 | 
			
		||||
        #endif
 | 
			
		||||
    #endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __91467D
 | 
			
		||||
    #include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __96340
 | 
			
		||||
    #include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Fx3__
 | 
			
		||||
    #include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx3__
 | 
			
		||||
    #include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx3_L__
 | 
			
		||||
    #include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Jx2__
 | 
			
		||||
    #include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_V850ES_Hx2__
 | 
			
		||||
    #include "../../Source/portable/IAR/V850ES/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_78K0R_Kx3__
 | 
			
		||||
    #include "../../Source/portable/IAR/78K0R/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __IAR_78K0R_Kx3L__
 | 
			
		||||
    #include "../../Source/portable/IAR/78K0R/portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DEPRECATED_DEFINITIONS_H */
 | 
			
		||||
							
								
								
									
										857
									
								
								include/event_groups.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										857
									
								
								include/event_groups.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,857 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef EVENT_GROUPS_H
 | 
			
		||||
#define EVENT_GROUPS_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
    #error "include FreeRTOS.h" must appear in source files before "include event_groups.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* FreeRTOS includes. */
 | 
			
		||||
#include "timers.h"
 | 
			
		||||
 | 
			
		||||
/* The following bit fields convey control information in a task's event list
 | 
			
		||||
 * item value.  It is important they don't clash with the
 | 
			
		||||
 * taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */
 | 
			
		||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
 | 
			
		||||
    #define eventCLEAR_EVENTS_ON_EXIT_BIT    ( ( uint16_t ) 0x0100U )
 | 
			
		||||
    #define eventUNBLOCKED_DUE_TO_BIT_SET    ( ( uint16_t ) 0x0200U )
 | 
			
		||||
    #define eventWAIT_FOR_ALL_BITS           ( ( uint16_t ) 0x0400U )
 | 
			
		||||
    #define eventEVENT_BITS_CONTROL_BYTES    ( ( uint16_t ) 0xff00U )
 | 
			
		||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
 | 
			
		||||
    #define eventCLEAR_EVENTS_ON_EXIT_BIT    ( ( uint32_t ) 0x01000000U )
 | 
			
		||||
    #define eventUNBLOCKED_DUE_TO_BIT_SET    ( ( uint32_t ) 0x02000000U )
 | 
			
		||||
    #define eventWAIT_FOR_ALL_BITS           ( ( uint32_t ) 0x04000000U )
 | 
			
		||||
    #define eventEVENT_BITS_CONTROL_BYTES    ( ( uint32_t ) 0xff000000U )
 | 
			
		||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
 | 
			
		||||
    #define eventCLEAR_EVENTS_ON_EXIT_BIT    ( ( uint64_t ) 0x0100000000000000U )
 | 
			
		||||
    #define eventUNBLOCKED_DUE_TO_BIT_SET    ( ( uint64_t ) 0x0200000000000000U )
 | 
			
		||||
    #define eventWAIT_FOR_ALL_BITS           ( ( uint64_t ) 0x0400000000000000U )
 | 
			
		||||
    #define eventEVENT_BITS_CONTROL_BYTES    ( ( uint64_t ) 0xff00000000000000U )
 | 
			
		||||
#endif /* if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS ) */
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An event group is a collection of bits to which an application can assign a
 | 
			
		||||
 * meaning.  For example, an application may create an event group to convey
 | 
			
		||||
 * the status of various CAN bus related events in which bit 0 might mean "A CAN
 | 
			
		||||
 * message has been received and is ready for processing", bit 1 might mean "The
 | 
			
		||||
 * application has queued a message that is ready for sending onto the CAN
 | 
			
		||||
 * network", and bit 2 might mean "It is time to send a SYNC message onto the
 | 
			
		||||
 * CAN network" etc.  A task can then test the bit values to see which events
 | 
			
		||||
 * are active, and optionally enter the Blocked state to wait for a specified
 | 
			
		||||
 * bit or a group of specified bits to be active.  To continue the CAN bus
 | 
			
		||||
 * example, a CAN controlling task can enter the Blocked state (and therefore
 | 
			
		||||
 * not consume any processing time) until either bit 0, bit 1 or bit 2 are
 | 
			
		||||
 * active, at which time the bit that was actually active would inform the task
 | 
			
		||||
 * which action it had to take (process a received message, send a message, or
 | 
			
		||||
 * send a SYNC).
 | 
			
		||||
 *
 | 
			
		||||
 * The event groups implementation contains intelligence to avoid race
 | 
			
		||||
 * conditions that would otherwise occur were an application to use a simple
 | 
			
		||||
 * variable for the same purpose.  This is particularly important with respect
 | 
			
		||||
 * to when a bit within an event group is to be cleared, and when bits have to
 | 
			
		||||
 * be set and then tested atomically - as is the case where event groups are
 | 
			
		||||
 * used to create a synchronisation point between multiple tasks (a
 | 
			
		||||
 * 'rendezvous').
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 *
 | 
			
		||||
 * Type by which event groups are referenced.  For example, a call to
 | 
			
		||||
 * xEventGroupCreate() returns an EventGroupHandle_t variable that can then
 | 
			
		||||
 * be used as a parameter to other event group functions.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup EventGroupHandle_t EventGroupHandle_t
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
struct EventGroupDef_t;
 | 
			
		||||
typedef struct EventGroupDef_t   * EventGroupHandle_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The type that holds event bits always matches TickType_t - therefore the
 | 
			
		||||
 * number of bits it holds is set by configTICK_TYPE_WIDTH_IN_BITS (16 bits if set to 0,
 | 
			
		||||
 * 32 bits if set to 1, 64 bits if set to 2.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup EventBits_t EventBits_t
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
typedef TickType_t               EventBits_t;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * EventGroupHandle_t xEventGroupCreate( void );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new event group.
 | 
			
		||||
 *
 | 
			
		||||
 * Internally, within the FreeRTOS implementation, event groups use a [small]
 | 
			
		||||
 * block of memory, in which the event group's structure is stored.  If an event
 | 
			
		||||
 * groups is created using xEventGroupCreate() then the required memory is
 | 
			
		||||
 * automatically dynamically allocated inside the xEventGroupCreate() function.
 | 
			
		||||
 * (see https://www.FreeRTOS.org/a00111.html).  If an event group is created
 | 
			
		||||
 * using xEventGroupCreateStatic() then the application writer must instead
 | 
			
		||||
 * provide the memory that will get used by the event group.
 | 
			
		||||
 * xEventGroupCreateStatic() therefore allows an event group to be created
 | 
			
		||||
 * without using any dynamic memory allocation.
 | 
			
		||||
 *
 | 
			
		||||
 * Although event groups are not related to ticks, for internal implementation
 | 
			
		||||
 * reasons the number of bits available for use in an event group is dependent
 | 
			
		||||
 * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h.  If
 | 
			
		||||
 * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit
 | 
			
		||||
 * 0 to bit 7).  If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has
 | 
			
		||||
 * 24 usable bits (bit 0 to bit 23).  If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then
 | 
			
		||||
 * each event group has 56 usable bits (bit 0 to bit 53). The EventBits_t type
 | 
			
		||||
 * is used to store event bits within an event group.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupCreate()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the event group was created then a handle to the event group is
 | 
			
		||||
 * returned.  If there was insufficient FreeRTOS heap available to create the
 | 
			
		||||
 * event group then NULL is returned.  See https://www.FreeRTOS.org/a00111.html
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  // Declare a variable to hold the created event group.
 | 
			
		||||
 *  EventGroupHandle_t xCreatedEventGroup;
 | 
			
		||||
 *
 | 
			
		||||
 *  // Attempt to create the event group.
 | 
			
		||||
 *  xCreatedEventGroup = xEventGroupCreate();
 | 
			
		||||
 *
 | 
			
		||||
 *  // Was the event group created successfully?
 | 
			
		||||
 *  if( xCreatedEventGroup == NULL )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The event group was not created because there was insufficient
 | 
			
		||||
 *      // FreeRTOS heap available.
 | 
			
		||||
 *  }
 | 
			
		||||
 *  else
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The event group was created.
 | 
			
		||||
 *  }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupCreate xEventGroupCreate
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
 | 
			
		||||
    EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Create a new event group.
 | 
			
		||||
 *
 | 
			
		||||
 * Internally, within the FreeRTOS implementation, event groups use a [small]
 | 
			
		||||
 * block of memory, in which the event group's structure is stored.  If an event
 | 
			
		||||
 * groups is created using xEventGroupCreate() then the required memory is
 | 
			
		||||
 * automatically dynamically allocated inside the xEventGroupCreate() function.
 | 
			
		||||
 * (see https://www.FreeRTOS.org/a00111.html).  If an event group is created
 | 
			
		||||
 * using xEventGroupCreateStatic() then the application writer must instead
 | 
			
		||||
 * provide the memory that will get used by the event group.
 | 
			
		||||
 * xEventGroupCreateStatic() therefore allows an event group to be created
 | 
			
		||||
 * without using any dynamic memory allocation.
 | 
			
		||||
 *
 | 
			
		||||
 * Although event groups are not related to ticks, for internal implementation
 | 
			
		||||
 * reasons the number of bits available for use in an event group is dependent
 | 
			
		||||
 * on the configTICK_TYPE_WIDTH_IN_BITS setting in FreeRTOSConfig.h.  If
 | 
			
		||||
 * configTICK_TYPE_WIDTH_IN_BITS is 0 then each event group contains 8 usable bits (bit
 | 
			
		||||
 * 0 to bit 7).  If configTICK_TYPE_WIDTH_IN_BITS is set to 1 then each event group has
 | 
			
		||||
 * 24 usable bits (bit 0 to bit 23).  If configTICK_TYPE_WIDTH_IN_BITS is set to 2 then
 | 
			
		||||
 * each event group has 56 usable bits (bit 0 to bit 53).  The EventBits_t type
 | 
			
		||||
 * is used to store event bits within an event group.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupCreateStatic()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type
 | 
			
		||||
 * StaticEventGroup_t, which will be then be used to hold the event group's data
 | 
			
		||||
 * structures, removing the need for the memory to be allocated dynamically.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the event group was created then a handle to the event group is
 | 
			
		||||
 * returned.  If pxEventGroupBuffer was NULL then NULL is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  // StaticEventGroup_t is a publicly accessible structure that has the same
 | 
			
		||||
 *  // size and alignment requirements as the real event group structure.  It is
 | 
			
		||||
 *  // provided as a mechanism for applications to know the size of the event
 | 
			
		||||
 *  // group (which is dependent on the architecture and configuration file
 | 
			
		||||
 *  // settings) without breaking the strict data hiding policy by exposing the
 | 
			
		||||
 *  // real event group internals.  This StaticEventGroup_t variable is passed
 | 
			
		||||
 *  // into the xSemaphoreCreateEventGroupStatic() function and is used to store
 | 
			
		||||
 *  // the event group's data structures
 | 
			
		||||
 *  StaticEventGroup_t xEventGroupBuffer;
 | 
			
		||||
 *
 | 
			
		||||
 *  // Create the event group without dynamically allocating any memory.
 | 
			
		||||
 *  xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 */
 | 
			
		||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
    EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupWaitBits(    EventGroupHandle_t xEventGroup,
 | 
			
		||||
 *                                      const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
 *                                      const BaseType_t xClearOnExit,
 | 
			
		||||
 *                                      const BaseType_t xWaitForAllBits,
 | 
			
		||||
 *                                      const TickType_t xTicksToWait );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * [Potentially] block to wait for one or more bits to be set within a
 | 
			
		||||
 * previously created event group.
 | 
			
		||||
 *
 | 
			
		||||
 * This function cannot be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupWaitBits()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are being tested.  The
 | 
			
		||||
 * event group must have previously been created using a call to
 | 
			
		||||
 * xEventGroupCreate().
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
 | 
			
		||||
 * inside the event group.  For example, to wait for bit 0 and/or bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x05.  To wait for bits 0 and/or bit 1 and/or bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x07.  Etc.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within
 | 
			
		||||
 * uxBitsToWaitFor that are set within the event group will be cleared before
 | 
			
		||||
 * xEventGroupWaitBits() returns if the wait condition was met (if the function
 | 
			
		||||
 * returns for a reason other than a timeout).  If xClearOnExit is set to
 | 
			
		||||
 * pdFALSE then the bits set in the event group are not altered when the call to
 | 
			
		||||
 * xEventGroupWaitBits() returns.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then
 | 
			
		||||
 * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor
 | 
			
		||||
 * are set or the specified block time expires.  If xWaitForAllBits is set to
 | 
			
		||||
 * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set
 | 
			
		||||
 * in uxBitsToWaitFor is set or the specified block time expires.  The block
 | 
			
		||||
 * time is specified by the xTicksToWait parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
 | 
			
		||||
 * for one/all (depending on the xWaitForAllBits value) of the bits specified by
 | 
			
		||||
 * uxBitsToWaitFor to become set. A value of portMAX_DELAY can be used to block
 | 
			
		||||
 * indefinitely (provided INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h).
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time either the bits being waited
 | 
			
		||||
 * for became set, or the block time expired.  Test the return value to know
 | 
			
		||||
 * which bits were set.  If xEventGroupWaitBits() returned because its timeout
 | 
			
		||||
 * expired then not all the bits being waited for will be set.  If
 | 
			
		||||
 * xEventGroupWaitBits() returned because the bits it was waiting for were set
 | 
			
		||||
 * then the returned value is the event group value before any bits were
 | 
			
		||||
 * automatically cleared in the case that xClearOnExit parameter was set to
 | 
			
		||||
 * pdTRUE.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * #define BIT_0 ( 1 << 0 )
 | 
			
		||||
 * #define BIT_4 ( 1 << 4 )
 | 
			
		||||
 *
 | 
			
		||||
 * void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
 * {
 | 
			
		||||
 * EventBits_t uxBits;
 | 
			
		||||
 * const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
 | 
			
		||||
 *
 | 
			
		||||
 *      // Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
 | 
			
		||||
 *      // the event group.  Clear the bits before exiting.
 | 
			
		||||
 *      uxBits = xEventGroupWaitBits(
 | 
			
		||||
 *                  xEventGroup,    // The event group being tested.
 | 
			
		||||
 *                  BIT_0 | BIT_4,  // The bits within the event group to wait for.
 | 
			
		||||
 *                  pdTRUE,         // BIT_0 and BIT_4 should be cleared before returning.
 | 
			
		||||
 *                  pdFALSE,        // Don't wait for both bits, either bit will do.
 | 
			
		||||
 *                  xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.
 | 
			
		||||
 *
 | 
			
		||||
 *      if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // xEventGroupWaitBits() returned because both bits were set.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // xEventGroupWaitBits() returned because just BIT_0 was set.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // xEventGroupWaitBits() returned because just BIT_4 was set.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // xEventGroupWaitBits() returned because xTicksToWait ticks passed
 | 
			
		||||
 *          // without either BIT_0 or BIT_4 becoming set.
 | 
			
		||||
 *      }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupWaitBits xEventGroupWaitBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                 const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                 const BaseType_t xClearOnExit,
 | 
			
		||||
                                 const BaseType_t xWaitForAllBits,
 | 
			
		||||
                                 TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Clear bits within an event group.  This function cannot be called from an
 | 
			
		||||
 * interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupClearBits()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear
 | 
			
		||||
 * in the event group.  For example, to clear bit 3 only, set uxBitsToClear to
 | 
			
		||||
 * 0x08.  To clear bit 3 and bit 0 set uxBitsToClear to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group before the specified bits were cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * #define BIT_0 ( 1 << 0 )
 | 
			
		||||
 * #define BIT_4 ( 1 << 4 )
 | 
			
		||||
 *
 | 
			
		||||
 * void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
 * {
 | 
			
		||||
 * EventBits_t uxBits;
 | 
			
		||||
 *
 | 
			
		||||
 *      // Clear bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
 *      uxBits = xEventGroupClearBits(
 | 
			
		||||
 *                              xEventGroup,    // The event group being updated.
 | 
			
		||||
 *                              BIT_0 | BIT_4 );// The bits being cleared.
 | 
			
		||||
 *
 | 
			
		||||
 *      if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Both bit 0 and bit 4 were set before xEventGroupClearBits() was
 | 
			
		||||
 *          // called.  Both will now be clear (not set).
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Bit 0 was set before xEventGroupClearBits() was called.  It will
 | 
			
		||||
 *          // now be clear.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Bit 4 was set before xEventGroupClearBits() was called.  It will
 | 
			
		||||
 *          // now be clear.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Neither bit 0 nor bit 4 were set in the first place.
 | 
			
		||||
 *      }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupClearBits xEventGroupClearBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                  const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupClearBits() that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group is not a deterministic operation because there
 | 
			
		||||
 * are an unknown number of tasks that may be waiting for the bit or bits being
 | 
			
		||||
 * set.  FreeRTOS does not allow nondeterministic operations to be performed
 | 
			
		||||
 * while interrupts are disabled, so protects event groups that are accessed
 | 
			
		||||
 * from tasks by suspending the scheduler rather than disabling interrupts.  As
 | 
			
		||||
 * a result event groups cannot be accessed directly from an interrupt service
 | 
			
		||||
 * routine.  Therefore xEventGroupClearBitsFromISR() sends a message to the
 | 
			
		||||
 * timer task to have the clear operation performed in the context of the timer
 | 
			
		||||
 * task.
 | 
			
		||||
 *
 | 
			
		||||
 * @note If this function returns pdPASS then the timer task is ready to run
 | 
			
		||||
 * and a portYIELD_FROM_ISR(pdTRUE) should be executed to perform the needed
 | 
			
		||||
 * clear on the event group.  This behavior is different from
 | 
			
		||||
 * xEventGroupSetBitsFromISR because the parameter xHigherPriorityTaskWoken is
 | 
			
		||||
 * not present.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear.
 | 
			
		||||
 * For example, to clear bit 3 only, set uxBitsToClear to 0x08.  To clear bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToClear to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the request to execute the function was posted successfully then
 | 
			
		||||
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
 | 
			
		||||
 * if the timer service queue was full.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * #define BIT_0 ( 1 << 0 )
 | 
			
		||||
 * #define BIT_4 ( 1 << 4 )
 | 
			
		||||
 *
 | 
			
		||||
 * // An event group which it is assumed has already been created by a call to
 | 
			
		||||
 * // xEventGroupCreate().
 | 
			
		||||
 * EventGroupHandle_t xEventGroup;
 | 
			
		||||
 *
 | 
			
		||||
 * void anInterruptHandler( void )
 | 
			
		||||
 * {
 | 
			
		||||
 *      // Clear bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
 *      xResult = xEventGroupClearBitsFromISR(
 | 
			
		||||
 *                          xEventGroup,     // The event group being updated.
 | 
			
		||||
 *                          BIT_0 | BIT_4 ); // The bits being set.
 | 
			
		||||
 *
 | 
			
		||||
 *      if( xResult == pdPASS )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // The message was posted successfully.
 | 
			
		||||
 *          portYIELD_FROM_ISR(pdTRUE);
 | 
			
		||||
 *      }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
    BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                            const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#else
 | 
			
		||||
    #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \
 | 
			
		||||
    xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Set bits within an event group.
 | 
			
		||||
 * This function cannot be called from an interrupt.  xEventGroupSetBitsFromISR()
 | 
			
		||||
 * is a version that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group will automatically unblock tasks that are
 | 
			
		||||
 * blocked waiting for the bits.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSetBits()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
 | 
			
		||||
 * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToSet to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time the call to
 | 
			
		||||
 * xEventGroupSetBits() returns.  There are two reasons why the returned value
 | 
			
		||||
 * might have the bits specified by the uxBitsToSet parameter cleared.  First,
 | 
			
		||||
 * if setting a bit results in a task that was waiting for the bit leaving the
 | 
			
		||||
 * blocked state then it is possible the bit will be cleared automatically
 | 
			
		||||
 * (see the xClearBitOnExit parameter of xEventGroupWaitBits()).  Second, any
 | 
			
		||||
 * unblocked (or otherwise Ready state) task that has a priority above that of
 | 
			
		||||
 * the task that called xEventGroupSetBits() will execute and may change the
 | 
			
		||||
 * event group value before the call to xEventGroupSetBits() returns.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * #define BIT_0 ( 1 << 0 )
 | 
			
		||||
 * #define BIT_4 ( 1 << 4 )
 | 
			
		||||
 *
 | 
			
		||||
 * void aFunction( EventGroupHandle_t xEventGroup )
 | 
			
		||||
 * {
 | 
			
		||||
 * EventBits_t uxBits;
 | 
			
		||||
 *
 | 
			
		||||
 *      // Set bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
 *      uxBits = xEventGroupSetBits(
 | 
			
		||||
 *                          xEventGroup,    // The event group being updated.
 | 
			
		||||
 *                          BIT_0 | BIT_4 );// The bits being set.
 | 
			
		||||
 *
 | 
			
		||||
 *      if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Both bit 0 and bit 4 remained set when the function returned.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_0 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Bit 0 remained set when the function returned, but bit 4 was
 | 
			
		||||
 *          // cleared.  It might be that bit 4 was cleared automatically as a
 | 
			
		||||
 *          // task that was waiting for bit 4 was removed from the Blocked
 | 
			
		||||
 *          // state.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else if( ( uxBits & BIT_4 ) != 0 )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Bit 4 remained set when the function returned, but bit 0 was
 | 
			
		||||
 *          // cleared.  It might be that bit 0 was cleared automatically as a
 | 
			
		||||
 *          // task that was waiting for bit 0 was removed from the Blocked
 | 
			
		||||
 *          // state.
 | 
			
		||||
 *      }
 | 
			
		||||
 *      else
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // Neither bit 0 nor bit 4 remained set.  It might be that a task
 | 
			
		||||
 *          // was waiting for both of the bits to be set, and the bits were
 | 
			
		||||
 *          // cleared as the task left the Blocked state.
 | 
			
		||||
 *      }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupSetBits xEventGroupSetBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupSetBits() that can be called from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting bits in an event group is not a deterministic operation because there
 | 
			
		||||
 * are an unknown number of tasks that may be waiting for the bit or bits being
 | 
			
		||||
 * set.  FreeRTOS does not allow nondeterministic operations to be performed in
 | 
			
		||||
 * interrupts or from critical sections.  Therefore xEventGroupSetBitsFromISR()
 | 
			
		||||
 * sends a message to the timer task to have the set operation performed in the
 | 
			
		||||
 * context of the timer task - where a scheduler lock is used in place of a
 | 
			
		||||
 * critical section.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are to be set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet A bitwise value that indicates the bit or bits to set.
 | 
			
		||||
 * For example, to set bit 3 only, set uxBitsToSet to 0x08.  To set bit 3
 | 
			
		||||
 * and bit 0 set uxBitsToSet to 0x09.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken As mentioned above, calling this function
 | 
			
		||||
 * will result in a message being sent to the timer daemon task.  If the
 | 
			
		||||
 * priority of the timer daemon task is higher than the priority of the
 | 
			
		||||
 * currently running task (the task the interrupt interrupted) then
 | 
			
		||||
 * *pxHigherPriorityTaskWoken will be set to pdTRUE by
 | 
			
		||||
 * xEventGroupSetBitsFromISR(), indicating that a context switch should be
 | 
			
		||||
 * requested before the interrupt exits.  For that reason
 | 
			
		||||
 * *pxHigherPriorityTaskWoken must be initialised to pdFALSE.  See the
 | 
			
		||||
 * example code below.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the request to execute the function was posted successfully then
 | 
			
		||||
 * pdPASS is returned, otherwise pdFALSE is returned.  pdFALSE will be returned
 | 
			
		||||
 * if the timer service queue was full.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * #define BIT_0 ( 1 << 0 )
 | 
			
		||||
 * #define BIT_4 ( 1 << 4 )
 | 
			
		||||
 *
 | 
			
		||||
 * // An event group which it is assumed has already been created by a call to
 | 
			
		||||
 * // xEventGroupCreate().
 | 
			
		||||
 * EventGroupHandle_t xEventGroup;
 | 
			
		||||
 *
 | 
			
		||||
 * void anInterruptHandler( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * BaseType_t xHigherPriorityTaskWoken, xResult;
 | 
			
		||||
 *
 | 
			
		||||
 *      // xHigherPriorityTaskWoken must be initialised to pdFALSE.
 | 
			
		||||
 *      xHigherPriorityTaskWoken = pdFALSE;
 | 
			
		||||
 *
 | 
			
		||||
 *      // Set bit 0 and bit 4 in xEventGroup.
 | 
			
		||||
 *      xResult = xEventGroupSetBitsFromISR(
 | 
			
		||||
 *                          xEventGroup,    // The event group being updated.
 | 
			
		||||
 *                          BIT_0 | BIT_4   // The bits being set.
 | 
			
		||||
 *                          &xHigherPriorityTaskWoken );
 | 
			
		||||
 *
 | 
			
		||||
 *      // Was the message posted successfully?
 | 
			
		||||
 *      if( xResult == pdPASS )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // If xHigherPriorityTaskWoken is now set to pdTRUE then a context
 | 
			
		||||
 *          // switch should be requested.  The macro used is port specific and
 | 
			
		||||
 *          // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
 | 
			
		||||
 *          // refer to the documentation page for the port being used.
 | 
			
		||||
 *          portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 | 
			
		||||
 *      }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
    BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                          const EventBits_t uxBitsToSet,
 | 
			
		||||
                                          BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#else
 | 
			
		||||
    #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \
 | 
			
		||||
    xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupSync(    EventGroupHandle_t xEventGroup,
 | 
			
		||||
 *                                  const EventBits_t uxBitsToSet,
 | 
			
		||||
 *                                  const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
 *                                  TickType_t xTicksToWait );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Atomically set bits within an event group, then wait for a combination of
 | 
			
		||||
 * bits to be set within the same event group.  This functionality is typically
 | 
			
		||||
 * used to synchronise multiple tasks, where each task has to wait for the other
 | 
			
		||||
 * tasks to reach a synchronisation point before proceeding.
 | 
			
		||||
 *
 | 
			
		||||
 * This function cannot be used from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * The function will return before its block time expires if the bits specified
 | 
			
		||||
 * by the uxBitsToWait parameter are set, or become set within that time.  In
 | 
			
		||||
 * this case all the bits specified by uxBitsToWait will be automatically
 | 
			
		||||
 * cleared before the function returns.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupSync()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group in which the bits are being tested.  The
 | 
			
		||||
 * event group must have previously been created using a call to
 | 
			
		||||
 * xEventGroupCreate().
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToSet The bits to set in the event group before determining
 | 
			
		||||
 * if, and possibly waiting for, all the bits specified by the uxBitsToWait
 | 
			
		||||
 * parameter are set.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test
 | 
			
		||||
 * inside the event group.  For example, to wait for bit 0 and bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x05.  To wait for bits 0 and bit 1 and bit 2 set
 | 
			
		||||
 * uxBitsToWaitFor to 0x07.  Etc.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait
 | 
			
		||||
 * for all of the bits specified by uxBitsToWaitFor to become set.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The value of the event group at the time either the bits being waited
 | 
			
		||||
 * for became set, or the block time expired.  Test the return value to know
 | 
			
		||||
 * which bits were set.  If xEventGroupSync() returned because its timeout
 | 
			
		||||
 * expired then not all the bits being waited for will be set.  If
 | 
			
		||||
 * xEventGroupSync() returned because all the bits it was waiting for were
 | 
			
		||||
 * set then the returned value is the event group value before any bits were
 | 
			
		||||
 * automatically cleared.
 | 
			
		||||
 *
 | 
			
		||||
 * Example usage:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // Bits used by the three tasks.
 | 
			
		||||
 * #define TASK_0_BIT     ( 1 << 0 )
 | 
			
		||||
 * #define TASK_1_BIT     ( 1 << 1 )
 | 
			
		||||
 * #define TASK_2_BIT     ( 1 << 2 )
 | 
			
		||||
 *
 | 
			
		||||
 * #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
 | 
			
		||||
 *
 | 
			
		||||
 * // Use an event group to synchronise three tasks.  It is assumed this event
 | 
			
		||||
 * // group has already been created elsewhere.
 | 
			
		||||
 * EventGroupHandle_t xEventBits;
 | 
			
		||||
 *
 | 
			
		||||
 * void vTask0( void *pvParameters )
 | 
			
		||||
 * {
 | 
			
		||||
 * EventBits_t uxReturn;
 | 
			
		||||
 * TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
 | 
			
		||||
 *
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *      // Perform task functionality here.
 | 
			
		||||
 *
 | 
			
		||||
 *      // Set bit 0 in the event flag to note this task has reached the
 | 
			
		||||
 *      // sync point.  The other two tasks will set the other two bits defined
 | 
			
		||||
 *      // by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
 | 
			
		||||
 *      // point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
 | 
			
		||||
 *      // for this to happen.
 | 
			
		||||
 *      uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
 | 
			
		||||
 *
 | 
			
		||||
 *      if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
 | 
			
		||||
 *      {
 | 
			
		||||
 *          // All three tasks reached the synchronisation point before the call
 | 
			
		||||
 *          // to xEventGroupSync() timed out.
 | 
			
		||||
 *      }
 | 
			
		||||
 *  }
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * void vTask1( void *pvParameters )
 | 
			
		||||
 * {
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *      // Perform task functionality here.
 | 
			
		||||
 *
 | 
			
		||||
 *      // Set bit 1 in the event flag to note this task has reached the
 | 
			
		||||
 *      // synchronisation point.  The other two tasks will set the other two
 | 
			
		||||
 *      // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
 | 
			
		||||
 *      // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
 | 
			
		||||
 *      // indefinitely for this to happen.
 | 
			
		||||
 *      xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
 | 
			
		||||
 *
 | 
			
		||||
 *      // xEventGroupSync() was called with an indefinite block time, so
 | 
			
		||||
 *      // this task will only reach here if the synchronisation was made by all
 | 
			
		||||
 *      // three tasks, so there is no need to test the return value.
 | 
			
		||||
 *   }
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * void vTask2( void *pvParameters )
 | 
			
		||||
 * {
 | 
			
		||||
 *   for( ;; )
 | 
			
		||||
 *   {
 | 
			
		||||
 *      // Perform task functionality here.
 | 
			
		||||
 *
 | 
			
		||||
 *      // Set bit 2 in the event flag to note this task has reached the
 | 
			
		||||
 *      // synchronisation point.  The other two tasks will set the other two
 | 
			
		||||
 *      // bits defined by ALL_SYNC_BITS.  All three tasks have reached the
 | 
			
		||||
 *      // synchronisation point when all the ALL_SYNC_BITS are set.  Wait
 | 
			
		||||
 *      // indefinitely for this to happen.
 | 
			
		||||
 *      xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
 | 
			
		||||
 *
 | 
			
		||||
 *      // xEventGroupSync() was called with an indefinite block time, so
 | 
			
		||||
 *      // this task will only reach here if the synchronisation was made by all
 | 
			
		||||
 *      // three tasks, so there is no need to test the return value.
 | 
			
		||||
 *  }
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xEventGroupSync xEventGroupSync
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                             const EventBits_t uxBitsToSet,
 | 
			
		||||
                             const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                             TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Returns the current value of the bits in an event group.  This function
 | 
			
		||||
 * cannot be used from an interrupt.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBits()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The event group bits at the time xEventGroupGetBits() was called.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xEventGroupGetBits xEventGroupGetBits
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
#define xEventGroupGetBits( xEventGroup )    xEventGroupClearBits( ( xEventGroup ), 0 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * A version of xEventGroupGetBits() that can be called from an ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetBitsFromISR()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The event group bits at the time xEventGroupGetBitsFromISR() was called.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR
 | 
			
		||||
 * \ingroup EventGroup
 | 
			
		||||
 */
 | 
			
		||||
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  void xEventGroupDelete( EventGroupHandle_t xEventGroup );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Delete an event group that was previously created by a call to
 | 
			
		||||
 * xEventGroupCreate().  Tasks that are blocked on the event group will be
 | 
			
		||||
 * unblocked and obtain 0 as the event group's value.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for vEventGroupDelete()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group being deleted.
 | 
			
		||||
 */
 | 
			
		||||
void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * event_groups.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *  BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
 | 
			
		||||
 *                                         StaticEventGroup_t ** ppxEventGroupBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve a pointer to a statically created event groups's data structure
 | 
			
		||||
 * buffer. It is the same buffer that is supplied at the time of creation.
 | 
			
		||||
 *
 | 
			
		||||
 * The configUSE_EVENT_GROUPS configuration constant must be set to 1 for xEventGroupGetStaticBuffer()
 | 
			
		||||
 * to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xEventGroup The event group for which to retrieve the buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param ppxEventGroupBuffer Used to return a pointer to the event groups's
 | 
			
		||||
 * data structure buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the buffer was retrieved, pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
    BaseType_t xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                           StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
/* For internal use only. */
 | 
			
		||||
void vEventGroupSetBitsCallback( void * pvEventGroup,
 | 
			
		||||
                                 uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vEventGroupClearBitsCallback( void * pvEventGroup,
 | 
			
		||||
                                   uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
    UBaseType_t uxEventGroupGetNumber( void * xEventGroup ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    void vEventGroupSetNumber( void * xEventGroup,
 | 
			
		||||
                               UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* EVENT_GROUPS_H */
 | 
			
		||||
							
								
								
									
										511
									
								
								include/list.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										511
									
								
								include/list.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,511 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This is the list implementation used by the scheduler.  While it is tailored
 | 
			
		||||
 * heavily for the schedulers needs, it is also available for use by
 | 
			
		||||
 * application code.
 | 
			
		||||
 *
 | 
			
		||||
 * list_ts can only store pointers to list_item_ts.  Each ListItem_t contains a
 | 
			
		||||
 * numeric value (xItemValue).  Most of the time the lists are sorted in
 | 
			
		||||
 * ascending item value order.
 | 
			
		||||
 *
 | 
			
		||||
 * Lists are created already containing one list item.  The value of this
 | 
			
		||||
 * item is the maximum possible that can be stored, it is therefore always at
 | 
			
		||||
 * the end of the list and acts as a marker.  The list member pxHead always
 | 
			
		||||
 * points to this marker - even though it is at the tail of the list.  This
 | 
			
		||||
 * is because the tail contains a wrap back pointer to the true head of
 | 
			
		||||
 * the list.
 | 
			
		||||
 *
 | 
			
		||||
 * In addition to it's value, each list item contains a pointer to the next
 | 
			
		||||
 * item in the list (pxNext), a pointer to the list it is in (pxContainer)
 | 
			
		||||
 * and a pointer to back to the object that contains it.  These later two
 | 
			
		||||
 * pointers are included for efficiency of list manipulation.  There is
 | 
			
		||||
 * effectively a two way link between the object containing the list item and
 | 
			
		||||
 * the list item itself.
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * \page ListIntroduction List Implementation
 | 
			
		||||
 * \ingroup FreeRTOSIntro
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef LIST_H
 | 
			
		||||
#define LIST_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
    #error "FreeRTOS.h must be included before list.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The list structure members are modified from within interrupts, and therefore
 | 
			
		||||
 * by rights should be declared volatile.  However, they are only modified in a
 | 
			
		||||
 * functionally atomic way (within critical sections of with the scheduler
 | 
			
		||||
 * suspended) and are either passed by reference into a function or indexed via
 | 
			
		||||
 * a volatile variable.  Therefore, in all use cases tested so far, the volatile
 | 
			
		||||
 * qualifier can be omitted in order to provide a moderate performance
 | 
			
		||||
 * improvement without adversely affecting functional behaviour.  The assembly
 | 
			
		||||
 * instructions generated by the IAR, ARM and GCC compilers when the respective
 | 
			
		||||
 * compiler's options were set for maximum optimisation has been inspected and
 | 
			
		||||
 * deemed to be as intended.  That said, as compiler technology advances, and
 | 
			
		||||
 * especially if aggressive cross module optimisation is used (a use case that
 | 
			
		||||
 * has not been exercised to any great extend) then it is feasible that the
 | 
			
		||||
 * volatile qualifier will be needed for correct optimisation.  It is expected
 | 
			
		||||
 * that a compiler removing essential code because, without the volatile
 | 
			
		||||
 * qualifier on the list structure members and with aggressive cross module
 | 
			
		||||
 * optimisation, the compiler deemed the code unnecessary will result in
 | 
			
		||||
 * complete and obvious failure of the scheduler.  If this is ever experienced
 | 
			
		||||
 * then the volatile qualifier can be inserted in the relevant places within the
 | 
			
		||||
 * list structures by simply defining configLIST_VOLATILE to volatile in
 | 
			
		||||
 * FreeRTOSConfig.h (as per the example at the bottom of this comment block).
 | 
			
		||||
 * If configLIST_VOLATILE is not defined then the preprocessor directives below
 | 
			
		||||
 * will simply #define configLIST_VOLATILE away completely.
 | 
			
		||||
 *
 | 
			
		||||
 * To use volatile list structure members then add the following line to
 | 
			
		||||
 * FreeRTOSConfig.h (without the quotes):
 | 
			
		||||
 * "#define configLIST_VOLATILE volatile"
 | 
			
		||||
 */
 | 
			
		||||
#ifndef configLIST_VOLATILE
 | 
			
		||||
    #define configLIST_VOLATILE
 | 
			
		||||
#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
/* Macros that can be used to place known values within the list structures,
 | 
			
		||||
 * then check that the known values do not get corrupted during the execution of
 | 
			
		||||
 * the application.   These may catch the list data structures being overwritten in
 | 
			
		||||
 * memory.  They will not catch data errors caused by incorrect configuration or
 | 
			
		||||
 * use of FreeRTOS.*/
 | 
			
		||||
#if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 )
 | 
			
		||||
    /* Define the macros to do nothing. */
 | 
			
		||||
    #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listFIRST_LIST_INTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSECOND_LIST_INTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
 | 
			
		||||
    #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )
 | 
			
		||||
    #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )
 | 
			
		||||
    #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )
 | 
			
		||||
    #define listTEST_LIST_ITEM_INTEGRITY( pxItem )
 | 
			
		||||
    #define listTEST_LIST_INTEGRITY( pxList )
 | 
			
		||||
#else /* if ( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) */
 | 
			
		||||
    /* Define macros that add new members into the list structures. */
 | 
			
		||||
    #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE     TickType_t xListItemIntegrityValue1;
 | 
			
		||||
    #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE    TickType_t xListItemIntegrityValue2;
 | 
			
		||||
    #define listFIRST_LIST_INTEGRITY_CHECK_VALUE          TickType_t xListIntegrityValue1;
 | 
			
		||||
    #define listSECOND_LIST_INTEGRITY_CHECK_VALUE         TickType_t xListIntegrityValue2;
 | 
			
		||||
 | 
			
		||||
/* Define macros that set the new structure members to known values. */
 | 
			
		||||
    #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )     ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem )    ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList )              ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE
 | 
			
		||||
    #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList )              ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE
 | 
			
		||||
 | 
			
		||||
/* Define macros that will assert if one of the structure members does not
 | 
			
		||||
 * contain its expected value. */
 | 
			
		||||
    #define listTEST_LIST_ITEM_INTEGRITY( pxItem )                      configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
 | 
			
		||||
    #define listTEST_LIST_INTEGRITY( pxList )                           configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) )
 | 
			
		||||
#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Definition of the only type of object that a list can contain.
 | 
			
		||||
 */
 | 
			
		||||
struct xLIST;
 | 
			
		||||
struct xLIST_ITEM
 | 
			
		||||
{
 | 
			
		||||
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
    configLIST_VOLATILE TickType_t xItemValue;          /**< The value being listed.  In most cases this is used to sort the list in ascending order. */
 | 
			
		||||
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;     /**< Pointer to the next ListItem_t in the list. */
 | 
			
		||||
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /**< Pointer to the previous ListItem_t in the list. */
 | 
			
		||||
    void * pvOwner;                                     /**< Pointer to the object (normally a TCB) that contains the list item.  There is therefore a two way link between the object containing the list item and the list item itself. */
 | 
			
		||||
    struct xLIST * configLIST_VOLATILE pxContainer;     /**< Pointer to the list in which this list item is placed (if any). */
 | 
			
		||||
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
};
 | 
			
		||||
typedef struct xLIST_ITEM ListItem_t;
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_MINI_LIST_ITEM == 1 )
 | 
			
		||||
    struct xMINI_LIST_ITEM
 | 
			
		||||
    {
 | 
			
		||||
        listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
        configLIST_VOLATILE TickType_t xItemValue;
 | 
			
		||||
        struct xLIST_ITEM * configLIST_VOLATILE pxNext;
 | 
			
		||||
        struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
 | 
			
		||||
    };
 | 
			
		||||
    typedef struct xMINI_LIST_ITEM MiniListItem_t;
 | 
			
		||||
#else
 | 
			
		||||
    typedef struct xLIST_ITEM      MiniListItem_t;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Definition of the type of queue used by the scheduler.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct xLIST
 | 
			
		||||
{
 | 
			
		||||
    listFIRST_LIST_INTEGRITY_CHECK_VALUE      /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
    configLIST_VOLATILE UBaseType_t uxNumberOfItems;
 | 
			
		||||
    ListItem_t * configLIST_VOLATILE pxIndex; /**< Used to walk through the list.  Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */
 | 
			
		||||
    MiniListItem_t xListEnd;                  /**< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */
 | 
			
		||||
    listSECOND_LIST_INTEGRITY_CHECK_VALUE     /**< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
} List_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to set the owner of a list item.  The owner of a list item
 | 
			
		||||
 * is the object (usually a TCB) that contains the list item.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner )    ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to get the owner of a list item.  The owner of a list item
 | 
			
		||||
 * is the object (usually a TCB) that contains the list item.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_LIST_ITEM_OWNER( pxListItem )             ( ( pxListItem )->pvOwner )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to set the value of the list item.  In most cases the value is
 | 
			
		||||
 * used to sort the list in ascending order.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listSET_LIST_ITEM_VALUE( pxListItem, xValue )     ( ( pxListItem )->xItemValue = ( xValue ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to retrieve the value of the list item.  The value can
 | 
			
		||||
 * represent anything - for example the priority of a task, or the time at
 | 
			
		||||
 * which a task should be unblocked.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_LIST_ITEM_VALUE( pxListItem )             ( ( pxListItem )->xItemValue )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to retrieve the value of the list item at the head of a given
 | 
			
		||||
 * list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList )        ( ( ( pxList )->xListEnd ).pxNext->xItemValue )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list item at the head of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_HEAD_ENTRY( pxList )                      ( ( ( pxList )->xListEnd ).pxNext )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the next list item.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_NEXT listGET_NEXT
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_NEXT( pxListItem )                        ( ( pxListItem )->pxNext )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list item that marks the end of the list
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_END_MARKER listGET_END_MARKER
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_END_MARKER( pxList )                      ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to determine if a list contains any items.  The macro will
 | 
			
		||||
 * only have the value true if the list is empty.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listLIST_IS_EMPTY listLIST_IS_EMPTY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_IS_EMPTY( pxList )                       ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access macro to return the number of items in the list.
 | 
			
		||||
 */
 | 
			
		||||
#define listCURRENT_LIST_LENGTH( pxList )                 ( ( pxList )->uxNumberOfItems )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access function to obtain the owner of the next entry in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * The list member pxIndex is used to walk through a list.  Calling
 | 
			
		||||
 * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list
 | 
			
		||||
 * and returns that entry's pxOwner parameter.  Using multiple calls to this
 | 
			
		||||
 * function it is therefore possible to move through every item contained in
 | 
			
		||||
 * a list.
 | 
			
		||||
 *
 | 
			
		||||
 * The pxOwner parameter of a list item is a pointer to the object that owns
 | 
			
		||||
 * the list item.  In the scheduler this is normally a task control block.
 | 
			
		||||
 * The pxOwner parameter effectively creates a two way link between the list
 | 
			
		||||
 * item and its owner.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxTCB pxTCB is set to the address of the owner of the next list item.
 | 
			
		||||
 * @param pxList The list from which the next item owner is to be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#if ( configNUMBER_OF_CORES == 1 )
 | 
			
		||||
    #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                       \
 | 
			
		||||
    do {                                                                                       \
 | 
			
		||||
        List_t * const pxConstList = ( pxList );                                               \
 | 
			
		||||
        /* Increment the index to the next item and return the item, ensuring */               \
 | 
			
		||||
        /* we don't return the marker used at the end of the list.  */                         \
 | 
			
		||||
        ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                           \
 | 
			
		||||
        if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \
 | 
			
		||||
        {                                                                                      \
 | 
			
		||||
            ( pxConstList )->pxIndex = ( pxConstList )->xListEnd.pxNext;                       \
 | 
			
		||||
        }                                                                                      \
 | 
			
		||||
        ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                         \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
#else /* #if ( configNUMBER_OF_CORES == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* This function is not required in SMP. FreeRTOS SMP scheduler doesn't use
 | 
			
		||||
 * pxIndex and it should always point to the xListEnd. Not defining this macro
 | 
			
		||||
 * here to prevent updating pxIndex.
 | 
			
		||||
 */
 | 
			
		||||
#endif /* #if ( configNUMBER_OF_CORES == 1 ) */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Version of uxListRemove() that does not return a value.  Provided as a slight
 | 
			
		||||
 * optimisation for xTaskIncrementTick() by being inline.
 | 
			
		||||
 *
 | 
			
		||||
 * Remove an item from a list.  The list item has a pointer to the list that
 | 
			
		||||
 * it is in, so only the list item need be passed into the function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxListRemove The item to be removed.  The item will remove itself from
 | 
			
		||||
 * the list pointed to by it's pxContainer parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of items that remain in the list after the list item has
 | 
			
		||||
 * been removed.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listREMOVE_ITEM listREMOVE_ITEM
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listREMOVE_ITEM( pxItemToRemove ) \
 | 
			
		||||
    do {                                  \
 | 
			
		||||
        /* The list item knows which list it is in.  Obtain the list from the list \
 | 
			
		||||
         * item. */                                                                                 \
 | 
			
		||||
        List_t * const pxList = ( pxItemToRemove )->pxContainer;                                    \
 | 
			
		||||
                                                                                                    \
 | 
			
		||||
        ( pxItemToRemove )->pxNext->pxPrevious = ( pxItemToRemove )->pxPrevious;                    \
 | 
			
		||||
        ( pxItemToRemove )->pxPrevious->pxNext = ( pxItemToRemove )->pxNext;                        \
 | 
			
		||||
        /* Make sure the index is left pointing to a valid item. */                                 \
 | 
			
		||||
        if( pxList->pxIndex == ( pxItemToRemove ) )                                                 \
 | 
			
		||||
        {                                                                                           \
 | 
			
		||||
            pxList->pxIndex = ( pxItemToRemove )->pxPrevious;                                       \
 | 
			
		||||
        }                                                                                           \
 | 
			
		||||
                                                                                                    \
 | 
			
		||||
        ( pxItemToRemove )->pxContainer = NULL;                                                     \
 | 
			
		||||
        ( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) - 1U ); \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Inline version of vListInsertEnd() to provide slight optimisation for
 | 
			
		||||
 * xTaskIncrementTick().
 | 
			
		||||
 *
 | 
			
		||||
 * Insert a list item into a list.  The item will be inserted in a position
 | 
			
		||||
 * such that it will be the last item within the list returned by multiple
 | 
			
		||||
 * calls to listGET_OWNER_OF_NEXT_ENTRY.
 | 
			
		||||
 *
 | 
			
		||||
 * The list member pxIndex is used to walk through a list.  Calling
 | 
			
		||||
 * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
 | 
			
		||||
 * Placing an item in a list using vListInsertEnd effectively places the item
 | 
			
		||||
 * in the list position pointed to by pxIndex.  This means that every other
 | 
			
		||||
 * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
 | 
			
		||||
 * the pxIndex parameter again points to the item being inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list into which the item is to be inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxNewListItem The list item to be inserted into the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listINSERT_END listINSERT_END
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listINSERT_END( pxList, pxNewListItem )           \
 | 
			
		||||
    do {                                                  \
 | 
			
		||||
        ListItem_t * const pxIndex = ( pxList )->pxIndex; \
 | 
			
		||||
                                                          \
 | 
			
		||||
        /* Only effective when configASSERT() is also defined, these tests may catch \
 | 
			
		||||
         * the list data structures being overwritten in memory.  They will not catch \
 | 
			
		||||
         * data errors caused by incorrect configuration or use of FreeRTOS. */ \
 | 
			
		||||
        listTEST_LIST_INTEGRITY( ( pxList ) );                                  \
 | 
			
		||||
        listTEST_LIST_ITEM_INTEGRITY( ( pxNewListItem ) );                      \
 | 
			
		||||
                                                                                \
 | 
			
		||||
        /* Insert a new list item into ( pxList ), but rather than sort the list, \
 | 
			
		||||
         * makes the new list item the last item to be removed by a call to \
 | 
			
		||||
         * listGET_OWNER_OF_NEXT_ENTRY(). */                                                        \
 | 
			
		||||
        ( pxNewListItem )->pxNext = pxIndex;                                                        \
 | 
			
		||||
        ( pxNewListItem )->pxPrevious = pxIndex->pxPrevious;                                        \
 | 
			
		||||
                                                                                                    \
 | 
			
		||||
        pxIndex->pxPrevious->pxNext = ( pxNewListItem );                                            \
 | 
			
		||||
        pxIndex->pxPrevious = ( pxNewListItem );                                                    \
 | 
			
		||||
                                                                                                    \
 | 
			
		||||
        /* Remember which list the item is in. */                                                   \
 | 
			
		||||
        ( pxNewListItem )->pxContainer = ( pxList );                                                \
 | 
			
		||||
                                                                                                    \
 | 
			
		||||
        ( ( pxList )->uxNumberOfItems ) = ( UBaseType_t ) ( ( ( pxList )->uxNumberOfItems ) + 1U ); \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Access function to obtain the owner of the first entry in a list.  Lists
 | 
			
		||||
 * are normally sorted in ascending item value order.
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns the pxOwner member of the first item in the list.
 | 
			
		||||
 * The pxOwner parameter of a list item is a pointer to the object that owns
 | 
			
		||||
 * the list item.  In the scheduler this is normally a task control block.
 | 
			
		||||
 * The pxOwner parameter effectively creates a two way link between the list
 | 
			
		||||
 * item and its owner.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list from which the owner of the head item is to be
 | 
			
		||||
 * returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
#define listGET_OWNER_OF_HEAD_ENTRY( pxList )            ( ( &( ( pxList )->xListEnd ) )->pxNext->pvOwner )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Check to see if a list item is within a list.  The list item maintains a
 | 
			
		||||
 * "container" pointer that points to the list it is in.  All this macro does
 | 
			
		||||
 * is check to see if the container and the list match.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list we want to know if the list item is within.
 | 
			
		||||
 * @param pxListItem The list item we want to know if is in the list.
 | 
			
		||||
 * @return pdTRUE if the list item is in the list, otherwise pdFALSE.
 | 
			
		||||
 */
 | 
			
		||||
#define listIS_CONTAINED_WITHIN( pxList, pxListItem )    ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Return the list a list item is contained within (referenced from).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxListItem The list item being queried.
 | 
			
		||||
 * @return A pointer to the List_t object that references the pxListItem
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_ITEM_CONTAINER( pxListItem )            ( ( pxListItem )->pxContainer )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This provides a crude means of knowing if a list has been initialised, as
 | 
			
		||||
 * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise()
 | 
			
		||||
 * function.
 | 
			
		||||
 */
 | 
			
		||||
#define listLIST_IS_INITIALISED( pxList )                ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY )
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Must be called before a list is used!  This initialises all the members
 | 
			
		||||
 * of the list structure and inserts the xListEnd item into the list as a
 | 
			
		||||
 * marker to the back of the list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList Pointer to the list being initialised.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInitialise vListInitialise
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Must be called before a list item is used.  This sets the list container to
 | 
			
		||||
 * null so the item does not think that it is already contained in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxItem Pointer to the list item being initialised.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInitialiseItem vListInitialiseItem
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a list item into a list.  The item will be inserted into the list in
 | 
			
		||||
 * a position determined by its item value (ascending item value order).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list into which the item is to be inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxNewListItem The item that is to be placed in the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInsert vListInsert
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInsert( List_t * const pxList,
 | 
			
		||||
                  ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Insert a list item into a list.  The item will be inserted in a position
 | 
			
		||||
 * such that it will be the last item within the list returned by multiple
 | 
			
		||||
 * calls to listGET_OWNER_OF_NEXT_ENTRY.
 | 
			
		||||
 *
 | 
			
		||||
 * The list member pxIndex is used to walk through a list.  Calling
 | 
			
		||||
 * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list.
 | 
			
		||||
 * Placing an item in a list using vListInsertEnd effectively places the item
 | 
			
		||||
 * in the list position pointed to by pxIndex.  This means that every other
 | 
			
		||||
 * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before
 | 
			
		||||
 * the pxIndex parameter again points to the item being inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxList The list into which the item is to be inserted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxNewListItem The list item to be inserted into the list.
 | 
			
		||||
 *
 | 
			
		||||
 * \page vListInsertEnd vListInsertEnd
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
void vListInsertEnd( List_t * const pxList,
 | 
			
		||||
                     ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Remove an item from a list.  The list item has a pointer to the list that
 | 
			
		||||
 * it is in, so only the list item need be passed into the function.
 | 
			
		||||
 *
 | 
			
		||||
 * @param uxListRemove The item to be removed.  The item will remove itself from
 | 
			
		||||
 * the list pointed to by it's pxContainer parameter.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of items that remain in the list after the list item has
 | 
			
		||||
 * been removed.
 | 
			
		||||
 *
 | 
			
		||||
 * \page uxListRemove uxListRemove
 | 
			
		||||
 * \ingroup LinkedList
 | 
			
		||||
 */
 | 
			
		||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* ifndef LIST_H */
 | 
			
		||||
							
								
								
									
										967
									
								
								include/message_buffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										967
									
								
								include/message_buffer.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,967 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Message buffers build functionality on top of FreeRTOS stream buffers.
 | 
			
		||||
 * Whereas stream buffers are used to send a continuous stream of data from one
 | 
			
		||||
 * task or interrupt to another, message buffers are used to send variable
 | 
			
		||||
 * length discrete messages from one task or interrupt to another.  Their
 | 
			
		||||
 * implementation is light weight, making them particularly suited for interrupt
 | 
			
		||||
 * to task and core to core communication scenarios.
 | 
			
		||||
 *
 | 
			
		||||
 * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
 | 
			
		||||
 * implementation (so also the message buffer implementation, as message buffers
 | 
			
		||||
 * are built on top of stream buffers) assumes there is only one task or
 | 
			
		||||
 * interrupt that will write to the buffer (the writer), and only one task or
 | 
			
		||||
 * interrupt that will read from the buffer (the reader).  It is safe for the
 | 
			
		||||
 * writer and reader to be different tasks or interrupts, but, unlike other
 | 
			
		||||
 * FreeRTOS objects, it is not safe to have multiple different writers or
 | 
			
		||||
 * multiple different readers.  If there are to be multiple different writers
 | 
			
		||||
 * then the application writer must place each call to a writing API function
 | 
			
		||||
 * (such as xMessageBufferSend()) inside a critical section and set the send
 | 
			
		||||
 * block time to 0.  Likewise, if there are to be multiple different readers
 | 
			
		||||
 * then the application writer must place each call to a reading API function
 | 
			
		||||
 * (such as xMessageBufferRead()) inside a critical section and set the receive
 | 
			
		||||
 * timeout to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Message buffers hold variable length messages.  To enable that, when a
 | 
			
		||||
 * message is written to the message buffer an additional sizeof( size_t ) bytes
 | 
			
		||||
 * are also written to store the message's length (that happens internally, with
 | 
			
		||||
 * the API function).  sizeof( size_t ) is typically 4 bytes on a 32-bit
 | 
			
		||||
 * architecture, so writing a 10 byte message to a message buffer on a 32-bit
 | 
			
		||||
 * architecture will actually reduce the available space in the message buffer
 | 
			
		||||
 * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length
 | 
			
		||||
 * of the message).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef FREERTOS_MESSAGE_BUFFER_H
 | 
			
		||||
#define FREERTOS_MESSAGE_BUFFER_H
 | 
			
		||||
 | 
			
		||||
#ifndef INC_FREERTOS_H
 | 
			
		||||
    #error "include FreeRTOS.h must appear in source files before include message_buffer.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Message buffers are built onto of stream buffers. */
 | 
			
		||||
#include "stream_buffer.h"
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#if defined( __cplusplus )
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Type by which message buffers are referenced.  For example, a call to
 | 
			
		||||
 * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can
 | 
			
		||||
 * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(),
 | 
			
		||||
 * etc. Message buffer is essentially built as a stream buffer hence its handle
 | 
			
		||||
 * is also set to same type as a stream buffer handle.
 | 
			
		||||
 */
 | 
			
		||||
typedef StreamBufferHandle_t MessageBufferHandle_t;
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Creates a new message buffer using dynamically allocated memory.  See
 | 
			
		||||
 * xMessageBufferCreateStatic() for a version that uses statically allocated
 | 
			
		||||
 * memory (memory that is allocated at compile time).
 | 
			
		||||
 *
 | 
			
		||||
 * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in
 | 
			
		||||
 * FreeRTOSConfig.h for xMessageBufferCreate() to be available.
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferCreate() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBufferSizeBytes The total number of bytes (not messages) the message
 | 
			
		||||
 * buffer will be able to hold at any one time.  When a message is written to
 | 
			
		||||
 * the message buffer an additional sizeof( size_t ) bytes are also written to
 | 
			
		||||
 * store the message's length.  sizeof( size_t ) is typically 4 bytes on a
 | 
			
		||||
 * 32-bit architecture, so on most 32-bit architectures a 10 byte message will
 | 
			
		||||
 * take up 14 bytes of message buffer space.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxSendCompletedCallback Callback invoked when a send operation to the
 | 
			
		||||
 * message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
 | 
			
		||||
 * is called without the parameter, then it will use the default implementation
 | 
			
		||||
 * provided by sbSEND_COMPLETED macro. To enable the callback,
 | 
			
		||||
 * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxReceiveCompletedCallback Callback invoked when a receive operation from
 | 
			
		||||
 * the message buffer is complete. If the parameter is NULL or xMessageBufferCreate()
 | 
			
		||||
 * is called without the parameter, it will use the default implementation provided
 | 
			
		||||
 * by sbRECEIVE_COMPLETED macro. To enable the callback,
 | 
			
		||||
 * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If NULL is returned, then the message buffer cannot be created
 | 
			
		||||
 * because there is insufficient heap memory available for FreeRTOS to allocate
 | 
			
		||||
 * the message buffer data structures and storage area.  A non-NULL value being
 | 
			
		||||
 * returned indicates that the message buffer has been created successfully -
 | 
			
		||||
 * the returned value should be stored as the handle to the created message
 | 
			
		||||
 * buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *
 | 
			
		||||
 * void vAFunction( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * MessageBufferHandle_t xMessageBuffer;
 | 
			
		||||
 * const size_t xMessageBufferSizeBytes = 100;
 | 
			
		||||
 *
 | 
			
		||||
 *  // Create a message buffer that can hold 100 bytes.  The memory used to hold
 | 
			
		||||
 *  // both the message buffer structure and the messages themselves is allocated
 | 
			
		||||
 *  // dynamically.  Each message added to the buffer consumes an additional 4
 | 
			
		||||
 *  // bytes which are used to hold the length of the message.
 | 
			
		||||
 *  xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xMessageBuffer == NULL )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // There was not enough heap memory space available to create the
 | 
			
		||||
 *      // message buffer.
 | 
			
		||||
 *  }
 | 
			
		||||
 *  else
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The message buffer was created successfully and can now be used.
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferCreate xMessageBufferCreate
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferCreate( xBufferSizeBytes ) \
 | 
			
		||||
    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, NULL, NULL )
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
 | 
			
		||||
    #define xMessageBufferCreateWithCallback( xBufferSizeBytes, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
 | 
			
		||||
    xStreamBufferGenericCreate( ( xBufferSizeBytes ), ( size_t ) 0, sbTYPE_MESSAGE_BUFFER, ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
 | 
			
		||||
 *                                                   uint8_t *pucMessageBufferStorageArea,
 | 
			
		||||
 *                                                   StaticMessageBuffer_t *pxStaticMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * Creates a new message buffer using statically allocated memory.  See
 | 
			
		||||
 * xMessageBufferCreate() for a version that uses dynamically allocated memory.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferCreateStatic() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the
 | 
			
		||||
 * pucMessageBufferStorageArea parameter.  When a message is written to the
 | 
			
		||||
 * message buffer an additional sizeof( size_t ) bytes are also written to store
 | 
			
		||||
 * the message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit
 | 
			
		||||
 * architecture, so on most 32-bit architecture a 10 byte message will take up
 | 
			
		||||
 * 14 bytes of message buffer space.  The maximum number of bytes that can be
 | 
			
		||||
 * stored in the message buffer is actually (xBufferSizeBytes - 1).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at
 | 
			
		||||
 * least xBufferSizeBytes big.  This is the array to which messages are
 | 
			
		||||
 * copied when they are written to the message buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxStaticMessageBuffer Must point to a variable of type
 | 
			
		||||
 * StaticMessageBuffer_t, which will be used to hold the message buffer's data
 | 
			
		||||
 * structure.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxSendCompletedCallback Callback invoked when a new message is sent to the message buffer.
 | 
			
		||||
 * If the parameter is NULL or xMessageBufferCreate() is called without the parameter, then it will use the default
 | 
			
		||||
 * implementation provided by sbSEND_COMPLETED macro. To enable the callback,
 | 
			
		||||
 * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxReceiveCompletedCallback Callback invoked when a message is read from a
 | 
			
		||||
 * message buffer. If the parameter is NULL or xMessageBufferCreate() is called without the parameter, it will
 | 
			
		||||
 * use the default implementation provided by sbRECEIVE_COMPLETED macro. To enable the callback,
 | 
			
		||||
 * configUSE_SB_COMPLETED_CALLBACK must be set to 1 in FreeRTOSConfig.h.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the message buffer is created successfully then a handle to the
 | 
			
		||||
 * created message buffer is returned. If either pucMessageBufferStorageArea or
 | 
			
		||||
 * pxStaticmessageBuffer are NULL then NULL is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 *
 | 
			
		||||
 * // Used to dimension the array used to hold the messages.  The available space
 | 
			
		||||
 * // will actually be one less than this, so 999.
 | 
			
		||||
 #define STORAGE_SIZE_BYTES 1000
 | 
			
		||||
 *
 | 
			
		||||
 * // Defines the memory that will actually hold the messages within the message
 | 
			
		||||
 * // buffer.
 | 
			
		||||
 * static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
 | 
			
		||||
 *
 | 
			
		||||
 * // The variable used to hold the message buffer structure.
 | 
			
		||||
 * StaticMessageBuffer_t xMessageBufferStruct;
 | 
			
		||||
 *
 | 
			
		||||
 * void MyFunction( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * MessageBufferHandle_t xMessageBuffer;
 | 
			
		||||
 *
 | 
			
		||||
 *  xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucStorageBuffer ),
 | 
			
		||||
 *                                               ucStorageBuffer,
 | 
			
		||||
 *                                               &xMessageBufferStruct );
 | 
			
		||||
 *
 | 
			
		||||
 *  // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
 | 
			
		||||
 *  // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
 | 
			
		||||
 *  // reference the created message buffer in other message buffer API calls.
 | 
			
		||||
 *
 | 
			
		||||
 *  // Other code that uses the message buffer can go here.
 | 
			
		||||
 * }
 | 
			
		||||
 *
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) \
 | 
			
		||||
    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), NULL, NULL )
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
 | 
			
		||||
    #define xMessageBufferCreateStaticWithCallback( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer, pxSendCompletedCallback, pxReceiveCompletedCallback ) \
 | 
			
		||||
    xStreamBufferGenericCreateStatic( ( xBufferSizeBytes ), 0, sbTYPE_MESSAGE_BUFFER, ( pucMessageBufferStorageArea ), ( pxStaticMessageBuffer ), ( pxSendCompletedCallback ), ( pxReceiveCompletedCallback ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferGetStaticBuffers( MessageBufferHandle_t xMessageBuffer,
 | 
			
		||||
 *                                            uint8_t ** ppucMessageBufferStorageArea,
 | 
			
		||||
 *                                            StaticMessageBuffer_t ** ppxStaticMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieve pointers to a statically created message buffer's data structure
 | 
			
		||||
 * buffer and storage area buffer. These are the same buffers that are supplied
 | 
			
		||||
 * at the time of creation.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferGetStaticBuffers() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The message buffer for which to retrieve the buffers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param ppucMessageBufferStorageArea Used to return a pointer to the
 | 
			
		||||
 * message buffer's storage area buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param ppxStaticMessageBuffer Used to return a pointer to the message
 | 
			
		||||
 * buffer's data structure buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if buffers were retrieved, pdFALSE otherwise..
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferGetStaticBuffers xMessageBufferGetStaticBuffers
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#if ( configSUPPORT_STATIC_ALLOCATION == 1 )
 | 
			
		||||
    #define xMessageBufferGetStaticBuffers( xMessageBuffer, ppucMessageBufferStorageArea, ppxStaticMessageBuffer ) \
 | 
			
		||||
    xStreamBufferGetStaticBuffers( ( xMessageBuffer ), ( ppucMessageBufferStorageArea ), ( ppxStaticMessageBuffer ) )
 | 
			
		||||
#endif /* configSUPPORT_STATIC_ALLOCATION */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
 | 
			
		||||
 *                            const void *pvTxData,
 | 
			
		||||
 *                            size_t xDataLengthBytes,
 | 
			
		||||
 *                            TickType_t xTicksToWait );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Sends a discrete message to the message buffer.  The message can be any
 | 
			
		||||
 * length that fits within the buffer's free space, and is copied into the
 | 
			
		||||
 * buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
 | 
			
		||||
 * implementation (so also the message buffer implementation, as message buffers
 | 
			
		||||
 * are built on top of stream buffers) assumes there is only one task or
 | 
			
		||||
 * interrupt that will write to the buffer (the writer), and only one task or
 | 
			
		||||
 * interrupt that will read from the buffer (the reader).  It is safe for the
 | 
			
		||||
 * writer and reader to be different tasks or interrupts, but, unlike other
 | 
			
		||||
 * FreeRTOS objects, it is not safe to have multiple different writers or
 | 
			
		||||
 * multiple different readers.  If there are to be multiple different writers
 | 
			
		||||
 * then the application writer must place each call to a writing API function
 | 
			
		||||
 * (such as xMessageBufferSend()) inside a critical section and set the send
 | 
			
		||||
 * block time to 0.  Likewise, if there are to be multiple different readers
 | 
			
		||||
 * then the application writer must place each call to a reading API function
 | 
			
		||||
 * (such as xMessageBufferRead()) inside a critical section and set the receive
 | 
			
		||||
 * block time to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferSend() to write to a message buffer from a task.  Use
 | 
			
		||||
 * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
 | 
			
		||||
 * service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferSend() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer to which a message is
 | 
			
		||||
 * being sent.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvTxData A pointer to the message that is to be copied into the
 | 
			
		||||
 * message buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xDataLengthBytes The length of the message.  That is, the number of
 | 
			
		||||
 * bytes to copy from pvTxData into the message buffer.  When a message is
 | 
			
		||||
 * written to the message buffer an additional sizeof( size_t ) bytes are also
 | 
			
		||||
 * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
 | 
			
		||||
 * on a 32-bit architecture, so on most 32-bit architecture setting
 | 
			
		||||
 * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
 | 
			
		||||
 * bytes (20 bytes of message data and 4 bytes to hold the message length).
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time the calling task should remain
 | 
			
		||||
 * in the Blocked state to wait for enough space to become available in the
 | 
			
		||||
 * message buffer, should the message buffer have insufficient space when
 | 
			
		||||
 * xMessageBufferSend() is called.  The calling task will never block if
 | 
			
		||||
 * xTicksToWait is zero.  The block time is specified in tick periods, so the
 | 
			
		||||
 * absolute time it represents is dependent on the tick frequency.  The macro
 | 
			
		||||
 * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
 | 
			
		||||
 * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
 | 
			
		||||
 * the task to wait indefinitely (without timing out), provided
 | 
			
		||||
 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
 | 
			
		||||
 * CPU time when they are in the Blocked state.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of bytes written to the message buffer.  If the call to
 | 
			
		||||
 * xMessageBufferSend() times out before there was enough space to write the
 | 
			
		||||
 * message into the message buffer then zero is returned.  If the call did not
 | 
			
		||||
 * time out then xDataLengthBytes is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * void vAFunction( MessageBufferHandle_t xMessageBuffer )
 | 
			
		||||
 * {
 | 
			
		||||
 * size_t xBytesSent;
 | 
			
		||||
 * uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
 | 
			
		||||
 * char *pcStringToSend = "String to send";
 | 
			
		||||
 * const TickType_t x100ms = pdMS_TO_TICKS( 100 );
 | 
			
		||||
 *
 | 
			
		||||
 *  // Send an array to the message buffer, blocking for a maximum of 100ms to
 | 
			
		||||
 *  // wait for enough space to be available in the message buffer.
 | 
			
		||||
 *  xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xBytesSent != sizeof( ucArrayToSend ) )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The call to xMessageBufferSend() times out before there was enough
 | 
			
		||||
 *      // space in the buffer for the data to be written.
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 *  // Send the string to the message buffer.  Return immediately if there is
 | 
			
		||||
 *  // not enough space in the buffer.
 | 
			
		||||
 *  xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xBytesSent != strlen( pcStringToSend ) )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The string could not be added to the message buffer because there was
 | 
			
		||||
 *      // not enough free space in the buffer.
 | 
			
		||||
 *  }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferSend xMessageBufferSend
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) \
 | 
			
		||||
    xStreamBufferSend( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( xTicksToWait ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
 | 
			
		||||
 *                                   const void *pvTxData,
 | 
			
		||||
 *                                   size_t xDataLengthBytes,
 | 
			
		||||
 *                                   BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Interrupt safe version of the API function that sends a discrete message to
 | 
			
		||||
 * the message buffer.  The message can be any length that fits within the
 | 
			
		||||
 * buffer's free space, and is copied into the buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
 | 
			
		||||
 * implementation (so also the message buffer implementation, as message buffers
 | 
			
		||||
 * are built on top of stream buffers) assumes there is only one task or
 | 
			
		||||
 * interrupt that will write to the buffer (the writer), and only one task or
 | 
			
		||||
 * interrupt that will read from the buffer (the reader).  It is safe for the
 | 
			
		||||
 * writer and reader to be different tasks or interrupts, but, unlike other
 | 
			
		||||
 * FreeRTOS objects, it is not safe to have multiple different writers or
 | 
			
		||||
 * multiple different readers.  If there are to be multiple different writers
 | 
			
		||||
 * then the application writer must place each call to a writing API function
 | 
			
		||||
 * (such as xMessageBufferSend()) inside a critical section and set the send
 | 
			
		||||
 * block time to 0.  Likewise, if there are to be multiple different readers
 | 
			
		||||
 * then the application writer must place each call to a reading API function
 | 
			
		||||
 * (such as xMessageBufferRead()) inside a critical section and set the receive
 | 
			
		||||
 * block time to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferSend() to write to a message buffer from a task.  Use
 | 
			
		||||
 * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
 | 
			
		||||
 * service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferSendFromISR() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer to which a message is
 | 
			
		||||
 * being sent.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvTxData A pointer to the message that is to be copied into the
 | 
			
		||||
 * message buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xDataLengthBytes The length of the message.  That is, the number of
 | 
			
		||||
 * bytes to copy from pvTxData into the message buffer.  When a message is
 | 
			
		||||
 * written to the message buffer an additional sizeof( size_t ) bytes are also
 | 
			
		||||
 * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
 | 
			
		||||
 * on a 32-bit architecture, so on most 32-bit architecture setting
 | 
			
		||||
 * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
 | 
			
		||||
 * bytes (20 bytes of message data and 4 bytes to hold the message length).
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
 | 
			
		||||
 * have a task blocked on it waiting for data.  Calling
 | 
			
		||||
 * xMessageBufferSendFromISR() can make data available, and so cause a task that
 | 
			
		||||
 * was waiting for data to leave the Blocked state.  If calling
 | 
			
		||||
 * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
 | 
			
		||||
 * unblocked task has a priority higher than the currently executing task (the
 | 
			
		||||
 * task that was interrupted), then, internally, xMessageBufferSendFromISR()
 | 
			
		||||
 * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
 | 
			
		||||
 * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
 | 
			
		||||
 * context switch should be performed before the interrupt is exited.  This will
 | 
			
		||||
 * ensure that the interrupt returns directly to the highest priority Ready
 | 
			
		||||
 * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
 | 
			
		||||
 * is passed into the function.  See the code example below for an example.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of bytes actually written to the message buffer.  If the
 | 
			
		||||
 * message buffer didn't have enough free space for the message to be stored
 | 
			
		||||
 * then 0 is returned, otherwise xDataLengthBytes is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // A message buffer that has already been created.
 | 
			
		||||
 * MessageBufferHandle_t xMessageBuffer;
 | 
			
		||||
 *
 | 
			
		||||
 * void vAnInterruptServiceRoutine( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * size_t xBytesSent;
 | 
			
		||||
 * char *pcStringToSend = "String to send";
 | 
			
		||||
 * BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
 | 
			
		||||
 *
 | 
			
		||||
 *  // Attempt to send the string to the message buffer.
 | 
			
		||||
 *  xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
 | 
			
		||||
 *                                          ( void * ) pcStringToSend,
 | 
			
		||||
 *                                          strlen( pcStringToSend ),
 | 
			
		||||
 *                                          &xHigherPriorityTaskWoken );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xBytesSent != strlen( pcStringToSend ) )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // The string could not be added to the message buffer because there was
 | 
			
		||||
 *      // not enough free space in the buffer.
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 *  // If xHigherPriorityTaskWoken was set to pdTRUE inside
 | 
			
		||||
 *  // xMessageBufferSendFromISR() then a task that has a priority above the
 | 
			
		||||
 *  // priority of the currently executing task was unblocked and a context
 | 
			
		||||
 *  // switch should be performed to ensure the ISR returns to the unblocked
 | 
			
		||||
 *  // task.  In most FreeRTOS ports this is done by simply passing
 | 
			
		||||
 *  // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
 | 
			
		||||
 *  // variables value, and perform the context switch if necessary.  Check the
 | 
			
		||||
 *  // documentation for the port in use for port specific instructions.
 | 
			
		||||
 *  portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) \
 | 
			
		||||
    xStreamBufferSendFromISR( ( xMessageBuffer ), ( pvTxData ), ( xDataLengthBytes ), ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
 | 
			
		||||
 *                               void *pvRxData,
 | 
			
		||||
 *                               size_t xBufferLengthBytes,
 | 
			
		||||
 *                               TickType_t xTicksToWait );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Receives a discrete message from a message buffer.  Messages can be of
 | 
			
		||||
 * variable length and are copied out of the buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
 | 
			
		||||
 * implementation (so also the message buffer implementation, as message buffers
 | 
			
		||||
 * are built on top of stream buffers) assumes there is only one task or
 | 
			
		||||
 * interrupt that will write to the buffer (the writer), and only one task or
 | 
			
		||||
 * interrupt that will read from the buffer (the reader).  It is safe for the
 | 
			
		||||
 * writer and reader to be different tasks or interrupts, but, unlike other
 | 
			
		||||
 * FreeRTOS objects, it is not safe to have multiple different writers or
 | 
			
		||||
 * multiple different readers.  If there are to be multiple different writers
 | 
			
		||||
 * then the application writer must place each call to a writing API function
 | 
			
		||||
 * (such as xMessageBufferSend()) inside a critical section and set the send
 | 
			
		||||
 * block time to 0.  Likewise, if there are to be multiple different readers
 | 
			
		||||
 * then the application writer must place each call to a reading API function
 | 
			
		||||
 * (such as xMessageBufferRead()) inside a critical section and set the receive
 | 
			
		||||
 * block time to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferReceive() to read from a message buffer from a task.  Use
 | 
			
		||||
 * xMessageBufferReceiveFromISR() to read from a message buffer from an
 | 
			
		||||
 * interrupt service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferReceive() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer from which a message
 | 
			
		||||
 * is being received.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvRxData A pointer to the buffer into which the received message is
 | 
			
		||||
 * to be copied.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
 | 
			
		||||
 * parameter.  This sets the maximum length of the message that can be received.
 | 
			
		||||
 * If xBufferLengthBytes is too small to hold the next message then the message
 | 
			
		||||
 * will be left in the message buffer and 0 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xTicksToWait The maximum amount of time the task should remain in the
 | 
			
		||||
 * Blocked state to wait for a message, should the message buffer be empty.
 | 
			
		||||
 * xMessageBufferReceive() will return immediately if xTicksToWait is zero and
 | 
			
		||||
 * the message buffer is empty.  The block time is specified in tick periods, so
 | 
			
		||||
 * the absolute time it represents is dependent on the tick frequency.  The
 | 
			
		||||
 * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds
 | 
			
		||||
 * into a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will
 | 
			
		||||
 * cause the task to wait indefinitely (without timing out), provided
 | 
			
		||||
 * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
 | 
			
		||||
 * CPU time when they are in the Blocked state.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The length, in bytes, of the message read from the message buffer, if
 | 
			
		||||
 * any.  If xMessageBufferReceive() times out before a message became available
 | 
			
		||||
 * then zero is returned.  If the length of the message is greater than
 | 
			
		||||
 * xBufferLengthBytes then the message will be left in the message buffer and
 | 
			
		||||
 * zero is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * void vAFunction( MessageBuffer_t xMessageBuffer )
 | 
			
		||||
 * {
 | 
			
		||||
 * uint8_t ucRxData[ 20 ];
 | 
			
		||||
 * size_t xReceivedBytes;
 | 
			
		||||
 * const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
 | 
			
		||||
 *
 | 
			
		||||
 *  // Receive the next message from the message buffer.  Wait in the Blocked
 | 
			
		||||
 *  // state (so not using any CPU processing time) for a maximum of 100ms for
 | 
			
		||||
 *  // a message to become available.
 | 
			
		||||
 *  xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
 | 
			
		||||
 *                                          ( void * ) ucRxData,
 | 
			
		||||
 *                                          sizeof( ucRxData ),
 | 
			
		||||
 *                                          xBlockTime );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xReceivedBytes > 0 )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // A ucRxData contains a message that is xReceivedBytes long.  Process
 | 
			
		||||
 *      // the message here....
 | 
			
		||||
 *  }
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferReceive xMessageBufferReceive
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) \
 | 
			
		||||
    xStreamBufferReceive( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( xTicksToWait ) )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
 | 
			
		||||
 *                                      void *pvRxData,
 | 
			
		||||
 *                                      size_t xBufferLengthBytes,
 | 
			
		||||
 *                                      BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * An interrupt safe version of the API function that receives a discrete
 | 
			
		||||
 * message from a message buffer.  Messages can be of variable length and are
 | 
			
		||||
 * copied out of the buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
 | 
			
		||||
 * implementation (so also the message buffer implementation, as message buffers
 | 
			
		||||
 * are built on top of stream buffers) assumes there is only one task or
 | 
			
		||||
 * interrupt that will write to the buffer (the writer), and only one task or
 | 
			
		||||
 * interrupt that will read from the buffer (the reader).  It is safe for the
 | 
			
		||||
 * writer and reader to be different tasks or interrupts, but, unlike other
 | 
			
		||||
 * FreeRTOS objects, it is not safe to have multiple different writers or
 | 
			
		||||
 * multiple different readers.  If there are to be multiple different writers
 | 
			
		||||
 * then the application writer must place each call to a writing API function
 | 
			
		||||
 * (such as xMessageBufferSend()) inside a critical section and set the send
 | 
			
		||||
 * block time to 0.  Likewise, if there are to be multiple different readers
 | 
			
		||||
 * then the application writer must place each call to a reading API function
 | 
			
		||||
 * (such as xMessageBufferRead()) inside a critical section and set the receive
 | 
			
		||||
 * block time to 0.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferReceive() to read from a message buffer from a task.  Use
 | 
			
		||||
 * xMessageBufferReceiveFromISR() to read from a message buffer from an
 | 
			
		||||
 * interrupt service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferReceiveFromISR() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer from which a message
 | 
			
		||||
 * is being received.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvRxData A pointer to the buffer into which the received message is
 | 
			
		||||
 * to be copied.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData
 | 
			
		||||
 * parameter.  This sets the maximum length of the message that can be received.
 | 
			
		||||
 * If xBufferLengthBytes is too small to hold the next message then the message
 | 
			
		||||
 * will be left in the message buffer and 0 will be returned.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
 | 
			
		||||
 * have a task blocked on it waiting for space to become available.  Calling
 | 
			
		||||
 * xMessageBufferReceiveFromISR() can make space available, and so cause a task
 | 
			
		||||
 * that is waiting for space to leave the Blocked state.  If calling
 | 
			
		||||
 * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and
 | 
			
		||||
 * the unblocked task has a priority higher than the currently executing task
 | 
			
		||||
 * (the task that was interrupted), then, internally,
 | 
			
		||||
 * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE.
 | 
			
		||||
 * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a
 | 
			
		||||
 * context switch should be performed before the interrupt is exited.  That will
 | 
			
		||||
 * ensure the interrupt returns directly to the highest priority Ready state
 | 
			
		||||
 * task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it is
 | 
			
		||||
 * passed into the function.  See the code example below for an example.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The length, in bytes, of the message read from the message buffer, if
 | 
			
		||||
 * any.
 | 
			
		||||
 *
 | 
			
		||||
 * Example use:
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * // A message buffer that has already been created.
 | 
			
		||||
 * MessageBuffer_t xMessageBuffer;
 | 
			
		||||
 *
 | 
			
		||||
 * void vAnInterruptServiceRoutine( void )
 | 
			
		||||
 * {
 | 
			
		||||
 * uint8_t ucRxData[ 20 ];
 | 
			
		||||
 * size_t xReceivedBytes;
 | 
			
		||||
 * BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
 | 
			
		||||
 *
 | 
			
		||||
 *  // Receive the next message from the message buffer.
 | 
			
		||||
 *  xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
 | 
			
		||||
 *                                                ( void * ) ucRxData,
 | 
			
		||||
 *                                                sizeof( ucRxData ),
 | 
			
		||||
 *                                                &xHigherPriorityTaskWoken );
 | 
			
		||||
 *
 | 
			
		||||
 *  if( xReceivedBytes > 0 )
 | 
			
		||||
 *  {
 | 
			
		||||
 *      // A ucRxData contains a message that is xReceivedBytes long.  Process
 | 
			
		||||
 *      // the message here....
 | 
			
		||||
 *  }
 | 
			
		||||
 *
 | 
			
		||||
 *  // If xHigherPriorityTaskWoken was set to pdTRUE inside
 | 
			
		||||
 *  // xMessageBufferReceiveFromISR() then a task that has a priority above the
 | 
			
		||||
 *  // priority of the currently executing task was unblocked and a context
 | 
			
		||||
 *  // switch should be performed to ensure the ISR returns to the unblocked
 | 
			
		||||
 *  // task.  In most FreeRTOS ports this is done by simply passing
 | 
			
		||||
 *  // xHigherPriorityTaskWoken into portYIELD_FROM_ISR(), which will test the
 | 
			
		||||
 *  // variables value, and perform the context switch if necessary.  Check the
 | 
			
		||||
 *  // documentation for the port in use for port specific instructions.
 | 
			
		||||
 *  portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
 | 
			
		||||
 * }
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) \
 | 
			
		||||
    xStreamBufferReceiveFromISR( ( xMessageBuffer ), ( pvRxData ), ( xBufferLengthBytes ), ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Deletes a message buffer that was previously created using a call to
 | 
			
		||||
 * xMessageBufferCreate() or xMessageBufferCreateStatic().  If the message
 | 
			
		||||
 * buffer was created using dynamic memory (that is, by xMessageBufferCreate()),
 | 
			
		||||
 * then the allocated memory is freed.
 | 
			
		||||
 *
 | 
			
		||||
 * A message buffer handle must not be used after the message buffer has been
 | 
			
		||||
 * deleted.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * vMessageBufferDelete() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer to be deleted.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#define vMessageBufferDelete( xMessageBuffer ) \
 | 
			
		||||
    vStreamBufferDelete( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Tests to see if a message buffer is full.  A message buffer is full if it
 | 
			
		||||
 * cannot accept any more messages, of any size, until space is made available
 | 
			
		||||
 * by a message being removed from the message buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferIsFull() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the message buffer referenced by xMessageBuffer is full then
 | 
			
		||||
 * pdTRUE is returned.  Otherwise pdFALSE is returned.
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferIsFull( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferIsFull( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Tests to see if a message buffer is empty (does not contain any messages).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferIsEmpty() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the message buffer referenced by xMessageBuffer is empty then
 | 
			
		||||
 * pdTRUE is returned.  Otherwise pdFALSE is returned.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferIsEmpty( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferIsEmpty( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * Resets a message buffer to its initial empty state, discarding any message it
 | 
			
		||||
 * contained.
 | 
			
		||||
 *
 | 
			
		||||
 * A message buffer can only be reset if there are no tasks blocked on it.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferReset() to reset a message buffer from a task.
 | 
			
		||||
 * Use xMessageBufferResetFromISR() to reset a message buffer from an
 | 
			
		||||
 * interrupt service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferReset() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being reset.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the message buffer was reset then pdPASS is returned.  If the
 | 
			
		||||
 * message buffer could not be reset because either there was a task blocked on
 | 
			
		||||
 * the message queue to wait for space to become available, or to wait for a
 | 
			
		||||
 * a message to be available, then pdFAIL is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferReset xMessageBufferReset
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferReset( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferReset( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferResetFromISR( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * An interrupt safe version of the API function that resets the message buffer.
 | 
			
		||||
 * Resets a message buffer to its initial empty state, discarding any message it
 | 
			
		||||
 * contained.
 | 
			
		||||
 *
 | 
			
		||||
 * A message buffer can only be reset if there are no tasks blocked on it.
 | 
			
		||||
 *
 | 
			
		||||
 * Use xMessageBufferReset() to reset a message buffer from a task.
 | 
			
		||||
 * Use xMessageBufferResetFromISR() to reset a message buffer from an
 | 
			
		||||
 * interrupt service routine (ISR).
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferResetFromISR() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being reset.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If the message buffer was reset then pdPASS is returned.  If the
 | 
			
		||||
 * message buffer could not be reset because either there was a task blocked on
 | 
			
		||||
 * the message queue to wait for space to become available, or to wait for a
 | 
			
		||||
 * a message to be available, then pdFAIL is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferResetFromISR xMessageBufferResetFromISR
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferResetFromISR( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferResetFromISR( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * Returns the number of bytes of free space in the message buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferSpaceAvailable() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The number of bytes that can be written to the message buffer before
 | 
			
		||||
 * the message buffer would be full.  When a message is written to the message
 | 
			
		||||
 * buffer an additional sizeof( size_t ) bytes are also written to store the
 | 
			
		||||
 * message's length.  sizeof( size_t ) is typically 4 bytes on a 32-bit
 | 
			
		||||
 * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size
 | 
			
		||||
 * of the largest message that can be written to the message buffer is 6 bytes.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferSpacesAvailable( xMessageBuffer )
 | 
			
		||||
#define xMessageBufferSpacesAvailable( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferSpacesAvailable( xMessageBuffer ) /* Corrects typo in original macro name. */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 * Returns the length (in bytes) of the next message in a message buffer.
 | 
			
		||||
 * Useful if xMessageBufferReceive() returned 0 because the size of the buffer
 | 
			
		||||
 * passed into xMessageBufferReceive() was too small to hold the next message.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferNextLengthBytes() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the message buffer being queried.
 | 
			
		||||
 *
 | 
			
		||||
 * @return The length (in bytes) of the next message in the message buffer, or 0
 | 
			
		||||
 * if the message buffer is empty.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
 | 
			
		||||
 * \ingroup MessageBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferNextLengthBytes( xMessageBuffer ) \
 | 
			
		||||
    xStreamBufferNextMessageLengthBytes( xMessageBuffer )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * For advanced users only.
 | 
			
		||||
 *
 | 
			
		||||
 * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when
 | 
			
		||||
 * data is sent to a message buffer or stream buffer.  If there was a task that
 | 
			
		||||
 * was blocked on the message or stream buffer waiting for data to arrive then
 | 
			
		||||
 * the sbSEND_COMPLETED() macro sends a notification to the task to remove it
 | 
			
		||||
 * from the Blocked state.  xMessageBufferSendCompletedFromISR() does the same
 | 
			
		||||
 * thing.  It is provided to enable application writers to implement their own
 | 
			
		||||
 * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME.
 | 
			
		||||
 *
 | 
			
		||||
 * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
 | 
			
		||||
 * additional information.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferSendCompletedFromISR() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the stream buffer to which data was
 | 
			
		||||
 * written.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
 | 
			
		||||
 * initialised to pdFALSE before it is passed into
 | 
			
		||||
 * xMessageBufferSendCompletedFromISR().  If calling
 | 
			
		||||
 * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state,
 | 
			
		||||
 * and the task has a priority above the priority of the currently running task,
 | 
			
		||||
 * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
 | 
			
		||||
 * context switch should be performed before exiting the ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If a task was removed from the Blocked state then pdTRUE is returned.
 | 
			
		||||
 * Otherwise pdFALSE is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR
 | 
			
		||||
 * \ingroup StreamBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
 | 
			
		||||
    xStreamBufferSendCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * message_buffer.h
 | 
			
		||||
 *
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xMessageBuffer, BaseType_t *pxHigherPriorityTaskWoken );
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * For advanced users only.
 | 
			
		||||
 *
 | 
			
		||||
 * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when
 | 
			
		||||
 * data is read out of a message buffer or stream buffer.  If there was a task
 | 
			
		||||
 * that was blocked on the message or stream buffer waiting for data to arrive
 | 
			
		||||
 * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to
 | 
			
		||||
 * remove it from the Blocked state.  xMessageBufferReceiveCompletedFromISR()
 | 
			
		||||
 * does the same thing.  It is provided to enable application writers to
 | 
			
		||||
 * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT
 | 
			
		||||
 * ANY OTHER TIME.
 | 
			
		||||
 *
 | 
			
		||||
 * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for
 | 
			
		||||
 * additional information.
 | 
			
		||||
 *
 | 
			
		||||
 * configUSE_STREAM_BUFFERS must be set to 1 in for FreeRTOSConfig.h for
 | 
			
		||||
 * xMessageBufferReceiveCompletedFromISR() to be available.
 | 
			
		||||
 *
 | 
			
		||||
 * @param xMessageBuffer The handle of the stream buffer from which data was
 | 
			
		||||
 * read.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be
 | 
			
		||||
 * initialised to pdFALSE before it is passed into
 | 
			
		||||
 * xMessageBufferReceiveCompletedFromISR().  If calling
 | 
			
		||||
 * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state,
 | 
			
		||||
 * and the task has a priority above the priority of the currently running task,
 | 
			
		||||
 * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a
 | 
			
		||||
 * context switch should be performed before exiting the ISR.
 | 
			
		||||
 *
 | 
			
		||||
 * @return If a task was removed from the Blocked state then pdTRUE is returned.
 | 
			
		||||
 * Otherwise pdFALSE is returned.
 | 
			
		||||
 *
 | 
			
		||||
 * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR
 | 
			
		||||
 * \ingroup StreamBufferManagement
 | 
			
		||||
 */
 | 
			
		||||
#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) \
 | 
			
		||||
    xStreamBufferReceiveCompletedFromISR( ( xMessageBuffer ), ( pxHigherPriorityTaskWoken ) )
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#if defined( __cplusplus )
 | 
			
		||||
    } /* extern "C" */
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */
 | 
			
		||||
							
								
								
									
										389
									
								
								include/mpu_prototypes.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										389
									
								
								include/mpu_prototypes.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,389 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * When the MPU is used the standard (non MPU) API functions are mapped to
 | 
			
		||||
 * equivalents that start "MPU_", the prototypes for which are defined in this
 | 
			
		||||
 * header files.  This will cause the application code to call the MPU_ version
 | 
			
		||||
 * which wraps the non-MPU version with privilege promoting then demoting code,
 | 
			
		||||
 * so the kernel code always runs will full privileges.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef MPU_PROTOTYPES_H
 | 
			
		||||
#define MPU_PROTOTYPES_H
 | 
			
		||||
 | 
			
		||||
typedef struct xTaskGenericNotifyParams
 | 
			
		||||
{
 | 
			
		||||
    TaskHandle_t xTaskToNotify;
 | 
			
		||||
    UBaseType_t uxIndexToNotify;
 | 
			
		||||
    uint32_t ulValue;
 | 
			
		||||
    eNotifyAction eAction;
 | 
			
		||||
    uint32_t * pulPreviousNotificationValue;
 | 
			
		||||
} xTaskGenericNotifyParams_t;
 | 
			
		||||
 | 
			
		||||
typedef struct xTaskGenericNotifyWaitParams
 | 
			
		||||
{
 | 
			
		||||
    UBaseType_t uxIndexToWaitOn;
 | 
			
		||||
    uint32_t ulBitsToClearOnEntry;
 | 
			
		||||
    uint32_t ulBitsToClearOnExit;
 | 
			
		||||
    uint32_t * pulNotificationValue;
 | 
			
		||||
    TickType_t xTicksToWait;
 | 
			
		||||
} xTaskGenericNotifyWaitParams_t;
 | 
			
		||||
 | 
			
		||||
typedef struct xTimerGenericCommandFromTaskParams
 | 
			
		||||
{
 | 
			
		||||
    TimerHandle_t xTimer;
 | 
			
		||||
    BaseType_t xCommandID;
 | 
			
		||||
    TickType_t xOptionalValue;
 | 
			
		||||
    BaseType_t * pxHigherPriorityTaskWoken;
 | 
			
		||||
    TickType_t xTicksToWait;
 | 
			
		||||
} xTimerGenericCommandFromTaskParams_t;
 | 
			
		||||
 | 
			
		||||
typedef struct xEventGroupWaitBitsParams
 | 
			
		||||
{
 | 
			
		||||
    EventGroupHandle_t xEventGroup;
 | 
			
		||||
    EventBits_t uxBitsToWaitFor;
 | 
			
		||||
    BaseType_t xClearOnExit;
 | 
			
		||||
    BaseType_t xWaitForAllBits;
 | 
			
		||||
    TickType_t xTicksToWait;
 | 
			
		||||
} xEventGroupWaitBitsParams_t;
 | 
			
		||||
 | 
			
		||||
/* MPU versions of task.h API functions. */
 | 
			
		||||
void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
 | 
			
		||||
                                const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskGetInfo( TaskHandle_t xTask,
 | 
			
		||||
                       TaskStatus_t * pxTaskStatus,
 | 
			
		||||
                       BaseType_t xGetFreeStackSpace,
 | 
			
		||||
                       eTaskState eState ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask,
 | 
			
		||||
                                     TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet,
 | 
			
		||||
                                            BaseType_t xIndex,
 | 
			
		||||
                                            void * pvValue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery,
 | 
			
		||||
                                               BaseType_t xIndex ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray,
 | 
			
		||||
                                      const UBaseType_t uxArraySize,
 | 
			
		||||
                                      configRUN_TIME_COUNTER_TYPE * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimeCounter( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetRunTimePercent( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
configRUN_TIME_COUNTER_TYPE MPU_ulTaskGetIdleRunTimePercent( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify,
 | 
			
		||||
                                   UBaseType_t uxIndexToNotify,
 | 
			
		||||
                                   uint32_t ulValue,
 | 
			
		||||
                                   eNotifyAction eAction,
 | 
			
		||||
                                   uint32_t * pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotifyEntry( const xTaskGenericNotifyParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotifyWait( UBaseType_t uxIndexToWaitOn,
 | 
			
		||||
                                       uint32_t ulBitsToClearOnEntry,
 | 
			
		||||
                                       uint32_t ulBitsToClearOnExit,
 | 
			
		||||
                                       uint32_t * pulNotificationValue,
 | 
			
		||||
                                       TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotifyWaitEntry( const xTaskGenericNotifyWaitParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
uint32_t MPU_ulTaskGenericNotifyTake( UBaseType_t uxIndexToWaitOn,
 | 
			
		||||
                                      BaseType_t xClearCountOnExit,
 | 
			
		||||
                                      TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotifyStateClear( TaskHandle_t xTask,
 | 
			
		||||
                                             UBaseType_t uxIndexToClear ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
uint32_t MPU_ulTaskGenericNotifyValueClear( TaskHandle_t xTask,
 | 
			
		||||
                                            UBaseType_t uxIndexToClear,
 | 
			
		||||
                                            uint32_t ulBitsToClear ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut,
 | 
			
		||||
                                     TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Task APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode,
 | 
			
		||||
                            const char * const pcName,
 | 
			
		||||
                            const configSTACK_DEPTH_TYPE uxStackDepth,
 | 
			
		||||
                            void * const pvParameters,
 | 
			
		||||
                            UBaseType_t uxPriority,
 | 
			
		||||
                            TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode,
 | 
			
		||||
                                    const char * const pcName,
 | 
			
		||||
                                    const configSTACK_DEPTH_TYPE uxStackDepth,
 | 
			
		||||
                                    void * const pvParameters,
 | 
			
		||||
                                    UBaseType_t uxPriority,
 | 
			
		||||
                                    StackType_t * const puxStackBuffer,
 | 
			
		||||
                                    StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vTaskPrioritySet( TaskHandle_t xTask,
 | 
			
		||||
                           UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION;
 | 
			
		||||
TaskHandle_t MPU_xTaskGetHandle( const char * pcNameToQuery ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask,
 | 
			
		||||
                                             void * pvParameter ) PRIVILEGED_FUNCTION;
 | 
			
		||||
char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition,
 | 
			
		||||
                                      TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition,
 | 
			
		||||
                                            TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vTaskAllocateMPURegions( TaskHandle_t xTaskToModify,
 | 
			
		||||
                                  const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskGetStaticBuffers( TaskHandle_t xTask,
 | 
			
		||||
                                      StackType_t ** ppuxStackBuffer,
 | 
			
		||||
                                      StaticTask_t ** ppxTaskBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
UBaseType_t MPU_uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
UBaseType_t MPU_uxTaskBasePriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
UBaseType_t MPU_uxTaskBasePriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION;
 | 
			
		||||
TaskHookFunction_t MPU_xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify,
 | 
			
		||||
                                          UBaseType_t uxIndexToNotify,
 | 
			
		||||
                                          uint32_t ulValue,
 | 
			
		||||
                                          eNotifyAction eAction,
 | 
			
		||||
                                          uint32_t * pulPreviousNotificationValue,
 | 
			
		||||
                                          BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vTaskGenericNotifyGiveFromISR( TaskHandle_t xTaskToNotify,
 | 
			
		||||
                                        UBaseType_t uxIndexToNotify,
 | 
			
		||||
                                        BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* MPU versions of queue.h API functions. */
 | 
			
		||||
BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue,
 | 
			
		||||
                                  const void * const pvItemToQueue,
 | 
			
		||||
                                  TickType_t xTicksToWait,
 | 
			
		||||
                                  const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue,
 | 
			
		||||
                              void * const pvBuffer,
 | 
			
		||||
                              TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue,
 | 
			
		||||
                           void * const pvBuffer,
 | 
			
		||||
                           TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue,
 | 
			
		||||
                                    TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex,
 | 
			
		||||
                                         TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vQueueAddToRegistry( QueueHandle_t xQueue,
 | 
			
		||||
                              const char * pcName ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore,
 | 
			
		||||
                               QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet,
 | 
			
		||||
                                                const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue,
 | 
			
		||||
                               UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Queue APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
void MPU_vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType,
 | 
			
		||||
                                           StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount,
 | 
			
		||||
                                                 const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount,
 | 
			
		||||
                                                       const UBaseType_t uxInitialCount,
 | 
			
		||||
                                                       StaticQueue_t * pxStaticQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength,
 | 
			
		||||
                                       const UBaseType_t uxItemSize,
 | 
			
		||||
                                       const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength,
 | 
			
		||||
                                             const UBaseType_t uxItemSize,
 | 
			
		||||
                                             uint8_t * pucQueueStorage,
 | 
			
		||||
                                             StaticQueue_t * pxStaticQueue,
 | 
			
		||||
                                             const uint8_t ucQueueType ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore,
 | 
			
		||||
                                    QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue,
 | 
			
		||||
                                   BaseType_t xNewQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueGenericGetStaticBuffers( QueueHandle_t xQueue,
 | 
			
		||||
                                              uint8_t ** ppucQueueStorage,
 | 
			
		||||
                                              StaticQueue_t ** ppxStaticQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueGenericSendFromISR( QueueHandle_t xQueue,
 | 
			
		||||
                                         const void * const pvItemToQueue,
 | 
			
		||||
                                         BaseType_t * const pxHigherPriorityTaskWoken,
 | 
			
		||||
                                         const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueGiveFromISR( QueueHandle_t xQueue,
 | 
			
		||||
                                  BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueuePeekFromISR( QueueHandle_t xQueue,
 | 
			
		||||
                                  void * const pvBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueReceiveFromISR( QueueHandle_t xQueue,
 | 
			
		||||
                                     void * const pvBuffer,
 | 
			
		||||
                                     BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
UBaseType_t MPU_uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
 | 
			
		||||
TaskHandle_t MPU_xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION;
 | 
			
		||||
QueueSetMemberHandle_t MPU_xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* MPU versions of timers.h API functions. */
 | 
			
		||||
void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTimerSetTimerID( TimerHandle_t xTimer,
 | 
			
		||||
                           void * pvNewID ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTimerGenericCommandFromTask( TimerHandle_t xTimer,
 | 
			
		||||
                                             const BaseType_t xCommandID,
 | 
			
		||||
                                             const TickType_t xOptionalValue,
 | 
			
		||||
                                             BaseType_t * const pxHigherPriorityTaskWoken,
 | 
			
		||||
                                             const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTimerGenericCommandFromTaskEntry( const xTimerGenericCommandFromTaskParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
void MPU_vTimerSetReloadMode( TimerHandle_t xTimer,
 | 
			
		||||
                              const BaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
UBaseType_t MPU_uxTimerGetReloadMode( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Timer APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName,
 | 
			
		||||
                                const TickType_t xTimerPeriodInTicks,
 | 
			
		||||
                                const UBaseType_t uxAutoReload,
 | 
			
		||||
                                void * const pvTimerID,
 | 
			
		||||
                                TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION;
 | 
			
		||||
TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName,
 | 
			
		||||
                                      const TickType_t xTimerPeriodInTicks,
 | 
			
		||||
                                      const UBaseType_t uxAutoReload,
 | 
			
		||||
                                      void * const pvTimerID,
 | 
			
		||||
                                      TimerCallbackFunction_t pxCallbackFunction,
 | 
			
		||||
                                      StaticTimer_t * pxTimerBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTimerGetStaticBuffer( TimerHandle_t xTimer,
 | 
			
		||||
                                      StaticTimer_t ** ppxTimerBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xTimerGenericCommandFromISR( TimerHandle_t xTimer,
 | 
			
		||||
                                            const BaseType_t xCommandID,
 | 
			
		||||
                                            const TickType_t xOptionalValue,
 | 
			
		||||
                                            BaseType_t * const pxHigherPriorityTaskWoken,
 | 
			
		||||
                                            const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* MPU versions of event_group.h API functions. */
 | 
			
		||||
EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                     const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                     const BaseType_t xClearOnExit,
 | 
			
		||||
                                     const BaseType_t xWaitForAllBits,
 | 
			
		||||
                                     TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
EventBits_t MPU_xEventGroupWaitBitsEntry( const xEventGroupWaitBitsParams_t * pxParams ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                      const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                    const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                 const EventBits_t uxBitsToSet,
 | 
			
		||||
                                 const EventBits_t uxBitsToWaitFor,
 | 
			
		||||
                                 TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
#if ( configUSE_TRACE_FACILITY == 1 )
 | 
			
		||||
    UBaseType_t MPU_uxEventGroupGetNumber( void * xEventGroup ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
    void MPU_vEventGroupSetNumber( void * xEventGroup,
 | 
			
		||||
                                   UBaseType_t uxEventGroupNumber ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
#endif /* ( configUSE_TRACE_FACILITY == 1 )*/
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Event Group APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
EventGroupHandle_t MPU_xEventGroupCreate( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t * pxEventGroupBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                           StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                            const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup,
 | 
			
		||||
                                          const EventBits_t uxBitsToSet,
 | 
			
		||||
                                          BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/* MPU versions of message/stream_buffer.h API functions. */
 | 
			
		||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                              const void * pvTxData,
 | 
			
		||||
                              size_t xDataLengthBytes,
 | 
			
		||||
                              TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                 void * pvRxData,
 | 
			
		||||
                                 size_t xBufferLengthBytes,
 | 
			
		||||
                                 TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                             size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL;
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes,
 | 
			
		||||
                                                     size_t xTriggerLevelBytes,
 | 
			
		||||
                                                     BaseType_t xStreamBufferType,
 | 
			
		||||
                                                     StreamBufferCallbackFunction_t pxSendCompletedCallback,
 | 
			
		||||
                                                     StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
 | 
			
		||||
StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
 | 
			
		||||
                                                           size_t xTriggerLevelBytes,
 | 
			
		||||
                                                           BaseType_t xStreamBufferType,
 | 
			
		||||
                                                           uint8_t * const pucStreamBufferStorageArea,
 | 
			
		||||
                                                           StaticStreamBuffer_t * const pxStaticStreamBuffer,
 | 
			
		||||
                                                           StreamBufferCallbackFunction_t pxSendCompletedCallback,
 | 
			
		||||
                                                           StreamBufferCallbackFunction_t pxReceiveCompletedCallback ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xStreamBufferGetStaticBuffers( StreamBufferHandle_t xStreamBuffers,
 | 
			
		||||
                                              uint8_t * ppucStreamBufferStorageArea,
 | 
			
		||||
                                              StaticStreamBuffer_t * ppxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                     const void * pvTxData,
 | 
			
		||||
                                     size_t xDataLengthBytes,
 | 
			
		||||
                                     BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                        void * pvRxData,
 | 
			
		||||
                                        size_t xBufferLengthBytes,
 | 
			
		||||
                                        BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                                  BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer,
 | 
			
		||||
                                                     BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
 | 
			
		||||
BaseType_t MPU_xStreamBufferResetFromISR( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
#endif /* MPU_PROTOTYPES_H */
 | 
			
		||||
							
								
								
									
										105
									
								
								include/mpu_syscall_numbers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								include/mpu_syscall_numbers.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MPU_SYSCALL_NUMBERS_H
 | 
			
		||||
#define MPU_SYSCALL_NUMBERS_H
 | 
			
		||||
 | 
			
		||||
/* Numbers assigned to various system calls. */
 | 
			
		||||
#define SYSTEM_CALL_xTaskGenericNotify                     0
 | 
			
		||||
#define SYSTEM_CALL_xTaskGenericNotifyWait                 1
 | 
			
		||||
#define SYSTEM_CALL_xTimerGenericCommandFromTask           2
 | 
			
		||||
#define SYSTEM_CALL_xEventGroupWaitBits                    3
 | 
			
		||||
#define SYSTEM_CALL_xTaskDelayUntil                        4
 | 
			
		||||
#define SYSTEM_CALL_xTaskAbortDelay                        5
 | 
			
		||||
#define SYSTEM_CALL_vTaskDelay                             6
 | 
			
		||||
#define SYSTEM_CALL_uxTaskPriorityGet                      7
 | 
			
		||||
#define SYSTEM_CALL_eTaskGetState                          8
 | 
			
		||||
#define SYSTEM_CALL_vTaskGetInfo                           9
 | 
			
		||||
#define SYSTEM_CALL_xTaskGetIdleTaskHandle                 10
 | 
			
		||||
#define SYSTEM_CALL_vTaskSuspend                           11
 | 
			
		||||
#define SYSTEM_CALL_vTaskResume                            12
 | 
			
		||||
#define SYSTEM_CALL_xTaskGetTickCount                      13
 | 
			
		||||
#define SYSTEM_CALL_uxTaskGetNumberOfTasks                 14
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGetRunTimeCounter                15
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGetRunTimePercent                16
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGetIdleRunTimePercent            17
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGetIdleRunTimeCounter            18
 | 
			
		||||
#define SYSTEM_CALL_vTaskSetApplicationTaskTag             19
 | 
			
		||||
#define SYSTEM_CALL_xTaskGetApplicationTaskTag             20
 | 
			
		||||
#define SYSTEM_CALL_vTaskSetThreadLocalStoragePointer      21
 | 
			
		||||
#define SYSTEM_CALL_pvTaskGetThreadLocalStoragePointer     22
 | 
			
		||||
#define SYSTEM_CALL_uxTaskGetSystemState                   23
 | 
			
		||||
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark            24
 | 
			
		||||
#define SYSTEM_CALL_uxTaskGetStackHighWaterMark2           25
 | 
			
		||||
#define SYSTEM_CALL_xTaskGetCurrentTaskHandle              26
 | 
			
		||||
#define SYSTEM_CALL_xTaskGetSchedulerState                 27
 | 
			
		||||
#define SYSTEM_CALL_vTaskSetTimeOutState                   28
 | 
			
		||||
#define SYSTEM_CALL_xTaskCheckForTimeOut                   29
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGenericNotifyTake                30
 | 
			
		||||
#define SYSTEM_CALL_xTaskGenericNotifyStateClear           31
 | 
			
		||||
#define SYSTEM_CALL_ulTaskGenericNotifyValueClear          32
 | 
			
		||||
#define SYSTEM_CALL_xQueueGenericSend                      33
 | 
			
		||||
#define SYSTEM_CALL_uxQueueMessagesWaiting                 34
 | 
			
		||||
#define SYSTEM_CALL_uxQueueSpacesAvailable                 35
 | 
			
		||||
#define SYSTEM_CALL_xQueueReceive                          36
 | 
			
		||||
#define SYSTEM_CALL_xQueuePeek                             37
 | 
			
		||||
#define SYSTEM_CALL_xQueueSemaphoreTake                    38
 | 
			
		||||
#define SYSTEM_CALL_xQueueGetMutexHolder                   39
 | 
			
		||||
#define SYSTEM_CALL_xQueueTakeMutexRecursive               40
 | 
			
		||||
#define SYSTEM_CALL_xQueueGiveMutexRecursive               41
 | 
			
		||||
#define SYSTEM_CALL_xQueueSelectFromSet                    42
 | 
			
		||||
#define SYSTEM_CALL_xQueueAddToSet                         43
 | 
			
		||||
#define SYSTEM_CALL_vQueueAddToRegistry                    44
 | 
			
		||||
#define SYSTEM_CALL_vQueueUnregisterQueue                  45
 | 
			
		||||
#define SYSTEM_CALL_pcQueueGetName                         46
 | 
			
		||||
#define SYSTEM_CALL_pvTimerGetTimerID                      47
 | 
			
		||||
#define SYSTEM_CALL_vTimerSetTimerID                       48
 | 
			
		||||
#define SYSTEM_CALL_xTimerIsTimerActive                    49
 | 
			
		||||
#define SYSTEM_CALL_xTimerGetTimerDaemonTaskHandle         50
 | 
			
		||||
#define SYSTEM_CALL_pcTimerGetName                         51
 | 
			
		||||
#define SYSTEM_CALL_vTimerSetReloadMode                    52
 | 
			
		||||
#define SYSTEM_CALL_xTimerGetReloadMode                    53
 | 
			
		||||
#define SYSTEM_CALL_uxTimerGetReloadMode                   54
 | 
			
		||||
#define SYSTEM_CALL_xTimerGetPeriod                        55
 | 
			
		||||
#define SYSTEM_CALL_xTimerGetExpiryTime                    56
 | 
			
		||||
#define SYSTEM_CALL_xEventGroupClearBits                   57
 | 
			
		||||
#define SYSTEM_CALL_xEventGroupSetBits                     58
 | 
			
		||||
#define SYSTEM_CALL_xEventGroupSync                        59
 | 
			
		||||
#define SYSTEM_CALL_uxEventGroupGetNumber                  60
 | 
			
		||||
#define SYSTEM_CALL_vEventGroupSetNumber                   61
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferSend                      62
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferReceive                   63
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferIsFull                    64
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferIsEmpty                   65
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferSpacesAvailable           66
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferBytesAvailable            67
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferSetTriggerLevel           68
 | 
			
		||||
#define SYSTEM_CALL_xStreamBufferNextMessageLengthBytes    69
 | 
			
		||||
#define NUM_SYSTEM_CALLS                                   70  /* Total number of system calls. */
 | 
			
		||||
 | 
			
		||||
#endif /* MPU_SYSCALL_NUMBERS_H */
 | 
			
		||||
							
								
								
									
										276
									
								
								include/mpu_wrappers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										276
									
								
								include/mpu_wrappers.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,276 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef MPU_WRAPPERS_H
 | 
			
		||||
#define MPU_WRAPPERS_H
 | 
			
		||||
 | 
			
		||||
/* This file redefines API functions to be called through a wrapper macro, but
 | 
			
		||||
 * only for ports that are using the MPU. */
 | 
			
		||||
#if ( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
 | 
			
		||||
/* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is
 | 
			
		||||
 * included from queue.c or task.c to prevent it from having an effect within
 | 
			
		||||
 * those files. */
 | 
			
		||||
    #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Map standard (non MPU) API functions to equivalents that start
 | 
			
		||||
 * "MPU_".  This will cause the application code to call the MPU_
 | 
			
		||||
 * version, which wraps the non-MPU version with privilege promoting
 | 
			
		||||
 * then demoting code, so the kernel code always runs will full
 | 
			
		||||
 * privileges.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Map standard task.h API functions to the MPU equivalents. */
 | 
			
		||||
        #define vTaskDelay                            MPU_vTaskDelay
 | 
			
		||||
        #define xTaskDelayUntil                       MPU_xTaskDelayUntil
 | 
			
		||||
        #define xTaskAbortDelay                       MPU_xTaskAbortDelay
 | 
			
		||||
        #define uxTaskPriorityGet                     MPU_uxTaskPriorityGet
 | 
			
		||||
        #define eTaskGetState                         MPU_eTaskGetState
 | 
			
		||||
        #define vTaskGetInfo                          MPU_vTaskGetInfo
 | 
			
		||||
        #define vTaskSuspend                          MPU_vTaskSuspend
 | 
			
		||||
        #define vTaskResume                           MPU_vTaskResume
 | 
			
		||||
        #define xTaskGetTickCount                     MPU_xTaskGetTickCount
 | 
			
		||||
        #define uxTaskGetNumberOfTasks                MPU_uxTaskGetNumberOfTasks
 | 
			
		||||
        #define uxTaskGetStackHighWaterMark           MPU_uxTaskGetStackHighWaterMark
 | 
			
		||||
        #define uxTaskGetStackHighWaterMark2          MPU_uxTaskGetStackHighWaterMark2
 | 
			
		||||
        #define vTaskSetApplicationTaskTag            MPU_vTaskSetApplicationTaskTag
 | 
			
		||||
        #define xTaskGetApplicationTaskTag            MPU_xTaskGetApplicationTaskTag
 | 
			
		||||
        #define vTaskSetThreadLocalStoragePointer     MPU_vTaskSetThreadLocalStoragePointer
 | 
			
		||||
        #define pvTaskGetThreadLocalStoragePointer    MPU_pvTaskGetThreadLocalStoragePointer
 | 
			
		||||
        #define xTaskGetIdleTaskHandle                MPU_xTaskGetIdleTaskHandle
 | 
			
		||||
        #define uxTaskGetSystemState                  MPU_uxTaskGetSystemState
 | 
			
		||||
        #define ulTaskGetIdleRunTimeCounter           MPU_ulTaskGetIdleRunTimeCounter
 | 
			
		||||
        #define ulTaskGetIdleRunTimePercent           MPU_ulTaskGetIdleRunTimePercent
 | 
			
		||||
        #define xTaskGenericNotify                    MPU_xTaskGenericNotify
 | 
			
		||||
        #define xTaskGenericNotifyWait                MPU_xTaskGenericNotifyWait
 | 
			
		||||
        #define ulTaskGenericNotifyTake               MPU_ulTaskGenericNotifyTake
 | 
			
		||||
        #define xTaskGenericNotifyStateClear          MPU_xTaskGenericNotifyStateClear
 | 
			
		||||
        #define ulTaskGenericNotifyValueClear         MPU_ulTaskGenericNotifyValueClear
 | 
			
		||||
        #define vTaskSetTimeOutState                  MPU_vTaskSetTimeOutState
 | 
			
		||||
        #define xTaskCheckForTimeOut                  MPU_xTaskCheckForTimeOut
 | 
			
		||||
        #define xTaskGetCurrentTaskHandle             MPU_xTaskGetCurrentTaskHandle
 | 
			
		||||
        #define xTaskGetSchedulerState                MPU_xTaskGetSchedulerState
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define ulTaskGetRunTimeCounter           MPU_ulTaskGetRunTimeCounter
 | 
			
		||||
            #define ulTaskGetRunTimePercent           MPU_ulTaskGetRunTimePercent
 | 
			
		||||
        #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Task APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
        #define xTaskCreate                              MPU_xTaskCreate
 | 
			
		||||
        #define xTaskCreateStatic                        MPU_xTaskCreateStatic
 | 
			
		||||
        #define vTaskDelete                              MPU_vTaskDelete
 | 
			
		||||
        #define vTaskPrioritySet                         MPU_vTaskPrioritySet
 | 
			
		||||
        #define xTaskGetHandle                           MPU_xTaskGetHandle
 | 
			
		||||
        #define xTaskCallApplicationTaskHook             MPU_xTaskCallApplicationTaskHook
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define pcTaskGetName                        MPU_pcTaskGetName
 | 
			
		||||
            #define xTaskCreateRestricted                MPU_xTaskCreateRestricted
 | 
			
		||||
            #define xTaskCreateRestrictedStatic          MPU_xTaskCreateRestrictedStatic
 | 
			
		||||
            #define vTaskAllocateMPURegions              MPU_vTaskAllocateMPURegions
 | 
			
		||||
            #define xTaskGetStaticBuffers                MPU_xTaskGetStaticBuffers
 | 
			
		||||
            #define uxTaskPriorityGetFromISR             MPU_uxTaskPriorityGetFromISR
 | 
			
		||||
            #define uxTaskBasePriorityGet                MPU_uxTaskBasePriorityGet
 | 
			
		||||
            #define uxTaskBasePriorityGetFromISR         MPU_uxTaskBasePriorityGetFromISR
 | 
			
		||||
            #define xTaskResumeFromISR                   MPU_xTaskResumeFromISR
 | 
			
		||||
            #define xTaskGetApplicationTaskTagFromISR    MPU_xTaskGetApplicationTaskTagFromISR
 | 
			
		||||
            #define xTaskGenericNotifyFromISR            MPU_xTaskGenericNotifyFromISR
 | 
			
		||||
            #define vTaskGenericNotifyGiveFromISR        MPU_vTaskGenericNotifyGiveFromISR
 | 
			
		||||
        #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Map standard queue.h API functions to the MPU equivalents. */
 | 
			
		||||
        #define xQueueGenericSend            MPU_xQueueGenericSend
 | 
			
		||||
        #define xQueueReceive                MPU_xQueueReceive
 | 
			
		||||
        #define xQueuePeek                   MPU_xQueuePeek
 | 
			
		||||
        #define xQueueSemaphoreTake          MPU_xQueueSemaphoreTake
 | 
			
		||||
        #define uxQueueMessagesWaiting       MPU_uxQueueMessagesWaiting
 | 
			
		||||
        #define uxQueueSpacesAvailable       MPU_uxQueueSpacesAvailable
 | 
			
		||||
        #define xQueueGetMutexHolder         MPU_xQueueGetMutexHolder
 | 
			
		||||
        #define xQueueTakeMutexRecursive     MPU_xQueueTakeMutexRecursive
 | 
			
		||||
        #define xQueueGiveMutexRecursive     MPU_xQueueGiveMutexRecursive
 | 
			
		||||
        #define xQueueAddToSet               MPU_xQueueAddToSet
 | 
			
		||||
        #define xQueueSelectFromSet          MPU_xQueueSelectFromSet
 | 
			
		||||
 | 
			
		||||
        #if ( configQUEUE_REGISTRY_SIZE > 0 )
 | 
			
		||||
            #define vQueueAddToRegistry      MPU_vQueueAddToRegistry
 | 
			
		||||
            #define vQueueUnregisterQueue    MPU_vQueueUnregisterQueue
 | 
			
		||||
            #define pcQueueGetName           MPU_pcQueueGetName
 | 
			
		||||
        #endif /* #if ( configQUEUE_REGISTRY_SIZE > 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Queue APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
        #define vQueueDelete                           MPU_vQueueDelete
 | 
			
		||||
        #define xQueueCreateMutex                      MPU_xQueueCreateMutex
 | 
			
		||||
        #define xQueueCreateMutexStatic                MPU_xQueueCreateMutexStatic
 | 
			
		||||
        #define xQueueCreateCountingSemaphore          MPU_xQueueCreateCountingSemaphore
 | 
			
		||||
        #define xQueueCreateCountingSemaphoreStatic    MPU_xQueueCreateCountingSemaphoreStatic
 | 
			
		||||
        #define xQueueGenericCreate                    MPU_xQueueGenericCreate
 | 
			
		||||
        #define xQueueGenericCreateStatic              MPU_xQueueGenericCreateStatic
 | 
			
		||||
        #define xQueueGenericReset                     MPU_xQueueGenericReset
 | 
			
		||||
        #define xQueueCreateSet                        MPU_xQueueCreateSet
 | 
			
		||||
        #define xQueueRemoveFromSet                    MPU_xQueueRemoveFromSet
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define xQueueGenericGetStaticBuffers      MPU_xQueueGenericGetStaticBuffers
 | 
			
		||||
            #define xQueueGenericSendFromISR           MPU_xQueueGenericSendFromISR
 | 
			
		||||
            #define xQueueGiveFromISR                  MPU_xQueueGiveFromISR
 | 
			
		||||
            #define xQueuePeekFromISR                  MPU_xQueuePeekFromISR
 | 
			
		||||
            #define xQueueReceiveFromISR               MPU_xQueueReceiveFromISR
 | 
			
		||||
            #define xQueueIsQueueEmptyFromISR          MPU_xQueueIsQueueEmptyFromISR
 | 
			
		||||
            #define xQueueIsQueueFullFromISR           MPU_xQueueIsQueueFullFromISR
 | 
			
		||||
            #define uxQueueMessagesWaitingFromISR      MPU_uxQueueMessagesWaitingFromISR
 | 
			
		||||
            #define xQueueGetMutexHolderFromISR        MPU_xQueueGetMutexHolderFromISR
 | 
			
		||||
            #define xQueueSelectFromSetFromISR         MPU_xQueueSelectFromSetFromISR
 | 
			
		||||
        #endif /* if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Map standard timer.h API functions to the MPU equivalents. */
 | 
			
		||||
        #define pvTimerGetTimerID                 MPU_pvTimerGetTimerID
 | 
			
		||||
        #define vTimerSetTimerID                  MPU_vTimerSetTimerID
 | 
			
		||||
        #define xTimerIsTimerActive               MPU_xTimerIsTimerActive
 | 
			
		||||
        #define xTimerGetTimerDaemonTaskHandle    MPU_xTimerGetTimerDaemonTaskHandle
 | 
			
		||||
        #define xTimerGenericCommandFromTask      MPU_xTimerGenericCommandFromTask
 | 
			
		||||
        #define pcTimerGetName                    MPU_pcTimerGetName
 | 
			
		||||
        #define vTimerSetReloadMode               MPU_vTimerSetReloadMode
 | 
			
		||||
        #define uxTimerGetReloadMode              MPU_uxTimerGetReloadMode
 | 
			
		||||
        #define xTimerGetPeriod                   MPU_xTimerGetPeriod
 | 
			
		||||
        #define xTimerGetExpiryTime               MPU_xTimerGetExpiryTime
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Timer APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define xTimerGetReloadMode            MPU_xTimerGetReloadMode
 | 
			
		||||
            #define xTimerCreate                   MPU_xTimerCreate
 | 
			
		||||
            #define xTimerCreateStatic             MPU_xTimerCreateStatic
 | 
			
		||||
            #define xTimerGetStaticBuffer          MPU_xTimerGetStaticBuffer
 | 
			
		||||
            #define xTimerGenericCommandFromISR    MPU_xTimerGenericCommandFromISR
 | 
			
		||||
        #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Map standard event_group.h API functions to the MPU equivalents. */
 | 
			
		||||
        #define xEventGroupWaitBits          MPU_xEventGroupWaitBits
 | 
			
		||||
        #define xEventGroupClearBits         MPU_xEventGroupClearBits
 | 
			
		||||
        #define xEventGroupSetBits           MPU_xEventGroupSetBits
 | 
			
		||||
        #define xEventGroupSync              MPU_xEventGroupSync
 | 
			
		||||
 | 
			
		||||
        #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
 | 
			
		||||
            #define uxEventGroupGetNumber    MPU_uxEventGroupGetNumber
 | 
			
		||||
            #define vEventGroupSetNumber     MPU_vEventGroupSetNumber
 | 
			
		||||
        #endif /* #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Event Group APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
        #define xEventGroupCreate                  MPU_xEventGroupCreate
 | 
			
		||||
        #define xEventGroupCreateStatic            MPU_xEventGroupCreateStatic
 | 
			
		||||
        #define vEventGroupDelete                  MPU_vEventGroupDelete
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define xEventGroupGetStaticBuffer     MPU_xEventGroupGetStaticBuffer
 | 
			
		||||
            #define xEventGroupClearBitsFromISR    MPU_xEventGroupClearBitsFromISR
 | 
			
		||||
            #define xEventGroupSetBitsFromISR      MPU_xEventGroupSetBitsFromISR
 | 
			
		||||
            #define xEventGroupGetBitsFromISR      MPU_xEventGroupGetBitsFromISR
 | 
			
		||||
        #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
/* Map standard message/stream_buffer.h API functions to the MPU
 | 
			
		||||
 * equivalents. */
 | 
			
		||||
        #define xStreamBufferSend                      MPU_xStreamBufferSend
 | 
			
		||||
        #define xStreamBufferReceive                   MPU_xStreamBufferReceive
 | 
			
		||||
        #define xStreamBufferIsFull                    MPU_xStreamBufferIsFull
 | 
			
		||||
        #define xStreamBufferIsEmpty                   MPU_xStreamBufferIsEmpty
 | 
			
		||||
        #define xStreamBufferSpacesAvailable           MPU_xStreamBufferSpacesAvailable
 | 
			
		||||
        #define xStreamBufferBytesAvailable            MPU_xStreamBufferBytesAvailable
 | 
			
		||||
        #define xStreamBufferSetTriggerLevel           MPU_xStreamBufferSetTriggerLevel
 | 
			
		||||
        #define xStreamBufferNextMessageLengthBytes    MPU_xStreamBufferNextMessageLengthBytes
 | 
			
		||||
 | 
			
		||||
/* Privileged only wrappers for Stream Buffer APIs. These are needed so that
 | 
			
		||||
 * the application can use opaque handles maintained in mpu_wrappers.c
 | 
			
		||||
 * with all the APIs. */
 | 
			
		||||
 | 
			
		||||
        #define xStreamBufferGenericCreate                  MPU_xStreamBufferGenericCreate
 | 
			
		||||
        #define xStreamBufferGenericCreateStatic            MPU_xStreamBufferGenericCreateStatic
 | 
			
		||||
        #define vStreamBufferDelete                         MPU_vStreamBufferDelete
 | 
			
		||||
        #define xStreamBufferReset                          MPU_xStreamBufferReset
 | 
			
		||||
 | 
			
		||||
        #if ( configUSE_MPU_WRAPPERS_V1 == 0 )
 | 
			
		||||
            #define xStreamBufferGetStaticBuffers           MPU_xStreamBufferGetStaticBuffers
 | 
			
		||||
            #define xStreamBufferSendFromISR                MPU_xStreamBufferSendFromISR
 | 
			
		||||
            #define xStreamBufferReceiveFromISR             MPU_xStreamBufferReceiveFromISR
 | 
			
		||||
            #define xStreamBufferSendCompletedFromISR       MPU_xStreamBufferSendCompletedFromISR
 | 
			
		||||
            #define xStreamBufferReceiveCompletedFromISR    MPU_xStreamBufferReceiveCompletedFromISR
 | 
			
		||||
            #define xStreamBufferResetFromISR               MPU_xStreamBufferResetFromISR
 | 
			
		||||
        #endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */
 | 
			
		||||
 | 
			
		||||
        #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToTask( xTask, xTaskToGrantAccess )                        vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToTask( xTask, xTaskToRevokeAccess )                      vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTaskToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToSemaphore( xTask, xSemaphoreToGrantAccess )              vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToSemaphore( xTask, xSemaphoreToRevokeAccess )            vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xSemaphoreToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToQueue( xTask, xQueueToGrantAccess )                      vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToQueue( xTask, xQueueToRevokeAccess )                    vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToQueueSet( xTask, xQueueSetToGrantAccess )                vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToQueueSet( xTask, xQueueSetToRevokeAccess )              vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xQueueSetToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToEventGroup( xTask, xEventGroupToGrantAccess )            vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToEventGroup( xTask, xEventGroupToRevokeAccess )          vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xEventGroupToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToStreamBuffer( xTask, xStreamBufferToGrantAccess )        vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToStreamBuffer( xTask, xStreamBufferToRevokeAccess )      vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xStreamBufferToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToMessageBuffer( xTask, xMessageBufferToGrantAccess )      vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToMessageBuffer( xTask, xMessageBufferToRevokeAccess )    vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xMessageBufferToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
            #define vGrantAccessToTimer( xTask, xTimerToGrantAccess )                      vGrantAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToGrantAccess ) )
 | 
			
		||||
            #define vRevokeAccessToTimer( xTask, xTimerToRevokeAccess )                    vRevokeAccessToKernelObject( ( xTask ), ( int32_t ) ( xTimerToRevokeAccess ) )
 | 
			
		||||
 | 
			
		||||
        #endif /* #if ( ( configUSE_MPU_WRAPPERS_V1 == 0 ) && ( configENABLE_ACCESS_CONTROL_LIST == 1 ) ) */
 | 
			
		||||
 | 
			
		||||
    #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */
 | 
			
		||||
 | 
			
		||||
    #define PRIVILEGED_FUNCTION     __attribute__( ( section( "privileged_functions" ) ) )
 | 
			
		||||
    #define PRIVILEGED_DATA         __attribute__( ( section( "privileged_data" ) ) )
 | 
			
		||||
    #define FREERTOS_SYSTEM_CALL    __attribute__( ( section( "freertos_system_calls" ) ) )
 | 
			
		||||
 | 
			
		||||
#else /* portUSING_MPU_WRAPPERS */
 | 
			
		||||
 | 
			
		||||
    #define PRIVILEGED_FUNCTION
 | 
			
		||||
    #define PRIVILEGED_DATA
 | 
			
		||||
    #define FREERTOS_SYSTEM_CALL
 | 
			
		||||
 | 
			
		||||
#endif /* portUSING_MPU_WRAPPERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* MPU_WRAPPERS_H */
 | 
			
		||||
							
								
								
									
										62
									
								
								include/newlib-freertos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								include/newlib-freertos.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef INC_NEWLIB_FREERTOS_H
 | 
			
		||||
#define INC_NEWLIB_FREERTOS_H
 | 
			
		||||
 | 
			
		||||
/* Note Newlib support has been included by popular demand, but is not
 | 
			
		||||
 * used by the FreeRTOS maintainers themselves.  FreeRTOS is not
 | 
			
		||||
 * responsible for resulting newlib operation.  User must be familiar with
 | 
			
		||||
 * newlib and must provide system-wide implementations of the necessary
 | 
			
		||||
 * stubs. Be warned that (at the time of writing) the current newlib design
 | 
			
		||||
 * implements a system-wide malloc() that must be provided with locks.
 | 
			
		||||
 *
 | 
			
		||||
 * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
 | 
			
		||||
 * for additional information. */
 | 
			
		||||
 | 
			
		||||
#include <reent.h>
 | 
			
		||||
 | 
			
		||||
#define configUSE_C_RUNTIME_TLS_SUPPORT    1
 | 
			
		||||
 | 
			
		||||
#ifndef configTLS_BLOCK_TYPE
 | 
			
		||||
    #define configTLS_BLOCK_TYPE           struct _reent
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configINIT_TLS_BLOCK
 | 
			
		||||
    #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack )    _REENT_INIT_PTR( &( xTLSBlock ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configSET_TLS_BLOCK
 | 
			
		||||
    #define configSET_TLS_BLOCK( xTLSBlock )    ( _impure_ptr = &( xTLSBlock ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configDEINIT_TLS_BLOCK
 | 
			
		||||
    #define configDEINIT_TLS_BLOCK( xTLSBlock )    _reclaim_reent( &( xTLSBlock ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* INC_NEWLIB_FREERTOS_H */
 | 
			
		||||
							
								
								
									
										91
									
								
								include/picolibc-freertos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								include/picolibc-freertos.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef INC_PICOLIBC_FREERTOS_H
 | 
			
		||||
#define INC_PICOLIBC_FREERTOS_H
 | 
			
		||||
 | 
			
		||||
/* Use picolibc TLS support to allocate space for __thread variables,
 | 
			
		||||
 * initialize them at thread creation and set the TLS context at
 | 
			
		||||
 * thread switch time.
 | 
			
		||||
 *
 | 
			
		||||
 * See the picolibc TLS docs:
 | 
			
		||||
 * https://github.com/picolibc/picolibc/blob/main/doc/tls.md
 | 
			
		||||
 * for additional information. */
 | 
			
		||||
 | 
			
		||||
#include <picotls.h>
 | 
			
		||||
 | 
			
		||||
#define configUSE_C_RUNTIME_TLS_SUPPORT    1
 | 
			
		||||
 | 
			
		||||
#define configTLS_BLOCK_TYPE               void *
 | 
			
		||||
 | 
			
		||||
#define picolibcTLS_SIZE                   ( ( portPOINTER_SIZE_TYPE ) _tls_size() )
 | 
			
		||||
#define picolibcSTACK_ALIGNMENT_MASK       ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
 | 
			
		||||
 | 
			
		||||
#if __PICOLIBC_MAJOR__ > 1 || __PICOLIBC_MINOR__ >= 8
 | 
			
		||||
 | 
			
		||||
/* Picolibc 1.8 and newer have explicit alignment values provided
 | 
			
		||||
 * by the _tls_align() inline */
 | 
			
		||||
    #define picolibcTLS_ALIGNMENT_MASK    ( ( portPOINTER_SIZE_TYPE ) ( _tls_align() - 1 ) )
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
/* For older Picolibc versions, use the general port alignment value */
 | 
			
		||||
    #define picolibcTLS_ALIGNMENT_MASK    ( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Allocate thread local storage block off the end of the
 | 
			
		||||
 * stack. The picolibcTLS_SIZE macro returns the size (in
 | 
			
		||||
 * bytes) of the total TLS area used by the application.
 | 
			
		||||
 * Calculate the top of stack address. */
 | 
			
		||||
#if ( portSTACK_GROWTH < 0 )
 | 
			
		||||
 | 
			
		||||
    #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack )                                  \
 | 
			
		||||
    do {                                                                                     \
 | 
			
		||||
        xTLSBlock = ( void * ) ( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) -              \
 | 
			
		||||
                                   picolibcTLS_SIZE ) &                                      \
 | 
			
		||||
                                 ~picolibcTLS_ALIGNMENT_MASK );                              \
 | 
			
		||||
        pxTopOfStack = ( StackType_t * ) ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) - 1 ) & \
 | 
			
		||||
                                           ~picolibcSTACK_ALIGNMENT_MASK );                  \
 | 
			
		||||
        _init_tls( xTLSBlock );                                                              \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
#else /* portSTACK_GROWTH */
 | 
			
		||||
    #define configINIT_TLS_BLOCK( xTLSBlock, pxTopOfStack )                                          \
 | 
			
		||||
    do {                                                                                             \
 | 
			
		||||
        xTLSBlock = ( void * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack +                          \
 | 
			
		||||
                                   picolibcTLS_ALIGNMENT_MASK ) & ~picolibcTLS_ALIGNMENT_MASK );     \
 | 
			
		||||
        pxTopOfStack = ( StackType_t * ) ( ( ( ( ( portPOINTER_SIZE_TYPE ) xTLSBlock ) +             \
 | 
			
		||||
                                               picolibcTLS_SIZE ) + picolibcSTACK_ALIGNMENT_MASK ) & \
 | 
			
		||||
                                           ~picolibcSTACK_ALIGNMENT_MASK );                          \
 | 
			
		||||
        _init_tls( xTLSBlock );                                                                      \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
#endif /* portSTACK_GROWTH */
 | 
			
		||||
 | 
			
		||||
#define configSET_TLS_BLOCK( xTLSBlock )    _set_tls( xTLSBlock )
 | 
			
		||||
 | 
			
		||||
#define configDEINIT_TLS_BLOCK( xTLSBlock )
 | 
			
		||||
 | 
			
		||||
#endif /* INC_PICOLIBC_FREERTOS_H */
 | 
			
		||||
							
								
								
									
										281
									
								
								include/portable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										281
									
								
								include/portable.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,281 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
* Portable layer API.  Each function must be defined for each port.
 | 
			
		||||
*----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#ifndef PORTABLE_H
 | 
			
		||||
#define PORTABLE_H
 | 
			
		||||
 | 
			
		||||
/* Each FreeRTOS port has a unique portmacro.h header file.  Originally a
 | 
			
		||||
 * pre-processor definition was used to ensure the pre-processor found the correct
 | 
			
		||||
 * portmacro.h file for the port being used.  That scheme was deprecated in favour
 | 
			
		||||
 * of setting the compiler's include path such that it found the correct
 | 
			
		||||
 * portmacro.h file - removing the need for the constant and allowing the
 | 
			
		||||
 * portmacro.h file to be located anywhere in relation to the port being used.
 | 
			
		||||
 * Purely for reasons of backward compatibility the old method is still valid, but
 | 
			
		||||
 * to make it clear that new projects should not use it, support for the port
 | 
			
		||||
 * specific constants has been moved into the deprecated_definitions.h header
 | 
			
		||||
 * file. */
 | 
			
		||||
#include "deprecated_definitions.h"
 | 
			
		||||
 | 
			
		||||
/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h
 | 
			
		||||
 * did not result in a portmacro.h header file being included - and it should be
 | 
			
		||||
 * included here.  In this case the path to the correct portmacro.h header file
 | 
			
		||||
 * must be set in the compiler's include path. */
 | 
			
		||||
#ifndef portENTER_CRITICAL
 | 
			
		||||
    #include "portmacro.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if portBYTE_ALIGNMENT == 32
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x001f )
 | 
			
		||||
#elif portBYTE_ALIGNMENT == 16
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x000f )
 | 
			
		||||
#elif portBYTE_ALIGNMENT == 8
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x0007 )
 | 
			
		||||
#elif portBYTE_ALIGNMENT == 4
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x0003 )
 | 
			
		||||
#elif portBYTE_ALIGNMENT == 2
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x0001 )
 | 
			
		||||
#elif portBYTE_ALIGNMENT == 1
 | 
			
		||||
    #define portBYTE_ALIGNMENT_MASK    ( 0x0000 )
 | 
			
		||||
#else /* if portBYTE_ALIGNMENT == 32 */
 | 
			
		||||
    #error "Invalid portBYTE_ALIGNMENT definition"
 | 
			
		||||
#endif /* if portBYTE_ALIGNMENT == 32 */
 | 
			
		||||
 | 
			
		||||
#ifndef portUSING_MPU_WRAPPERS
 | 
			
		||||
    #define portUSING_MPU_WRAPPERS    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portNUM_CONFIGURABLE_REGIONS
 | 
			
		||||
    #define portNUM_CONFIGURABLE_REGIONS    1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portHAS_STACK_OVERFLOW_CHECKING
 | 
			
		||||
    #define portHAS_STACK_OVERFLOW_CHECKING    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef portARCH_NAME
 | 
			
		||||
    #define portARCH_NAME    NULL
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configSTACK_DEPTH_TYPE
 | 
			
		||||
    #define configSTACK_DEPTH_TYPE    StackType_t
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef configSTACK_ALLOCATION_FROM_SEPARATE_HEAP
 | 
			
		||||
    /* Defaults to 0 for backward compatibility. */
 | 
			
		||||
    #define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#include "mpu_wrappers.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the stack of a new task so it is ready to be placed under the
 | 
			
		||||
 * scheduler control.  The registers have to be placed on the stack in
 | 
			
		||||
 * the order that the port expects to find them.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#if ( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
    #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
 | 
			
		||||
        StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                             StackType_t * pxEndOfStack,
 | 
			
		||||
                                             TaskFunction_t pxCode,
 | 
			
		||||
                                             void * pvParameters,
 | 
			
		||||
                                             BaseType_t xRunPrivileged,
 | 
			
		||||
                                             xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    #else
 | 
			
		||||
        StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                             TaskFunction_t pxCode,
 | 
			
		||||
                                             void * pvParameters,
 | 
			
		||||
                                             BaseType_t xRunPrivileged,
 | 
			
		||||
                                             xMPU_SETTINGS * xMPUSettings ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    #endif /* if ( portHAS_STACK_OVERFLOW_CHECKING == 1 ) */
 | 
			
		||||
#else /* if ( portUSING_MPU_WRAPPERS == 1 ) */
 | 
			
		||||
    #if ( portHAS_STACK_OVERFLOW_CHECKING == 1 )
 | 
			
		||||
        StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                             StackType_t * pxEndOfStack,
 | 
			
		||||
                                             TaskFunction_t pxCode,
 | 
			
		||||
                                             void * pvParameters ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    #else
 | 
			
		||||
        StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
                                             TaskFunction_t pxCode,
 | 
			
		||||
                                             void * pvParameters ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    #endif
 | 
			
		||||
#endif /* if ( portUSING_MPU_WRAPPERS == 1 ) */
 | 
			
		||||
 | 
			
		||||
/* Used by heap_5.c to define the start address and size of each memory region
 | 
			
		||||
 * that together comprise the total FreeRTOS heap space. */
 | 
			
		||||
typedef struct HeapRegion
 | 
			
		||||
{
 | 
			
		||||
    uint8_t * pucStartAddress;
 | 
			
		||||
    size_t xSizeInBytes;
 | 
			
		||||
} HeapRegion_t;
 | 
			
		||||
 | 
			
		||||
/* Used to pass information about the heap out of vPortGetHeapStats(). */
 | 
			
		||||
typedef struct xHeapStats
 | 
			
		||||
{
 | 
			
		||||
    size_t xAvailableHeapSpaceInBytes;      /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */
 | 
			
		||||
    size_t xSizeOfLargestFreeBlockInBytes;  /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
 | 
			
		||||
    size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */
 | 
			
		||||
    size_t xNumberOfFreeBlocks;             /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */
 | 
			
		||||
    size_t xMinimumEverFreeBytesRemaining;  /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */
 | 
			
		||||
    size_t xNumberOfSuccessfulAllocations;  /* The number of calls to pvPortMalloc() that have returned a valid memory block. */
 | 
			
		||||
    size_t xNumberOfSuccessfulFrees;        /* The number of calls to vPortFree() that has successfully freed a block of memory. */
 | 
			
		||||
} HeapStats_t;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Used to define multiple heap regions for use by heap_5.c.  This function
 | 
			
		||||
 * must be called before any calls to pvPortMalloc() - not creating a task,
 | 
			
		||||
 * queue, semaphore, mutex, software timer, event group, etc. will result in
 | 
			
		||||
 * pvPortMalloc being called.
 | 
			
		||||
 *
 | 
			
		||||
 * pxHeapRegions passes in an array of HeapRegion_t structures - each of which
 | 
			
		||||
 * defines a region of memory that can be used as the heap.  The array is
 | 
			
		||||
 * terminated by a HeapRegions_t structure that has a size of 0.  The region
 | 
			
		||||
 * with the lowest start address must appear first in the array.
 | 
			
		||||
 */
 | 
			
		||||
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Returns a HeapStats_t structure filled with information about the current
 | 
			
		||||
 * heap state.
 | 
			
		||||
 */
 | 
			
		||||
void vPortGetHeapStats( HeapStats_t * pxHeapStats );
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Map to the memory management routines required for the port.
 | 
			
		||||
 */
 | 
			
		||||
void * pvPortMalloc( size_t xWantedSize ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void * pvPortCalloc( size_t xNum,
 | 
			
		||||
                     size_t xSize ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vPortFree( void * pv ) PRIVILEGED_FUNCTION;
 | 
			
		||||
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
#if ( configSTACK_ALLOCATION_FROM_SEPARATE_HEAP == 1 )
 | 
			
		||||
    void * pvPortMallocStack( size_t xSize ) PRIVILEGED_FUNCTION;
 | 
			
		||||
    void vPortFreeStack( void * pv ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#else
 | 
			
		||||
    #define pvPortMallocStack    pvPortMalloc
 | 
			
		||||
    #define vPortFreeStack       vPortFree
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This function resets the internal state of the heap module. It must be called
 | 
			
		||||
 * by the application before restarting the scheduler.
 | 
			
		||||
 */
 | 
			
		||||
void vPortHeapResetState( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
#if ( configUSE_MALLOC_FAILED_HOOK == 1 )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * task.h
 | 
			
		||||
 * @code{c}
 | 
			
		||||
 * void vApplicationMallocFailedHook( void )
 | 
			
		||||
 * @endcode
 | 
			
		||||
 *
 | 
			
		||||
 * This hook function is called when allocation failed.
 | 
			
		||||
 */
 | 
			
		||||
    void vApplicationMallocFailedHook( void );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Setup the hardware ready for the scheduler to take control.  This generally
 | 
			
		||||
 * sets up a tick interrupt and sets timers for the correct tick frequency.
 | 
			
		||||
 */
 | 
			
		||||
BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so
 | 
			
		||||
 * the hardware is left in its original condition after the scheduler stops
 | 
			
		||||
 * executing.
 | 
			
		||||
 */
 | 
			
		||||
void vPortEndScheduler( void ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The structures and methods of manipulating the MPU are contained within the
 | 
			
		||||
 * port layer.
 | 
			
		||||
 *
 | 
			
		||||
 * Fills the xMPUSettings structure with the memory region information
 | 
			
		||||
 * contained in xRegions.
 | 
			
		||||
 */
 | 
			
		||||
#if ( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
    struct xMEMORY_REGION;
 | 
			
		||||
    void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings,
 | 
			
		||||
                                    const struct xMEMORY_REGION * const xRegions,
 | 
			
		||||
                                    StackType_t * pxBottomOfStack,
 | 
			
		||||
                                    configSTACK_DEPTH_TYPE uxStackDepth ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Checks if the calling task is authorized to access the given buffer.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pvBuffer The buffer which the calling task wants to access.
 | 
			
		||||
 * @param ulBufferLength The length of the pvBuffer.
 | 
			
		||||
 * @param ulAccessRequested The permissions that the calling task wants.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the calling task is authorized to access the buffer,
 | 
			
		||||
 *         pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
#if ( portUSING_MPU_WRAPPERS == 1 )
 | 
			
		||||
    BaseType_t xPortIsAuthorizedToAccessBuffer( const void * pvBuffer,
 | 
			
		||||
                                                uint32_t ulBufferLength,
 | 
			
		||||
                                                uint32_t ulAccessRequested ) PRIVILEGED_FUNCTION;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Checks if the calling task is authorized to access the given kernel object.
 | 
			
		||||
 *
 | 
			
		||||
 * @param lInternalIndexOfKernelObject The index of the kernel object in the kernel
 | 
			
		||||
 *                                     object handle pool.
 | 
			
		||||
 *
 | 
			
		||||
 * @return pdTRUE if the calling task is authorized to access the kernel object,
 | 
			
		||||
 *         pdFALSE otherwise.
 | 
			
		||||
 */
 | 
			
		||||
#if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) )
 | 
			
		||||
 | 
			
		||||
    BaseType_t xPortIsAuthorizedToAccessKernelObject( int32_t lInternalIndexOfKernelObject ) PRIVILEGED_FUNCTION;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* *INDENT-OFF* */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
/* *INDENT-ON* */
 | 
			
		||||
 | 
			
		||||
#endif /* PORTABLE_H */
 | 
			
		||||
							
								
								
									
										118
									
								
								include/portmacro.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								include/portmacro.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Changes from V1.2.3
 | 
			
		||||
 *
 | 
			
		||||
 + portCPU_CLOCK_HZ definition changed to 8MHz base 10, previously it
 | 
			
		||||
 +    base 16.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 #ifndef PORTMACRO_H
 | 
			
		||||
 #define PORTMACRO_H
 | 
			
		||||
 
 | 
			
		||||
 /* *INDENT-OFF* */
 | 
			
		||||
 #ifdef __cplusplus
 | 
			
		||||
     extern "C" {
 | 
			
		||||
 #endif
 | 
			
		||||
 /* *INDENT-ON* */
 | 
			
		||||
 
 | 
			
		||||
 /*-----------------------------------------------------------
 | 
			
		||||
  * Port specific definitions.
 | 
			
		||||
  *
 | 
			
		||||
  * The settings in this file configure FreeRTOS correctly for the
 | 
			
		||||
  * given hardware and compiler.
 | 
			
		||||
  *
 | 
			
		||||
  * These settings should not be altered.
 | 
			
		||||
  *-----------------------------------------------------------
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
 /* Type definitions. */
 | 
			
		||||
 #define portCHAR                 char
 | 
			
		||||
 #define portFLOAT                float
 | 
			
		||||
 #define portDOUBLE               double
 | 
			
		||||
 #define portLONG                 long
 | 
			
		||||
 #define portSHORT                int
 | 
			
		||||
 #define portSTACK_TYPE           uint8_t
 | 
			
		||||
 #define portBASE_TYPE            char
 | 
			
		||||
 
 | 
			
		||||
 #define portPOINTER_SIZE_TYPE    uint16_t
 | 
			
		||||
 
 | 
			
		||||
 typedef portSTACK_TYPE   StackType_t;
 | 
			
		||||
 typedef signed char      BaseType_t;
 | 
			
		||||
 typedef unsigned char    UBaseType_t;
 | 
			
		||||
 
 | 
			
		||||
 #if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
 | 
			
		||||
     typedef uint16_t     TickType_t;
 | 
			
		||||
     #define portMAX_DELAY    ( TickType_t ) 0xffff
 | 
			
		||||
 #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
 | 
			
		||||
     typedef uint32_t     TickType_t;
 | 
			
		||||
     #define portMAX_DELAY    ( TickType_t ) ( 0xFFFFFFFFUL )
 | 
			
		||||
 #else
 | 
			
		||||
     #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
 | 
			
		||||
 #endif
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* Critical section management. */
 | 
			
		||||
 #define portENTER_CRITICAL()                            \
 | 
			
		||||
     asm volatile ( "in      __tmp_reg__, __SREG__" ::); \
 | 
			
		||||
     asm volatile ( "cli" ::);                           \
 | 
			
		||||
     asm volatile ( "push    __tmp_reg__" ::)
 | 
			
		||||
 
 | 
			
		||||
 #define portEXIT_CRITICAL()                   \
 | 
			
		||||
     asm volatile ( "pop     __tmp_reg__" ::); \
 | 
			
		||||
     asm volatile ( "out     __SREG__, __tmp_reg__" ::)
 | 
			
		||||
 
 | 
			
		||||
 #define portDISABLE_INTERRUPTS()    asm volatile ( "cli" ::);
 | 
			
		||||
 #define portENABLE_INTERRUPTS()     asm volatile ( "sei" ::);
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* Architecture specifics. */
 | 
			
		||||
 #define portSTACK_GROWTH      ( -1 )
 | 
			
		||||
 #define portTICK_PERIOD_MS    ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
 | 
			
		||||
 #define portBYTE_ALIGNMENT    1
 | 
			
		||||
 #define portNOP()    asm volatile ( "nop" );
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* Kernel utilities. */
 | 
			
		||||
 extern void vPortYield( void ) __attribute__( ( naked ) );
 | 
			
		||||
 #define portYIELD()    vPortYield()
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* Task function macros as described on the FreeRTOS.org WEB site. */
 | 
			
		||||
 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )    void vFunction( void * pvParameters )
 | 
			
		||||
 #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void * pvParameters )
 | 
			
		||||
 
 | 
			
		||||
 /* *INDENT-OFF* */
 | 
			
		||||
 #ifdef __cplusplus
 | 
			
		||||
     }
 | 
			
		||||
 #endif
 | 
			
		||||
 /* *INDENT-ON* */
 | 
			
		||||
 
 | 
			
		||||
 #endif /* PORTMACRO_H */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										138
									
								
								include/projdefs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								include/projdefs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef PROJDEFS_H
 | 
			
		||||
#define PROJDEFS_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Defines the prototype to which task functions must conform.  Defined in this
 | 
			
		||||
 * file to ensure the type is known before portable.h is included.
 | 
			
		||||
 */
 | 
			
		||||
typedef void (* TaskFunction_t)( void * arg );
 | 
			
		||||
 | 
			
		||||
/* Converts a time in milliseconds to a time in ticks.  This macro can be
 | 
			
		||||
 * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
 | 
			
		||||
 * definition here is not suitable for your application. */
 | 
			
		||||
#ifndef pdMS_TO_TICKS
 | 
			
		||||
    #define pdMS_TO_TICKS( xTimeInMs )    ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInMs ) * ( uint64_t ) configTICK_RATE_HZ ) / ( uint64_t ) 1000U ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Converts a time in ticks to a time in milliseconds.  This macro can be
 | 
			
		||||
 * overridden by a macro of the same name defined in FreeRTOSConfig.h in case the
 | 
			
		||||
 * definition here is not suitable for your application. */
 | 
			
		||||
#ifndef pdTICKS_TO_MS
 | 
			
		||||
    #define pdTICKS_TO_MS( xTimeInTicks )    ( ( TickType_t ) ( ( ( uint64_t ) ( xTimeInTicks ) * ( uint64_t ) 1000U ) / ( uint64_t ) configTICK_RATE_HZ ) )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define pdFALSE                                  ( ( BaseType_t ) 0 )
 | 
			
		||||
#define pdTRUE                                   ( ( BaseType_t ) 1 )
 | 
			
		||||
#define pdFALSE_SIGNED                           ( ( BaseType_t ) 0 )
 | 
			
		||||
#define pdTRUE_SIGNED                            ( ( BaseType_t ) 1 )
 | 
			
		||||
#define pdFALSE_UNSIGNED                         ( ( UBaseType_t ) 0 )
 | 
			
		||||
#define pdTRUE_UNSIGNED                          ( ( UBaseType_t ) 1 )
 | 
			
		||||
 | 
			
		||||
#define pdPASS                                   ( pdTRUE )
 | 
			
		||||
#define pdFAIL                                   ( pdFALSE )
 | 
			
		||||
#define errQUEUE_EMPTY                           ( ( BaseType_t ) 0 )
 | 
			
		||||
#define errQUEUE_FULL                            ( ( BaseType_t ) 0 )
 | 
			
		||||
 | 
			
		||||
/* FreeRTOS error definitions. */
 | 
			
		||||
#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY    ( -1 )
 | 
			
		||||
#define errQUEUE_BLOCKED                         ( -4 )
 | 
			
		||||
#define errQUEUE_YIELD                           ( -5 )
 | 
			
		||||
 | 
			
		||||
/* Macros used for basic data corruption checks. */
 | 
			
		||||
#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES
 | 
			
		||||
    #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
 | 
			
		||||
    #define pdINTEGRITY_CHECK_VALUE    0x5a5a
 | 
			
		||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
 | 
			
		||||
    #define pdINTEGRITY_CHECK_VALUE    0x5a5a5a5aUL
 | 
			
		||||
#elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_64_BITS )
 | 
			
		||||
    #define pdINTEGRITY_CHECK_VALUE    0x5a5a5a5a5a5a5a5aULL
 | 
			
		||||
#else
 | 
			
		||||
    #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
 | 
			
		||||
 * itself. */
 | 
			
		||||
#define pdFREERTOS_ERRNO_NONE             0   /* No errors */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOENT           2   /* No such file or directory */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EINTR            4   /* Interrupted system call */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EIO              5   /* I/O error */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENXIO            6   /* No such device or address */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EBADF            9   /* Bad file number */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EAGAIN           11  /* No more processes */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EWOULDBLOCK      11  /* Operation would block */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOMEM           12  /* Not enough memory */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EACCES           13  /* Permission denied */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EFAULT           14  /* Bad address */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EBUSY            16  /* Mount device busy */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EEXIST           17  /* File exists */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EXDEV            18  /* Cross-device link */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENODEV           19  /* No such device */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOTDIR          20  /* Not a directory */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EISDIR           21  /* Is a directory */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EINVAL           22  /* Invalid argument */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOSPC           28  /* No space left on device */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ESPIPE           29  /* Illegal seek */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EROFS            30  /* Read only file system */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EUNATCH          42  /* Protocol driver not attached */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EBADE            50  /* Invalid exchange */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EFTYPE           79  /* Inappropriate file type or format */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENMFILE          89  /* No more files */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOTEMPTY        90  /* Directory not empty */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENAMETOOLONG     91  /* File or path name too long */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EOPNOTSUPP       95  /* Operation not supported on transport endpoint */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EAFNOSUPPORT     97  /* Address family not supported by protocol */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOBUFS          105 /* No buffer space available */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOPROTOOPT      109 /* Protocol not available */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EADDRINUSE       112 /* Address already in use */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ETIMEDOUT        116 /* Connection timed out */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EINPROGRESS      119 /* Connection already in progress */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EALREADY         120 /* Socket already connected */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EADDRNOTAVAIL    125 /* Address not available */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EISCONN          127 /* Socket is already connected */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOTCONN         128 /* Socket is not connected */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ENOMEDIUM        135 /* No medium inserted */
 | 
			
		||||
#define pdFREERTOS_ERRNO_EILSEQ           138 /* An invalid UTF-16 sequence was encountered. */
 | 
			
		||||
#define pdFREERTOS_ERRNO_ECANCELED        140 /* Operation canceled. */
 | 
			
		||||
 | 
			
		||||
/* The following endian values are used by FreeRTOS+ components, not FreeRTOS
 | 
			
		||||
 * itself. */
 | 
			
		||||
#define pdFREERTOS_LITTLE_ENDIAN          0
 | 
			
		||||
#define pdFREERTOS_BIG_ENDIAN             1
 | 
			
		||||
 | 
			
		||||
/* Re-defining endian values for generic naming. */
 | 
			
		||||
#define pdLITTLE_ENDIAN                   pdFREERTOS_LITTLE_ENDIAN
 | 
			
		||||
#define pdBIG_ENDIAN                      pdFREERTOS_BIG_ENDIAN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* PROJDEFS_H */
 | 
			
		||||
							
								
								
									
										1810
									
								
								include/queue.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1810
									
								
								include/queue.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1215
									
								
								include/semphr.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1215
									
								
								include/semphr.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										141
									
								
								include/stack_macros.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								include/stack_macros.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef STACK_MACROS_H
 | 
			
		||||
#define STACK_MACROS_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Call the stack overflow hook function if the stack of the task being swapped
 | 
			
		||||
 * out is currently overflowed, or looks like it might have overflowed in the
 | 
			
		||||
 * past.
 | 
			
		||||
 *
 | 
			
		||||
 * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check
 | 
			
		||||
 * the current stack state only - comparing the current top of stack value to
 | 
			
		||||
 * the stack limit.  Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1
 | 
			
		||||
 * will also cause the last few stack bytes to be checked to ensure the value
 | 
			
		||||
 * to which the bytes were set when the task was created have not been
 | 
			
		||||
 * overwritten.  Note this second test does not guarantee that an overflowed
 | 
			
		||||
 * stack will always be recognised.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * portSTACK_LIMIT_PADDING is a number of extra words to consider to be in
 | 
			
		||||
 * use on the stack.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef portSTACK_LIMIT_PADDING
 | 
			
		||||
    #define portSTACK_LIMIT_PADDING    0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Only the current stack state is to be checked. */
 | 
			
		||||
    #define taskCHECK_FOR_STACK_OVERFLOW()                                                      \
 | 
			
		||||
    do {                                                                                        \
 | 
			
		||||
        /* Is the currently saved stack pointer within the stack limit? */                      \
 | 
			
		||||
        if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack + portSTACK_LIMIT_PADDING )     \
 | 
			
		||||
        {                                                                                       \
 | 
			
		||||
            char * pcOverflowTaskName = pxCurrentTCB->pcTaskName;                               \
 | 
			
		||||
            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
 | 
			
		||||
        }                                                                                       \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) )
 | 
			
		||||
 | 
			
		||||
/* Only the current stack state is to be checked. */
 | 
			
		||||
    #define taskCHECK_FOR_STACK_OVERFLOW()                                                       \
 | 
			
		||||
    do {                                                                                         \
 | 
			
		||||
                                                                                                 \
 | 
			
		||||
        /* Is the currently saved stack pointer within the stack limit? */                       \
 | 
			
		||||
        if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack - portSTACK_LIMIT_PADDING ) \
 | 
			
		||||
        {                                                                                        \
 | 
			
		||||
            char * pcOverflowTaskName = pxCurrentTCB->pcTaskName;                                \
 | 
			
		||||
            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName );  \
 | 
			
		||||
        }                                                                                        \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) )
 | 
			
		||||
 | 
			
		||||
    #define taskCHECK_FOR_STACK_OVERFLOW()                                                      \
 | 
			
		||||
    do {                                                                                        \
 | 
			
		||||
        const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack;                 \
 | 
			
		||||
        const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5U;                                 \
 | 
			
		||||
                                                                                                \
 | 
			
		||||
        if( ( pulStack[ 0 ] != ulCheckValue ) ||                                                \
 | 
			
		||||
            ( pulStack[ 1 ] != ulCheckValue ) ||                                                \
 | 
			
		||||
            ( pulStack[ 2 ] != ulCheckValue ) ||                                                \
 | 
			
		||||
            ( pulStack[ 3 ] != ulCheckValue ) )                                                 \
 | 
			
		||||
        {                                                                                       \
 | 
			
		||||
            char * pcOverflowTaskName = pxCurrentTCB->pcTaskName;                               \
 | 
			
		||||
            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName ); \
 | 
			
		||||
        }                                                                                       \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#if ( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) )
 | 
			
		||||
 | 
			
		||||
    #define taskCHECK_FOR_STACK_OVERFLOW()                                                                                                \
 | 
			
		||||
    do {                                                                                                                                  \
 | 
			
		||||
        int8_t * pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack;                                                                  \
 | 
			
		||||
        static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
 | 
			
		||||
                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
 | 
			
		||||
                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
 | 
			
		||||
                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE,   \
 | 
			
		||||
                                                        tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \
 | 
			
		||||
                                                                                                                                          \
 | 
			
		||||
                                                                                                                                          \
 | 
			
		||||
        pcEndOfStack -= sizeof( ucExpectedStackBytes );                                                                                   \
 | 
			
		||||
                                                                                                                                          \
 | 
			
		||||
        /* Has the extremity of the task stack ever been written over? */                                                                 \
 | 
			
		||||
        if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 )                     \
 | 
			
		||||
        {                                                                                                                                 \
 | 
			
		||||
            char * pcOverflowTaskName = pxCurrentTCB->pcTaskName;                                                                         \
 | 
			
		||||
            vApplicationStackOverflowHook( ( TaskHandle_t ) pxCurrentTCB, pcOverflowTaskName );                                           \
 | 
			
		||||
        }                                                                                                                                 \
 | 
			
		||||
    } while( 0 )
 | 
			
		||||
 | 
			
		||||
#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
/* Remove stack overflow macro if not being used. */
 | 
			
		||||
#ifndef taskCHECK_FOR_STACK_OVERFLOW
 | 
			
		||||
    #define taskCHECK_FOR_STACK_OVERFLOW()
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* STACK_MACROS_H */
 | 
			
		||||
							
								
								
									
										1280
									
								
								include/stream_buffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1280
									
								
								include/stream_buffer.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3774
									
								
								include/task.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3774
									
								
								include/task.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1431
									
								
								include/timers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1431
									
								
								include/timers.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										246
									
								
								list.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								list.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,246 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | 
			
		||||
 * all the API functions to use the MPU wrappers.  That should only be done when
 | 
			
		||||
 * task.h is included from an application file. */
 | 
			
		||||
#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
 | 
			
		||||
/* The MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be
 | 
			
		||||
 * defined for the header files above, but not in this file, in order to
 | 
			
		||||
 * generate the correct privileged Vs unprivileged linkage and placement. */
 | 
			
		||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------
 | 
			
		||||
* PUBLIC LIST API documented in list.h
 | 
			
		||||
*----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInitialise( List_t * const pxList )
 | 
			
		||||
{
 | 
			
		||||
    traceENTER_vListInitialise( pxList );
 | 
			
		||||
 | 
			
		||||
    /* The list structure contains a list item which is used to mark the
 | 
			
		||||
     * end of the list.  To initialise the list the list end is inserted
 | 
			
		||||
     * as the only list entry. */
 | 
			
		||||
    pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
 | 
			
		||||
 | 
			
		||||
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
 | 
			
		||||
 | 
			
		||||
    /* The list end value is the highest possible value in the list to
 | 
			
		||||
     * ensure it remains at the end of the list. */
 | 
			
		||||
    pxList->xListEnd.xItemValue = portMAX_DELAY;
 | 
			
		||||
 | 
			
		||||
    /* The list end next and previous pointers point to itself so we know
 | 
			
		||||
     * when the list is empty. */
 | 
			
		||||
    pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
 | 
			
		||||
    pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
 | 
			
		||||
 | 
			
		||||
    /* Initialize the remaining fields of xListEnd when it is a proper ListItem_t */
 | 
			
		||||
    #if ( configUSE_MINI_LIST_ITEM == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        pxList->xListEnd.pvOwner = NULL;
 | 
			
		||||
        pxList->xListEnd.pxContainer = NULL;
 | 
			
		||||
        listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( &( pxList->xListEnd ) );
 | 
			
		||||
    }
 | 
			
		||||
    #endif
 | 
			
		||||
 | 
			
		||||
    pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
 | 
			
		||||
 | 
			
		||||
    /* Write known values into the list if
 | 
			
		||||
     * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
    listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
 | 
			
		||||
    listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
 | 
			
		||||
 | 
			
		||||
    traceRETURN_vListInitialise();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInitialiseItem( ListItem_t * const pxItem )
 | 
			
		||||
{
 | 
			
		||||
    traceENTER_vListInitialiseItem( pxItem );
 | 
			
		||||
 | 
			
		||||
    /* Make sure the list item is not recorded as being on a list. */
 | 
			
		||||
    pxItem->pxContainer = NULL;
 | 
			
		||||
 | 
			
		||||
    /* Write known values into the list item if
 | 
			
		||||
     * configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */
 | 
			
		||||
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
 | 
			
		||||
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
 | 
			
		||||
 | 
			
		||||
    traceRETURN_vListInitialiseItem();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInsertEnd( List_t * const pxList,
 | 
			
		||||
                     ListItem_t * const pxNewListItem )
 | 
			
		||||
{
 | 
			
		||||
    ListItem_t * const pxIndex = pxList->pxIndex;
 | 
			
		||||
 | 
			
		||||
    traceENTER_vListInsertEnd( pxList, pxNewListItem );
 | 
			
		||||
 | 
			
		||||
    /* Only effective when configASSERT() is also defined, these tests may catch
 | 
			
		||||
     * the list data structures being overwritten in memory.  They will not catch
 | 
			
		||||
     * data errors caused by incorrect configuration or use of FreeRTOS. */
 | 
			
		||||
    listTEST_LIST_INTEGRITY( pxList );
 | 
			
		||||
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
 | 
			
		||||
 | 
			
		||||
    /* Insert a new list item into pxList, but rather than sort the list,
 | 
			
		||||
     * makes the new list item the last item to be removed by a call to
 | 
			
		||||
     * listGET_OWNER_OF_NEXT_ENTRY(). */
 | 
			
		||||
    pxNewListItem->pxNext = pxIndex;
 | 
			
		||||
    pxNewListItem->pxPrevious = pxIndex->pxPrevious;
 | 
			
		||||
 | 
			
		||||
    /* Only used during decision coverage testing. */
 | 
			
		||||
    mtCOVERAGE_TEST_DELAY();
 | 
			
		||||
 | 
			
		||||
    pxIndex->pxPrevious->pxNext = pxNewListItem;
 | 
			
		||||
    pxIndex->pxPrevious = pxNewListItem;
 | 
			
		||||
 | 
			
		||||
    /* Remember which list the item is in. */
 | 
			
		||||
    pxNewListItem->pxContainer = pxList;
 | 
			
		||||
 | 
			
		||||
    ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );
 | 
			
		||||
 | 
			
		||||
    traceRETURN_vListInsertEnd();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
void vListInsert( List_t * const pxList,
 | 
			
		||||
                  ListItem_t * const pxNewListItem )
 | 
			
		||||
{
 | 
			
		||||
    ListItem_t * pxIterator;
 | 
			
		||||
    const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
 | 
			
		||||
 | 
			
		||||
    traceENTER_vListInsert( pxList, pxNewListItem );
 | 
			
		||||
 | 
			
		||||
    /* Only effective when configASSERT() is also defined, these tests may catch
 | 
			
		||||
     * the list data structures being overwritten in memory.  They will not catch
 | 
			
		||||
     * data errors caused by incorrect configuration or use of FreeRTOS. */
 | 
			
		||||
    listTEST_LIST_INTEGRITY( pxList );
 | 
			
		||||
    listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
 | 
			
		||||
 | 
			
		||||
    /* Insert the new list item into the list, sorted in xItemValue order.
 | 
			
		||||
     *
 | 
			
		||||
     * If the list already contains a list item with the same item value then the
 | 
			
		||||
     * new list item should be placed after it.  This ensures that TCBs which are
 | 
			
		||||
     * stored in ready lists (all of which have the same xItemValue value) get a
 | 
			
		||||
     * share of the CPU.  However, if the xItemValue is the same as the back marker
 | 
			
		||||
     * the iteration loop below will not end.  Therefore the value is checked
 | 
			
		||||
     * first, and the algorithm slightly modified if necessary. */
 | 
			
		||||
    if( xValueOfInsertion == portMAX_DELAY )
 | 
			
		||||
    {
 | 
			
		||||
        pxIterator = pxList->xListEnd.pxPrevious;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* *** NOTE ***********************************************************
 | 
			
		||||
        *  If you find your application is crashing here then likely causes are
 | 
			
		||||
        *  listed below.  In addition see https://www.FreeRTOS.org/FAQHelp.html for
 | 
			
		||||
        *  more tips, and ensure configASSERT() is defined!
 | 
			
		||||
        *  https://www.FreeRTOS.org/a00110.html#configASSERT
 | 
			
		||||
        *
 | 
			
		||||
        *   1) Stack overflow -
 | 
			
		||||
        *      see https://www.FreeRTOS.org/Stacks-and-stack-overflow-checking.html
 | 
			
		||||
        *   2) Incorrect interrupt priority assignment, especially on Cortex-M
 | 
			
		||||
        *      parts where numerically high priority values denote low actual
 | 
			
		||||
        *      interrupt priorities, which can seem counter intuitive.  See
 | 
			
		||||
        *      https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html and the definition
 | 
			
		||||
        *      of configMAX_SYSCALL_INTERRUPT_PRIORITY on
 | 
			
		||||
        *      https://www.FreeRTOS.org/a00110.html
 | 
			
		||||
        *   3) Calling an API function from within a critical section or when
 | 
			
		||||
        *      the scheduler is suspended, or calling an API function that does
 | 
			
		||||
        *      not end in "FromISR" from an interrupt.
 | 
			
		||||
        *   4) Using a queue or semaphore before it has been initialised or
 | 
			
		||||
        *      before the scheduler has been started (are interrupts firing
 | 
			
		||||
        *      before vTaskStartScheduler() has been called?).
 | 
			
		||||
        *   5) If the FreeRTOS port supports interrupt nesting then ensure that
 | 
			
		||||
        *      the priority of the tick interrupt is at or below
 | 
			
		||||
        *      configMAX_SYSCALL_INTERRUPT_PRIORITY.
 | 
			
		||||
        **********************************************************************/
 | 
			
		||||
 | 
			
		||||
        for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext )
 | 
			
		||||
        {
 | 
			
		||||
            /* There is nothing to do here, just iterating to the wanted
 | 
			
		||||
             * insertion position. */
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pxNewListItem->pxNext = pxIterator->pxNext;
 | 
			
		||||
    pxNewListItem->pxNext->pxPrevious = pxNewListItem;
 | 
			
		||||
    pxNewListItem->pxPrevious = pxIterator;
 | 
			
		||||
    pxIterator->pxNext = pxNewListItem;
 | 
			
		||||
 | 
			
		||||
    /* Remember which list the item is in.  This allows fast removal of the
 | 
			
		||||
     * item later. */
 | 
			
		||||
    pxNewListItem->pxContainer = pxList;
 | 
			
		||||
 | 
			
		||||
    ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems + 1U );
 | 
			
		||||
 | 
			
		||||
    traceRETURN_vListInsert();
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
 | 
			
		||||
{
 | 
			
		||||
    /* The list item knows which list it is in.  Obtain the list from the list
 | 
			
		||||
     * item. */
 | 
			
		||||
    List_t * const pxList = pxItemToRemove->pxContainer;
 | 
			
		||||
 | 
			
		||||
    traceENTER_uxListRemove( pxItemToRemove );
 | 
			
		||||
 | 
			
		||||
    pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
 | 
			
		||||
    pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
 | 
			
		||||
 | 
			
		||||
    /* Only used during decision coverage testing. */
 | 
			
		||||
    mtCOVERAGE_TEST_DELAY();
 | 
			
		||||
 | 
			
		||||
    /* Make sure the index is left pointing to a valid item. */
 | 
			
		||||
    if( pxList->pxIndex == pxItemToRemove )
 | 
			
		||||
    {
 | 
			
		||||
        pxList->pxIndex = pxItemToRemove->pxPrevious;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        mtCOVERAGE_TEST_MARKER();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pxItemToRemove->pxContainer = NULL;
 | 
			
		||||
    ( pxList->uxNumberOfItems ) = ( UBaseType_t ) ( pxList->uxNumberOfItems - 1U );
 | 
			
		||||
 | 
			
		||||
    traceRETURN_uxListRemove( pxList->uxNumberOfItems );
 | 
			
		||||
 | 
			
		||||
    return pxList->uxNumberOfItems;
 | 
			
		||||
}
 | 
			
		||||
/*-----------------------------------------------------------*/
 | 
			
		||||
							
								
								
									
										429
									
								
								port.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429
									
								
								port.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,429 @@
 | 
			
		||||
/*
 | 
			
		||||
 * FreeRTOS Kernel V11.1.0
 | 
			
		||||
 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: MIT
 | 
			
		||||
 *
 | 
			
		||||
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
 * this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
 * the Software without restriction, including without limitation the rights to
 | 
			
		||||
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
 * the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
 * subject to the following conditions:
 | 
			
		||||
 *
 | 
			
		||||
 * The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
 * copies or substantial portions of the Software.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 *
 | 
			
		||||
 * https://www.FreeRTOS.org
 | 
			
		||||
 * https://github.com/FreeRTOS
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *
 | 
			
		||||
 * Changes from V2.6.0
 | 
			
		||||
 *
 | 
			
		||||
 + AVR port - Replaced the inb() and outb() functions with direct memory
 | 
			
		||||
 +    access.  This allows the port to be built with the 20050414 build of
 | 
			
		||||
 +    WinAVR.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 #include <stdlib.h>
 | 
			
		||||
 #include <avr/interrupt.h>
 | 
			
		||||
 
 | 
			
		||||
 #include "FreeRTOS.h"
 | 
			
		||||
 #include "task.h"
 | 
			
		||||
 
 | 
			
		||||
 /*-----------------------------------------------------------
 | 
			
		||||
 * Implementation of functions defined in portable.h for the AVR port.
 | 
			
		||||
 *----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* Start tasks with interrupts enables. */
 | 
			
		||||
 #define portFLAGS_INT_ENABLED                   ( ( StackType_t ) 0x80 )
 | 
			
		||||
 
 | 
			
		||||
 /* Hardware constants for timer 1. */
 | 
			
		||||
 #define portCLEAR_COUNTER_ON_MATCH              ( ( uint8_t ) 0x08 )
 | 
			
		||||
 #define portPRESCALE_64                         ( ( uint8_t ) 0x03 )
 | 
			
		||||
 #define portCLOCK_PRESCALER                     ( ( uint32_t ) 64 )
 | 
			
		||||
 #define portCOMPARE_MATCH_A_INTERRUPT_ENABLE    ( ( uint8_t ) 0x02 )
 | 
			
		||||
 
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /* We require the address of the pxCurrentTCB variable, but don't want to know
 | 
			
		||||
  * any details of its type. */
 | 
			
		||||
 typedef void TCB_t;
 | 
			
		||||
 extern volatile TCB_t * volatile pxCurrentTCB;
 | 
			
		||||
 
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Macro to save all the general purpose registers, the save the stack pointer
 | 
			
		||||
  * into the TCB.
 | 
			
		||||
  *
 | 
			
		||||
  * The first thing we do is save the flags then disable interrupts.  This is to
 | 
			
		||||
  * guard our stack against having a context switch interrupt after we have already
 | 
			
		||||
  * pushed the registers onto the stack - causing the 32 registers to be on the
 | 
			
		||||
  * stack twice.
 | 
			
		||||
  *
 | 
			
		||||
  * r1 is set to zero as the compiler expects it to be thus, however some
 | 
			
		||||
  * of the math routines make use of R1.
 | 
			
		||||
  *
 | 
			
		||||
  * The interrupts will have been disabled during the call to portSAVE_CONTEXT()
 | 
			
		||||
  * so we need not worry about reading/writing to the stack pointer.
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
 #define portSAVE_CONTEXT()                               \
 | 
			
		||||
	 asm volatile ( "push   r0                      \n\t" \
 | 
			
		||||
					"in     r0, __SREG__            \n\t" \
 | 
			
		||||
					"cli                            \n\t" \
 | 
			
		||||
					"push   r0                      \n\t" \
 | 
			
		||||
					"push   r1                      \n\t" \
 | 
			
		||||
					"clr    r1                      \n\t" \
 | 
			
		||||
					"push   r2                      \n\t" \
 | 
			
		||||
					"push   r3                      \n\t" \
 | 
			
		||||
					"push   r4                      \n\t" \
 | 
			
		||||
					"push   r5                      \n\t" \
 | 
			
		||||
					"push   r6                      \n\t" \
 | 
			
		||||
					"push   r7                      \n\t" \
 | 
			
		||||
					"push   r8                      \n\t" \
 | 
			
		||||
					"push   r9                      \n\t" \
 | 
			
		||||
					"push   r10                     \n\t" \
 | 
			
		||||
					"push   r11                     \n\t" \
 | 
			
		||||
					"push   r12                     \n\t" \
 | 
			
		||||
					"push   r13                     \n\t" \
 | 
			
		||||
					"push   r14                     \n\t" \
 | 
			
		||||
					"push   r15                     \n\t" \
 | 
			
		||||
					"push   r16                     \n\t" \
 | 
			
		||||
					"push   r17                     \n\t" \
 | 
			
		||||
					"push   r18                     \n\t" \
 | 
			
		||||
					"push   r19                     \n\t" \
 | 
			
		||||
					"push   r20                     \n\t" \
 | 
			
		||||
					"push   r21                     \n\t" \
 | 
			
		||||
					"push   r22                     \n\t" \
 | 
			
		||||
					"push   r23                     \n\t" \
 | 
			
		||||
					"push   r24                     \n\t" \
 | 
			
		||||
					"push   r25                     \n\t" \
 | 
			
		||||
					"push   r26                     \n\t" \
 | 
			
		||||
					"push   r27                     \n\t" \
 | 
			
		||||
					"push   r28                     \n\t" \
 | 
			
		||||
					"push   r29                     \n\t" \
 | 
			
		||||
					"push   r30                     \n\t" \
 | 
			
		||||
					"push   r31                     \n\t" \
 | 
			
		||||
					"lds    r26, pxCurrentTCB       \n\t" \
 | 
			
		||||
					"lds    r27, pxCurrentTCB + 1   \n\t" \
 | 
			
		||||
					"in     r0, 0x3d                \n\t" \
 | 
			
		||||
					"st     x+, r0                  \n\t" \
 | 
			
		||||
					"in     r0, 0x3e                \n\t" \
 | 
			
		||||
					"st     x+, r0                  \n\t" \
 | 
			
		||||
					);
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Opposite to portSAVE_CONTEXT().  Interrupts will have been disabled during
 | 
			
		||||
  * the context save so we can write to the stack pointer.
 | 
			
		||||
  */
 | 
			
		||||
 
 | 
			
		||||
 #define portRESTORE_CONTEXT()                            \
 | 
			
		||||
	 asm volatile ( "lds    r26, pxCurrentTCB       \n\t" \
 | 
			
		||||
					"lds    r27, pxCurrentTCB + 1   \n\t" \
 | 
			
		||||
					"ld     r28, x+                 \n\t" \
 | 
			
		||||
					"out    __SP_L__, r28           \n\t" \
 | 
			
		||||
					"ld     r29, x+                 \n\t" \
 | 
			
		||||
					"out    __SP_H__, r29           \n\t" \
 | 
			
		||||
					"pop    r31                     \n\t" \
 | 
			
		||||
					"pop    r30                     \n\t" \
 | 
			
		||||
					"pop    r29                     \n\t" \
 | 
			
		||||
					"pop    r28                     \n\t" \
 | 
			
		||||
					"pop    r27                     \n\t" \
 | 
			
		||||
					"pop    r26                     \n\t" \
 | 
			
		||||
					"pop    r25                     \n\t" \
 | 
			
		||||
					"pop    r24                     \n\t" \
 | 
			
		||||
					"pop    r23                     \n\t" \
 | 
			
		||||
					"pop    r22                     \n\t" \
 | 
			
		||||
					"pop    r21                     \n\t" \
 | 
			
		||||
					"pop    r20                     \n\t" \
 | 
			
		||||
					"pop    r19                     \n\t" \
 | 
			
		||||
					"pop    r18                     \n\t" \
 | 
			
		||||
					"pop    r17                     \n\t" \
 | 
			
		||||
					"pop    r16                     \n\t" \
 | 
			
		||||
					"pop    r15                     \n\t" \
 | 
			
		||||
					"pop    r14                     \n\t" \
 | 
			
		||||
					"pop    r13                     \n\t" \
 | 
			
		||||
					"pop    r12                     \n\t" \
 | 
			
		||||
					"pop    r11                     \n\t" \
 | 
			
		||||
					"pop    r10                     \n\t" \
 | 
			
		||||
					"pop    r9                      \n\t" \
 | 
			
		||||
					"pop    r8                      \n\t" \
 | 
			
		||||
					"pop    r7                      \n\t" \
 | 
			
		||||
					"pop    r6                      \n\t" \
 | 
			
		||||
					"pop    r5                      \n\t" \
 | 
			
		||||
					"pop    r4                      \n\t" \
 | 
			
		||||
					"pop    r3                      \n\t" \
 | 
			
		||||
					"pop    r2                      \n\t" \
 | 
			
		||||
					"pop    r1                      \n\t" \
 | 
			
		||||
					"pop    r0                      \n\t" \
 | 
			
		||||
					"out    __SREG__, r0            \n\t" \
 | 
			
		||||
					"pop    r0                      \n\t" \
 | 
			
		||||
					);
 | 
			
		||||
 
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Perform hardware setup to enable ticks from timer 1, compare match A.
 | 
			
		||||
  */
 | 
			
		||||
 static void prvSetupTimerInterrupt( void );
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * See header file for description.
 | 
			
		||||
  */
 | 
			
		||||
 StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
 | 
			
		||||
									  TaskFunction_t pxCode,
 | 
			
		||||
									  void * pvParameters )
 | 
			
		||||
 {
 | 
			
		||||
	 uint16_t usAddress;
 | 
			
		||||
 
 | 
			
		||||
	 /* Place a few bytes of known values on the bottom of the stack.
 | 
			
		||||
	  * This is just useful for debugging. */
 | 
			
		||||
 
 | 
			
		||||
	 *pxTopOfStack = 0x11;
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = 0x22;
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = 0x33;
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 /* Simulate how the stack would look after a call to vPortYield() generated by
 | 
			
		||||
	  * the compiler. */
 | 
			
		||||
 
 | 
			
		||||
	 /*lint -e950 -e611 -e923 Lint doesn't like this much - but nothing I can do about it. */
 | 
			
		||||
 
 | 
			
		||||
	 /* The start of the task code will be popped off the stack last, so place
 | 
			
		||||
	  * it on first. */
 | 
			
		||||
	 usAddress = ( uint16_t ) pxCode;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 usAddress >>= 8;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 /* Next simulate the stack as if after a call to portSAVE_CONTEXT().
 | 
			
		||||
	  *  portSAVE_CONTEXT places the flags on the stack immediately after r0
 | 
			
		||||
	  *  to ensure the interrupts get disabled as soon as possible, and so ensuring
 | 
			
		||||
	  *  the stack use is minimal should a context switch interrupt occur. */
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = portFLAGS_INT_ENABLED;
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
	 /* Now the remaining registers.   The compiler expects R1 to be 0. */
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x00; /* R1 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x02; /* R2 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x03; /* R3 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x04; /* R4 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x05; /* R5 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x06; /* R6 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x07; /* R7 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x08; /* R8 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x09; /* R9 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x10; /* R10 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x11; /* R11 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x12; /* R12 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x13; /* R13 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x14; /* R14 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x15; /* R15 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x16; /* R16 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x17; /* R17 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x18; /* R18 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x19; /* R19 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x20; /* R20 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x21; /* R21 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x22; /* R22 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x23; /* R23 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 /* Place the parameter on the stack in the expected location. */
 | 
			
		||||
	 usAddress = ( uint16_t ) pvParameters;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 usAddress >>= 8;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x26;  /* R26 X */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x27;  /* R27 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x28;  /* R28 Y */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x29;  /* R29 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x30;  /* R30 Z */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
	 *pxTopOfStack = ( StackType_t ) 0x031; /* R31 */
 | 
			
		||||
	 pxTopOfStack--;
 | 
			
		||||
 
 | 
			
		||||
	 /*lint +e950 +e611 +e923 */
 | 
			
		||||
 
 | 
			
		||||
	 return pxTopOfStack;
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 BaseType_t xPortStartScheduler( void )
 | 
			
		||||
 {
 | 
			
		||||
	 /* Setup the hardware to generate the tick. */
 | 
			
		||||
	 prvSetupTimerInterrupt();
 | 
			
		||||
 
 | 
			
		||||
	 /* Restore the context of the first task that is going to run. */
 | 
			
		||||
	 portRESTORE_CONTEXT();
 | 
			
		||||
 
 | 
			
		||||
	 /* Simulate a function call end as generated by the compiler.  We will now
 | 
			
		||||
	  * jump to the start of the task the context of which we have just restored. */
 | 
			
		||||
	 asm volatile ( "ret" );
 | 
			
		||||
 
 | 
			
		||||
	 /* Should not get here. */
 | 
			
		||||
	 return pdTRUE;
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 void vPortEndScheduler( void )
 | 
			
		||||
 {
 | 
			
		||||
	 /* It is unlikely that the AVR port will get stopped.  If required simply
 | 
			
		||||
	  * disable the tick interrupt here. */
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Manual context switch.  The first thing we do is save the registers so we
 | 
			
		||||
  * can use a naked attribute.
 | 
			
		||||
  */
 | 
			
		||||
 void vPortYield( void ) __attribute__( ( naked ) );
 | 
			
		||||
 void vPortYield( void )
 | 
			
		||||
 {
 | 
			
		||||
	 portSAVE_CONTEXT();
 | 
			
		||||
	 vTaskSwitchContext();
 | 
			
		||||
	 portRESTORE_CONTEXT();
 | 
			
		||||
 
 | 
			
		||||
	 asm volatile ( "ret" );
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Context switch function used by the tick.  This must be identical to
 | 
			
		||||
  * vPortYield() from the call to vTaskSwitchContext() onwards.  The only
 | 
			
		||||
  * difference from vPortYield() is the tick count is incremented as the
 | 
			
		||||
  * call comes from the tick ISR.
 | 
			
		||||
  */
 | 
			
		||||
 void vPortYieldFromTick( void ) __attribute__( ( naked ) );
 | 
			
		||||
 void vPortYieldFromTick( void )
 | 
			
		||||
 {
 | 
			
		||||
	 portSAVE_CONTEXT();
 | 
			
		||||
 
 | 
			
		||||
	 if( xTaskIncrementTick() != pdFALSE )
 | 
			
		||||
	 {
 | 
			
		||||
		 vTaskSwitchContext();
 | 
			
		||||
	 }
 | 
			
		||||
 
 | 
			
		||||
	 portRESTORE_CONTEXT();
 | 
			
		||||
 
 | 
			
		||||
	 asm volatile ( "ret" );
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Setup timer 1 compare match A to generate a tick interrupt.
 | 
			
		||||
  */
 | 
			
		||||
 static void prvSetupTimerInterrupt( void )
 | 
			
		||||
 {
 | 
			
		||||
	 uint32_t ulCompareMatch;
 | 
			
		||||
	 uint8_t ucHighByte, ucLowByte;
 | 
			
		||||
 
 | 
			
		||||
	 /* Using 16bit timer 1 to generate the tick.  Correct fuses must be
 | 
			
		||||
	  * selected for the configCPU_CLOCK_HZ clock. */
 | 
			
		||||
 
 | 
			
		||||
	 ulCompareMatch = configCPU_CLOCK_HZ / configTICK_RATE_HZ;
 | 
			
		||||
 
 | 
			
		||||
	 /* We only have 16 bits so have to scale to get our required tick rate. */
 | 
			
		||||
	 ulCompareMatch /= portCLOCK_PRESCALER;
 | 
			
		||||
 
 | 
			
		||||
	 /* Adjust for correct value. */
 | 
			
		||||
	 ulCompareMatch -= ( uint32_t ) 1;
 | 
			
		||||
 
 | 
			
		||||
	 /* Setup compare match value for compare match A.  Interrupts are disabled
 | 
			
		||||
	  * before this is called so we need not worry here. */
 | 
			
		||||
	 ucLowByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
 | 
			
		||||
	 ulCompareMatch >>= 8;
 | 
			
		||||
	 ucHighByte = ( uint8_t ) ( ulCompareMatch & ( uint32_t ) 0xff );
 | 
			
		||||
	 OCR1AH = ucHighByte;
 | 
			
		||||
	 OCR1AL = ucLowByte;
 | 
			
		||||
 
 | 
			
		||||
	 /* Setup clock source and compare match behaviour. */
 | 
			
		||||
	 ucLowByte = portCLEAR_COUNTER_ON_MATCH | portPRESCALE_64;
 | 
			
		||||
	 TCCR1B = ucLowByte;
 | 
			
		||||
 
 | 
			
		||||
	 /* Enable the interrupt - this is okay as interrupt are currently globally
 | 
			
		||||
	  * disabled. */
 | 
			
		||||
	 ucLowByte = TIMSK1;
 | 
			
		||||
	 ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE;
 | 
			
		||||
	 TIMSK1 = ucLowByte;
 | 
			
		||||
 }
 | 
			
		||||
 /*-----------------------------------------------------------*/
 | 
			
		||||
 
 | 
			
		||||
 #if configUSE_PREEMPTION == 1
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Tick ISR for preemptive scheduler.  We can use a naked attribute as
 | 
			
		||||
  * the context is saved at the start of vPortYieldFromTick().  The tick
 | 
			
		||||
  * count is incremented after the context is saved.
 | 
			
		||||
  */
 | 
			
		||||
	 void TIMER1_COMPA_vect( void ) __attribute__( ( signal, naked ) );
 | 
			
		||||
	 void TIMER1_COMPA_vect( void )
 | 
			
		||||
	 {
 | 
			
		||||
		 vPortYieldFromTick();
 | 
			
		||||
		 asm volatile ( "reti" );
 | 
			
		||||
	 }
 | 
			
		||||
 #else
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
  * Tick ISR for the cooperative scheduler.  All this does is increment the
 | 
			
		||||
  * tick count.  We don't need to switch context, this can only be done by
 | 
			
		||||
  * manual calls to taskYIELD();
 | 
			
		||||
  */
 | 
			
		||||
	 void TIMER1_COMPA_vect( void ) __attribute__( ( signal ) );
 | 
			
		||||
	 void TIMER1_COMPA_vect( void )
 | 
			
		||||
	 {
 | 
			
		||||
		 xTaskIncrementTick();
 | 
			
		||||
	 }
 | 
			
		||||
 #endif /* if configUSE_PREEMPTION == 1 */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1718
									
								
								stream_buffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1718
									
								
								stream_buffer.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Reference in New Issue
	
	Block a user