diff --git a/croutine.c b/croutine.c deleted file mode 100644 index a17475aa6..000000000 --- a/croutine.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * FreeRTOS Kernel - * 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 is 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 = 0; - static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; - -/* 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 ) \ - { \ - if( ( pxCRCB )->uxPriority > uxTopCoRoutineReadyPriority ) \ - { \ - uxTopCoRoutineReadyPriority = ( pxCRCB )->uxPriority; \ - } \ - vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ ( pxCRCB )->uxPriority ] ), &( ( pxCRCB )->xGenericListItem ) ); \ - } - -/* - * 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; - - /* Allocate the memory that will store the co-routine control block. */ - 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; - } - - return xReturn; - } -/*-----------------------------------------------------------*/ - - void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, - List_t * pxEventList ) - { - TickType_t xTimeToWake; - - /* 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 ) ); - } - } -/*-----------------------------------------------------------*/ - - 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 ) - { - /* 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 ); - } - } -/*-----------------------------------------------------------*/ - - 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; - - /* 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; - } - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES == 0 */ diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index 75be8648b..86e4dbde1 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -159,10 +159,6 @@ #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. #endif -#ifndef configUSE_CO_ROUTINES - #define configUSE_CO_ROUTINES 0 -#endif - #ifndef INCLUDE_vTaskPrioritySet #define INCLUDE_vTaskPrioritySet 0 #endif @@ -257,10 +253,8 @@ #define INCLUDE_xTaskGetCurrentTaskHandle 1 #endif -#if configUSE_CO_ROUTINES != 0 - #ifndef configMAX_CO_ROUTINE_PRIORITIES - #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. - #endif +#if ( defined( configUSE_CO_ROUTINES ) && configUSE_CO_ROUTINES != 0 ) + #warning Co-routines have been removed from FreeRTOS-Kernel versions released after V10.5.1. You can view previous versions of the FreeRTOS Kernel at github.com/freertos/freertos-kernel/tree/V10.5.1 . #endif #ifndef configUSE_DAEMON_TASK_STARTUP_HOOK diff --git a/include/croutine.h b/include/croutine.h deleted file mode 100644 index 63d1d94f7..000000000 --- a/include/croutine.h +++ /dev/null @@ -1,753 +0,0 @@ -/* - * FreeRTOS Kernel - * 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, - UBaseType_t ); - -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 ) \ - if( ( xTicksToDelay ) > 0 ) \ - { \ - vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ - } \ - crSET_STATE0( ( xHandle ) ); - -/** - * @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 ) \ - { \ - *( 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; \ - } \ - } - -/** - * 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 ) \ - { \ - *( 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; \ - } \ - } - -/** - * 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 ); - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* CO_ROUTINE_H */ diff --git a/include/queue.h b/include/queue.h index 426de468f..02356766a 100644 --- a/include/queue.h +++ b/include/queue.h @@ -1426,28 +1426,6 @@ BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FU BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; -/* - * The functions defined above are for passing data to and from tasks. The - * functions below are the equivalents for passing data to and from - * co-routines. - * - * These functions are called from the co-routine macro implementation and - * should not be called directly from application code. Instead use the macro - * wrappers defined within croutine.h. - */ -BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, - const void * pvItemToQueue, - BaseType_t xCoRoutinePreviouslyWoken ); -BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, - void * pvBuffer, - BaseType_t * pxTaskWoken ); -BaseType_t xQueueCRSend( QueueHandle_t xQueue, - const void * pvItemToQueue, - TickType_t xTicksToWait ); -BaseType_t xQueueCRReceive( QueueHandle_t xQueue, - void * pvBuffer, - TickType_t xTicksToWait ); - /* * For internal use only. Use xSemaphoreCreateMutex(), * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling diff --git a/queue.c b/queue.c index 86dae0bc4..b75edc933 100644 --- a/queue.c +++ b/queue.c @@ -38,10 +38,6 @@ #include "task.h" #include "queue.h" -#if ( configUSE_CO_ROUTINES == 1 ) - #include "croutine.h" -#endif - /* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified * because 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 @@ -2478,293 +2474,6 @@ BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ /*-----------------------------------------------------------*/ -#if ( configUSE_CO_ROUTINES == 1 ) - - BaseType_t xQueueCRSend( QueueHandle_t xQueue, - const void * pvItemToQueue, - TickType_t xTicksToWait ) - { - BaseType_t xReturn; - Queue_t * const pxQueue = xQueue; - - /* If the queue is already full we may have to block. A critical section - * is required to prevent an interrupt removing something from the queue - * between the check to see if the queue is full and blocking on the queue. */ - portDISABLE_INTERRUPTS(); - { - if( prvIsQueueFull( pxQueue ) != pdFALSE ) - { - /* The queue is full - do we want to block or just leave without - * posting? */ - if( xTicksToWait > ( TickType_t ) 0 ) - { - /* As this is called from a coroutine we cannot block directly, but - * return indicating that we need to block. */ - vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); - portENABLE_INTERRUPTS(); - return errQUEUE_BLOCKED; - } - else - { - portENABLE_INTERRUPTS(); - return errQUEUE_FULL; - } - } - } - portENABLE_INTERRUPTS(); - - portDISABLE_INTERRUPTS(); - { - if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) - { - /* There is room in the queue, copy the data into the queue. */ - prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); - xReturn = pdPASS; - - /* Were any co-routines waiting for data to become available? */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - /* In this instance the co-routine could be placed directly - * into the ready list as we are within a critical section. - * Instead the same pending ready list mechanism is used as if - * the event were caused from within an interrupt. */ - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - /* The co-routine waiting has a higher priority so record - * that a yield might be appropriate. */ - xReturn = errQUEUE_YIELD; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - xReturn = errQUEUE_FULL; - } - } - portENABLE_INTERRUPTS(); - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - BaseType_t xQueueCRReceive( QueueHandle_t xQueue, - void * pvBuffer, - TickType_t xTicksToWait ) - { - BaseType_t xReturn; - Queue_t * const pxQueue = xQueue; - - /* If the queue is already empty we may have to block. A critical section - * is required to prevent an interrupt adding something to the queue - * between the check to see if the queue is empty and blocking on the queue. */ - portDISABLE_INTERRUPTS(); - { - if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) - { - /* There are no messages in the queue, do we want to block or just - * leave with nothing? */ - if( xTicksToWait > ( TickType_t ) 0 ) - { - /* As this is a co-routine we cannot block directly, but return - * indicating that we need to block. */ - vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); - portENABLE_INTERRUPTS(); - return errQUEUE_BLOCKED; - } - else - { - portENABLE_INTERRUPTS(); - return errQUEUE_FULL; - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - portENABLE_INTERRUPTS(); - - portDISABLE_INTERRUPTS(); - { - if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) - { - /* Data is available from the queue. */ - pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; - - if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) - { - pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - --( pxQueue->uxMessagesWaiting ); - ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); - - xReturn = pdPASS; - - /* Were any co-routines waiting for space to become available? */ - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - /* In this instance the co-routine could be placed directly - * into the ready list as we are within a critical section. - * Instead the same pending ready list mechanism is used as if - * the event were caused from within an interrupt. */ - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - xReturn = errQUEUE_YIELD; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - xReturn = pdFAIL; - } - } - portENABLE_INTERRUPTS(); - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, - const void * pvItemToQueue, - BaseType_t xCoRoutinePreviouslyWoken ) - { - Queue_t * const pxQueue = xQueue; - - /* Cannot block within an ISR so if there is no space on the queue then - * exit without doing anything. */ - if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) - { - prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); - - /* We only want to wake one co-routine per ISR, so check that a - * co-routine has not already been woken. */ - if( xCoRoutinePreviouslyWoken == pdFALSE ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) - { - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) - { - return pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - return xCoRoutinePreviouslyWoken; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - -#if ( configUSE_CO_ROUTINES == 1 ) - - BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, - void * pvBuffer, - BaseType_t * pxCoRoutineWoken ) - { - BaseType_t xReturn; - Queue_t * const pxQueue = xQueue; - - /* We cannot block from an ISR, so check there is data available. If - * not then just leave without doing anything. */ - if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) - { - /* Copy the data from the queue. */ - pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; - - if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) - { - pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - --( pxQueue->uxMessagesWaiting ); - ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); - - if( ( *pxCoRoutineWoken ) == pdFALSE ) - { - if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) - { - if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) - { - *pxCoRoutineWoken = pdTRUE; - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - } - else - { - mtCOVERAGE_TEST_MARKER(); - } - - xReturn = pdPASS; - } - else - { - xReturn = pdFAIL; - } - - return xReturn; - } - -#endif /* configUSE_CO_ROUTINES */ -/*-----------------------------------------------------------*/ - #if ( configQUEUE_REGISTRY_SIZE > 0 ) void vQueueAddToRegistry( QueueHandle_t xQueue,