网站后台管理系统界面,北京seo排名,品牌建设运营规划,wordpress删除空关键词文章目录 基础知识创建信号量获取信号量释放信号量信号量 内部实现框图 基础知识
[FreeRTOS 基础知识] 信号量 概念 创建信号量
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
#define xSe… 文章目录 基础知识创建信号量获取信号量释放信号量信号量 内部实现框图 基础知识
[FreeRTOS 基础知识] 信号量 概念 创建信号量
#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U )
#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U )
#define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE )根据上面的定义可知创建信号量本质就是创建队列。长度第一个参数为1大小第二个参数为0
QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType )- if( uxItemSize ( UBaseType_t ) 0 ) xQueueSizeInBytes ( size_t ) 0;- pxNewQueue ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) xQueueSizeInBytes ); // 动态分配大小只有一个Queue_t结构体大小获取信号量
通过队列获取信号量
#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait )for( ;; )
{taskENTER_CRITICAL(); // 关中断{const UBaseType_t uxSemaphoreCount pxQueue-uxMessagesWaiting; // 获取当前信号量值if( uxSemaphoreCount ( UBaseType_t ) 0 ) // 信号量值大于0{traceQUEUE_RECEIVE( pxQueue );pxQueue-uxMessagesWaiting uxSemaphoreCount - ( UBaseType_t ) 1; // 信号量-1// 检查是否有其他任务阻塞等待信号量。if( listLIST_IS_EMPTY( ( pxQueue-xTasksWaitingToSend ) ) pdFALSE ){// 如果是解除阻塞最高优先级的任务。// 1、将最高阻塞任务从xTasksWaitingToSend链表中移除// 2、将最高阻塞任务从从DelayList移动到ReadyList链表if( xTaskRemoveFromEventList( ( pxQueue-xTasksWaitingToSend ) ) ! pdFALSE ){queueYIELD_IF_USING_PREEMPTION(); // 让出CPU使用权}else{mtCOVERAGE_TEST_MARKER();}}else{mtCOVERAGE_TEST_MARKER();}taskEXIT_CRITICAL(); //开中断return pdPASS; // 返回成功}else{if( xTicksToWait ( TickType_t ) 0 ) // 是否愿意等待{// 不愿意等待taskEXIT_CRITICAL(); // 打开中断traceQUEUE_RECEIVE_FAILED( pxQueue );return errQUEUE_EMPTY; // 返回队列空失败}else if( xEntryTimeSet pdFALSE ){// 信号量计数为0阻塞时间被指定所以配置超时结构准备阻塞。vTaskInternalSetTimeOutState( xTimeOut );xEntryTimeSet pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}}}taskEXIT_CRITICAL();vTaskSuspendAll();prvLockQueue( pxQueue );if( xTaskCheckForTimeOut( xTimeOut, xTicksToWait ) pdFALSE ){if( prvIsQueueEmpty( pxQueue ) ! pdFALSE ){traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue );// 1、当前的任务加入到队列的xTasksWaitingToReceive链表中// 2、当前的任务从ReadyList移动到DelayListvTaskPlaceOnEventList( ( pxQueue-xTasksWaitingToReceive ), xTicksToWait );prvUnlockQueue( pxQueue );if( xTaskResumeAll() pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}} else{prvUnlockQueue( pxQueue );( void ) xTaskResumeAll();}}else{...}释放信号量
#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U )
#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition )
- for( ;; ){taskENTER_CRITICAL(); // 关中断 portDISABLE_INTERRUPTS();{if( ( pxQueue-uxMessagesWaiting pxQueue-uxLength ) || ( xCopyPosition queueOVERWRITE ) ) // 判断当前信号量是否超过队列信号量长度{ traceQUEUE_SEND( pxQueue );xYieldRequired prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );// 不会写数据但是会将 uxMessagesWaiting 1if( listLIST_IS_EMPTY( ( pxQueue-xTasksWaitingToReceive ) ) pdFALSE ) // 判断xTasksWaitingToReceive队列里是否有等待的任务{if( xTaskRemoveFromEventList( ( pxQueue-xTasksWaitingToReceive ) ) ! pdFALSE ) // 1、将要写的任务从xTasksWaitingToReceive移除2、将要写的任务从DelayList移动到ReadyList{queueYIELD_IF_USING_PREEMPTION(); //让出CPU使用权}else{mtCOVERAGE_TEST_MARKER();}} else if( xYieldRequired ! pdFALSE ){queueYIELD_IF_USING_PREEMPTION();}else{mtCOVERAGE_TEST_MARKER();}}taskEXIT_CRITICAL(); // 开中断return pdPASS; // 返回成功}else{if( xTicksToWait ( TickType_t ) 0 ){taskEXIT_CRITICAL();traceQUEUE_SEND_FAILED( pxQueue );return errQUEUE_FULL; // 返回队列已满}else if( xEntryTimeSet pdFALSE ){vTaskInternalSetTimeOutState( xTimeOut ); // 阻塞时间被指定所以配置超时结构。 xEntryTimeSet pdTRUE;}else{mtCOVERAGE_TEST_MARKER();}}
}
taskEXIT_CRITICAL(); // 开中断vTaskSuspendAll();
prvLockQueue( pxQueue );if( xTaskCheckForTimeOut( xTimeOut, xTicksToWait ) pdFALSE )
{if( prvIsQueueFull( pxQueue ) ! pdFALSE ){traceBLOCKING_ON_QUEUE_SEND( pxQueue );// 1、当前的任务加入到队列的xTasksWaitingToSend链表中// 2、当前的任务从ReadyList移动到DelayList vTaskPlaceOnEventList( ( pxQueue-xTasksWaitingToSend ), xTicksToWait );prvUnlockQueue( pxQueue );if( xTaskResumeAll() pdFALSE ){portYIELD_WITHIN_API();}}else{prvUnlockQueue( pxQueue );( void ) xTaskResumeAll();}
}
else
{prvUnlockQueue( pxQueue );( void ) xTaskResumeAll();traceQUEUE_SEND_FAILED( pxQueue );return errQUEUE_FULL;
}
}信号量 内部实现框图