欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > FreeRTOS的事件组

FreeRTOS的事件组

2025/2/10 1:09:00 来源:https://blog.csdn.net/m0_37202877/article/details/144815056  浏览:    关键词:FreeRTOS的事件组

1 创建事件组 xEventGroupCreate

EventGroupHandle_t xEventGroupCreate( void )
{
EventGroup_t *pxEventBits;/* 分配事件组内存。*/pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) );if( pxEventBits != NULL ){pxEventBits->uxEventBits = 0;   // 初始化事件位为0vListInitialise( &( pxEventBits->xTasksWaitingForBits ) );   // 初始化等待事件的任务列表traceEVENT_GROUP_CREATE( pxEventBits );}else{traceEVENT_GROUP_CREATE_FAILED();}return ( EventGroupHandle_t ) pxEventBits;
}

2 事件置位 xEventGroupSetBits

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet )
{
ListItem_t *pxListItem, *pxNext;
ListItem_t const *pxListEnd;
List_t *pxList;
EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
BaseType_t xMatchFound = pdFALSE;/* Check the user is not attempting to set the bits used by the kernelitself. */configASSERT( xEventGroup );configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 );/* 获取事件列表头 */pxList = &( pxEventBits->xTasksWaitingForBits );/* 获取列表尾节点 */pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 The mini list structure is used as the list end to save RAM.  This is checked and valid. *//* 挂起调度器 */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 listitem before removing the task from the event list.  TheeventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knowsthat is was unblocked due to its required bits matching, ratherthan because it timed out. *//* 把任务从事件列表中移除	*/( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );}/* Move onto the next list item.  Note pxListItem->pxNext is notused here as the list item may have been removed from the event listand inserted into the ready/pending reading list. */pxListItem = pxNext;  //当前列表项指向下个,继续遍历}/* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BITbit was set in the control word. */pxEventBits->uxEventBits &= ~uxBitsToClear;  //清除设置后的标志位}( void ) xTaskResumeAll();  //开启调度器return pxEventBits->uxEventBits;
}

3 等待标志位 xEventGroupWaitBits

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait )
{
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn, uxControlBits = 0;
BaseType_t xWaitConditionMet, xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE;/* Check the user is not attempting to wait on the bits used by the kernelitself, 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 ) ) );}#endifvTaskSuspendAll();  //挂起调度器{/* 获取当前的事件标志位 */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 toblock. *//* 已经触发 */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 ){/* 不需要超时,直接返回标志位. */uxReturn = uxCurrentEventBits;}else{/* 事件没有触发,并且需要超时*/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();}/* 把任务添加到事件列表中	*/vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );uxReturn = 0;traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );}}xAlreadyYielded = xTaskResumeAll();  //恢复调度器	if( xTicksToWait != ( TickType_t ) 0 ){if( xAlreadyYielded == pdFALSE ){portYIELD_WITHIN_API();}else{mtCOVERAGE_TEST_MARKER();}/* 任务已经恢复,则复位列表项中的值  复位为任务有优先级 */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 thistask 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();}}taskEXIT_CRITICAL();/* Prevent compiler warnings when trace macros are not used. */xTimeoutOccurred = pdFALSE;}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 );return uxReturn;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com