signed portBASE_TYPE xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, unsigned portBASE_TYPE uxPriority, unsigned portBASE_TYPE uxIndex ) { signed portBASE_TYPE xReturn; corCRCB *pxCoRoutine; /* Allocate the memory that will store the co-routine control block. */ pxCoRoutine = ( corCRCB * ) pvPortMalloc( sizeof( corCRCB ) ); 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 xListItem. 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 ), configMAX_PRIORITIES - ( portTickType ) 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; }
static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, Timer_t *pxNewTimer ) { /* 0 is not a valid value for xTimerPeriodInTicks. */ configASSERT( ( xTimerPeriodInTicks > 0 ) ); if( pxNewTimer != NULL ) { /* Ensure the infrastructure used by the timer service task has been created/initialised. */ prvCheckForValidListAndQueue(); /* Initialise the timer structure members using the function parameters. */ pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; pxNewTimer->uxAutoReload = uxAutoReload; pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pxCallbackFunction = pxCallbackFunction; vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); traceTIMER_CREATE( pxNewTimer ); } }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); #if ( configQUEUE_REGISTRY_SIZE > 0 ) { vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" ); } #endif /* configQUEUE_REGISTRY_SIZE */ /* If the trace recorder code is included name the semaphore for viewing in FreeRTOS+Trace. */ #if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 ) { extern QueueHandle_t xNetworkEventQueue; vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" ); vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" ); } #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */ if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. No storage is allocated to the buffers yet. */ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL; vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { /* In case alternative locking is used, the mutexes can be initialised here */ ipconfigBUFFER_ALLOC_INIT( ); /* * HT: The use of counting semaphores is perfect, good invention * It is just that I didn't find the time yet to adopt the newer FreeRTOS kernel * which supports it. I tried it and it crashed. Must dive into it some day */ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
BaseType_t xNetworkBuffersInitialise( void ) { BaseType_t xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { /* In case alternative locking is used, the mutexes can be initialised here */ ipconfigBUFFER_ALLOC_INIT(); xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
xSocket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol ) { xFreeRTOS_Socket_t *pxSocket; /* Only UDP on Ethernet is currently supported. */ configASSERT( xDomain == FREERTOS_AF_INET ); configASSERT( xType == FREERTOS_SOCK_DGRAM ); configASSERT( xProtocol == FREERTOS_IPPROTO_UDP ); configASSERT( listLIST_IS_INITIALISED( &xBoundSocketsList ) ); /* Allocate the structure that will hold the socket information. */ pxSocket = ( xFreeRTOS_Socket_t * ) pvPortMalloc( sizeof( xFreeRTOS_Socket_t ) ); if( pxSocket == NULL ) { pxSocket = ( xFreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET; iptraceFAILED_TO_CREATE_SOCKET(); } else { /* Initialise the socket's members. The semaphore will be created if the socket is bound to an address, for now the pointer to the semaphore is just set to NULL to show it has not been created. */ pxSocket->xWaitingPacketSemaphore = NULL; vListInitialise( &( pxSocket->xWaitingPacketsList ) ); vListInitialiseItem( &( pxSocket->xBoundSocketListItem ) ); listSET_LIST_ITEM_OWNER( &( pxSocket->xBoundSocketListItem ), ( void * ) pxSocket ); pxSocket->xSendBlockTime = ( TickType_t ) 0; pxSocket->xReceiveBlockTime = portMAX_DELAY; pxSocket->ucSocketOptions = FREERTOS_SO_UDPCKSUM_OUT; #if ipconfigSUPPORT_SELECT_FUNCTION == 1 pxSocket->xSelectQueue = NULL; #endif } /* Remove compiler warnings in the case the configASSERT() is not defined. */ ( void ) xDomain; ( void ) xType; ( void ) xProtocol; return ( xSocket_t ) pxSocket; }
portBASE_TYPE xNetworkBuffersInitialise( void ) { portBASE_TYPE xReturn, x; /* Only initialise the buffers and their associated kernel objects if they have not been initialised before. */ if( xNetworkBufferSemaphore == NULL ) { xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFERS, ipconfigNUM_NETWORK_BUFFERS ); configASSERT( xNetworkBufferSemaphore ); if( xNetworkBufferSemaphore != NULL ) { vListInitialise( &xFreeBuffersList ); /* Initialise all the network buffers. The buffer storage comes from the network interface, and different hardware has different requirements. */ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers ); for( x = 0; x < ipconfigNUM_NETWORK_BUFFERS; x++ ) { /* Initialise and set the owner of the buffer list items. */ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) ); listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] ); /* Currently, all buffers are available for use. */ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) ); } } } if( xNetworkBufferSemaphore == NULL ) { xReturn = pdFAIL; } else { xReturn = pdPASS; } return xReturn; }
TimerHandle_t xTimerGenericCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ { Timer_t *pxNewTimer; #if( ( configASSERT_DEFINED == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) { /* Sanity check that the size of the structure used to declare a variable of type StaticTimer_t equals the size of the real timer structures. */ volatile size_t xSize = sizeof( StaticTimer_t ); configASSERT( xSize == sizeof( Timer_t ) ); } #endif /* configASSERT_DEFINED */ /* Allocate the timer structure. */ if( xTimerPeriodInTicks == ( TickType_t ) 0U ) { pxNewTimer = NULL; } else { /* If the user passed in a statically allocated timer structure then use it, otherwise allocate the structure dynamically. */ if( pxTimerBuffer == NULL ) { pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); } else { pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ } if( pxNewTimer != NULL ) { /* Ensure the infrastructure used by the timer service task has been created/initialised. */ prvCheckForValidListAndQueue(); /* Initialise the timer structure members using the function parameters. */ pxNewTimer->pcTimerName = pcTimerName; pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; pxNewTimer->uxAutoReload = uxAutoReload; pxNewTimer->pvTimerID = pvTimerID; pxNewTimer->pxCallbackFunction = pxCallbackFunction; vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); #if( configSUPPORT_STATIC_ALLOCATION == 1 ) { if( pxTimerBuffer == NULL ) { pxNewTimer->ucStaticallyAllocated = pdFALSE; } else { pxNewTimer->ucStaticallyAllocated = pdTRUE; } } #endif /* configSUPPORT_STATIC_ALLOCATION */ traceTIMER_CREATE( pxNewTimer ); } else { traceTIMER_CREATE_FAILED(); } } /* 0 is not a valid value for xTimerPeriodInTicks. */ configASSERT( ( xTimerPeriodInTicks > 0 ) ); return ( TimerHandle_t ) pxNewTimer; }