国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FreeRTOS源碼分析-10 互斥信號(hào)量

這篇具有很好參考價(jià)值的文章主要介紹了FreeRTOS源碼分析-10 互斥信號(hào)量。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

目錄

?

1 事件標(biāo)志組概念及其應(yīng)用

1.1 事件標(biāo)志組定義

1.2 FreeRTOS事件標(biāo)志組介紹

1.3 FreeRTOS事件標(biāo)志組工作原理

2 事件標(biāo)志組應(yīng)用

2.1 功能需求

2.2 API

?2.3 功能實(shí)現(xiàn)

3 事件標(biāo)志組原理

3.1 事件標(biāo)志組控制塊

3.2 事件標(biāo)志組獲取標(biāo)志位

3.3?等待事件標(biāo)志觸發(fā)

3.4 事件標(biāo)志組設(shè)置標(biāo)志位

3.5 事件標(biāo)志組任務(wù)同步


1 事件標(biāo)志組概念及其應(yīng)用

1.1 事件標(biāo)志組定義

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

門鑰匙代表或的問題,每個(gè)都可以開啟
公交車代表與的問題,到齊了才可以走

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

FreeRTOS事件標(biāo)志組一共8個(gè)bit。

如Task 1或Tast 2去觸發(fā)第1位,第1位或第三位能觸發(fā)任務(wù)Task3

如Task 6、7、8同時(shí)置位觸發(fā)Task 4

1.2 FreeRTOS事件標(biāo)志組介紹

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

任務(wù)可以和事件標(biāo)志組進(jìn)行關(guān)聯(lián),如bit23,任務(wù)阻塞等待消息,和消息隊(duì)列一樣有個(gè)超時(shí)機(jī)制

當(dāng)任意任務(wù)或者中斷觸發(fā)置位的時(shí)候,任務(wù)會(huì)從阻塞變?yōu)榫途w態(tài)。

1.3 FreeRTOS事件標(biāo)志組工作原理

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?創(chuàng)建事件控制塊,關(guān)聯(lián)事件,等待事件觸發(fā)

2 事件標(biāo)志組應(yīng)用

2.1 功能需求

  • 1、使用事件標(biāo)志組檢測多個(gè)按鍵輸入(K3、K4、K5、K6)
  • 2、當(dāng)檢測到任何一個(gè)按鍵按下,串口打印輸出按鍵信息
  • 3、當(dāng)4路按鍵都已經(jīng)按下,觸發(fā)蜂鳴器報(bào)警

2.2 API

CubeMX中未提供,需要自己創(chuàng)建

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?EventBits_t 返回值返回的是所有24位的值FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

守護(hù)任務(wù):處理操作系統(tǒng)不想在中斷中處理的任務(wù),是一種特殊類型的任務(wù),它在系統(tǒng)中扮演著重要的角色。它被用于監(jiān)控和處理FreeRTOS內(nèi)部的錯(cuò)誤和異常情況,以確保系統(tǒng)的穩(wěn)定性。守護(hù)任務(wù)可以使用軟件定時(shí)器來執(zhí)行一些周期性的任務(wù)。通過創(chuàng)建一個(gè)周期性的軟件定時(shí)器,守護(hù)任務(wù)可以在固定的時(shí)間間隔內(nèi)執(zhí)行特定的操作。例如,守護(hù)任務(wù)可以使用軟件定時(shí)器來定期檢查任務(wù)堆棧的使用情況、檢測任務(wù)優(yōu)先級(jí)錯(cuò)誤或處理未處理的中斷等。軟件定時(shí)器提供了一種簡便的方式來觸發(fā)守護(hù)任務(wù)的執(zhí)行,以確保系統(tǒng)中的重要任務(wù)得到及時(shí)處理。FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

中斷中不允許上下文切換,都是由守護(hù)任務(wù)來執(zhí)行的。

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32?使用WaitBits,會(huì)讓任務(wù)進(jìn)入阻塞態(tài)

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?參數(shù)解釋:

  • xEventGroup:事件組句柄,表示要操作的事件組。
  • uxBitsToWaitFor:等待的事件位,即需要等待其中的哪些事件發(fā)生。可以使用位掩碼形式指定多個(gè)事件位。若指定為0,則表示不等待任何事件,直接返回當(dāng)前事件組的位狀態(tài)。
  • uxBitsToSet:設(shè)置的事件位,即在等待期間發(fā)生事件后,需要設(shè)置哪些事件位。同樣,可以使用位掩碼指定多個(gè)事件位。
  • xTicksToWait:等待的超時(shí)時(shí)間,以FreeRTOS的Tick單位表示??梢栽O(shè)置為portMAX_DELAY表示無限等待,或者具體的等待時(shí)間。

返回值:

  • 返回已經(jīng)發(fā)生的事件位,即滿足等待條件的事件。如果等待發(fā)生事件時(shí)超時(shí),則返回0。

使用xEvetnGroupSync函數(shù)的具體步驟如下:

  1. 創(chuàng)建或獲取一個(gè)事件組句柄。
  2. 使用xEvetnGroupSync函數(shù)等待指定的事件位??梢栽O(shè)置需要等待的事件位、需要設(shè)置的事件位和等待超時(shí)時(shí)間。
  3. 根據(jù)返回值判斷等待是否成功,根據(jù)已發(fā)生的事件位執(zhí)行相應(yīng)的操作。

注意,xEvetnGroupSync函數(shù)是一個(gè)阻塞函數(shù),即在等待期間會(huì)阻塞當(dāng)前任務(wù)的執(zhí)行。如果有其他任務(wù)在等待相同的事件組,則它們可能會(huì)被喚醒以執(zhí)行后續(xù)操作。因此,在使用xEvetnGroupSync函數(shù)時(shí)需要謹(jǐn)慎設(shè)計(jì),以避免出現(xiàn)死鎖或優(yōu)先級(jí)反轉(zhuǎn)等問題。

?2.3 功能實(shí)現(xiàn)

STM32CubeMX功能配置

GPIO略

根據(jù)接口說明 ,事件標(biāo)志組中斷中需要開啟守護(hù)任務(wù)

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

按鍵中斷及事件標(biāo)志組創(chuàng)建

//freertos.c

//...略
#include "event_groups.h"

EventGroupHandle_t KeyEventGroup; //全局變量句柄

void MX_FREERTOS_Init(void) {

	//創(chuàng)建
	KeyEventGroup = xEventGroupCreate();
	if(KeyEventGroup == NULL){
		printf("KeyEventGroup Create Error\r\n");
	}

    //...略
}

按鍵檢測任務(wù)和蜂鳴器報(bào)警任務(wù)

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

//gpio.c

#include "event_groups.h"

//...略
/*  
#define KEY3_EVENT_BIT  (1<<0)
#define KEY4_EVENT_BIT  (1<<1)
#define KEY5_EVENT_BIT  (1<<2)
#define KEY6_EVENT_BIT  (1<<3) 
	 
typedef enum
{
	KEY_DOWN,
	KEY_UP,
	KEY_RESET

}teKeyStatus;

*/

teKeyStatus KeyStatus;
extern EventGroupHandle_t KeyEventGroup;


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){

	if(Key3_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET)
            {
                //設(shè)置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY3_EVENT_BIT,NULL);
			}
		}
	}
	
	if(Key4_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET)
            {
                //設(shè)置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY4_EVENT_BIT,NULL);
			}
		}
	}

	if(Key5_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET)
            {
                //設(shè)置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY5_EVENT_BIT,NULL);
			}
		}
	}

	if(Key6_Pin == GPIO_Pin)
    {
		if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET)
        {
			HAL_Delay(10);
			if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET)
            {
                //設(shè)置事件
				xEventGroupSetBitsFromISR(KeyEventGroup,KEY6_EVENT_BIT,NULL);
			}
		}
	}
}
//freertos.c



void Delay_Task(void const * argument)
{
  /* USER CODE BEGIN Delay_Task */
	EventBits_t KeyEventBits;
  /* Infinite loop */
  for(;;)
  {
	  KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
							KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
								pdFALSE,
								pdFALSE,
								portMAX_DELAY);
	  printf("Key is Down Key Event Bit is %x\r\n",KeyEventBits);
	  osDelay(10);
  }
}




void High_Task(void const * argument)
{
  EventBits_t KeyEventBits;
  for(;;)
  {
	  KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
							KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
								pdTRUE,
								pdTRUE,
								portMAX_DELAY);	
	  if(KeyEventBits == (KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT))
      {
		printf("Buzzer is Toggle\r\n");
		HAL_GPIO_TogglePin(Buzzer_GPIO_Port,Buzzer_Pin);
	  }
      osDelay(10);
  }
}

3 事件標(biāo)志組原理

3.1 事件標(biāo)志組控制塊

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32


	
	#define eventCLEAR_EVENTS_ON_EXIT_BIT	0x01000000UL		//表示退出是否清楚已經(jīng)觸發(fā)的標(biāo)志位 25bit表示
	#define eventUNBLOCKED_DUE_TO_BIT_SET	0x02000000UL		//解除阻塞是否,已經(jīng)設(shè)置標(biāo)志位 26位
	#define eventWAIT_FOR_ALL_BITS			0x04000000UL		//是與邏輯還是或邏輯
	#define eventEVENT_BITS_CONTROL_BYTES	0xff000000UL		//用于分解出,事件標(biāo)志組位使用

typedef struct xEventGroupDefinition
{
	//事件標(biāo)志組
	EventBits_t uxEventBits;
	//任務(wù)等待的列表
	List_t xTasksWaitingForBits;		/*< List of tasks waiting for a bit to be set. */
} EventGroup_t;

3.2 事件標(biāo)志組獲取標(biāo)志位

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?全局變量一定要保護(hù),所以要進(jìn)入臨界段

#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )

/*
	參數(shù):
	1、控制塊/句柄
	2、要清除位
	返回值:
		事件標(biāo)志位

*/ 1<<0
EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear )
{
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn;

	/*
		1、進(jìn)入臨界段
		2、獲取當(dāng)前事件標(biāo)志位
		3、清除要設(shè)置的事件標(biāo)志位
		4、退出臨界段
		5、返回事件標(biāo)志組值
	
	*/
	taskENTER_CRITICAL();
	{

		/* 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();

	return uxReturn;
}

/*
	參數(shù):	
		1、事件控制塊
	返回值:
		事件標(biāo)志位

*/
EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup )
{
UBaseType_t uxSavedInterruptStatus;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
EventBits_t uxReturn;
	
	//禁止中斷 帶返回值
	uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();
	{
		//獲取事件標(biāo)志位
		uxReturn = pxEventBits->uxEventBits;
	}
	//恢復(fù)中斷,在進(jìn)入禁止之前的狀態(tài)
	portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

	return uxReturn;
}

3.3?等待事件標(biāo)志觸發(fā)

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?復(fù)位列表項(xiàng):表示事件信息

/*
	參數(shù):
		1、事件控制塊
		2、要等待出發(fā)的標(biāo)志位
		3、退出是否要清除
		4、與邏輯還是或邏輯
		5、阻塞等待時(shí)間
	返回值:
		當(dāng)前事件標(biāo)志位
*/
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;
	//掛起調(diào)度器
	vTaskSuspendAll();
	{
		//獲取當(dāng)前的事件標(biāo)志位
		const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits;

		/* 檢查是否觸發(fā) 
			參數(shù):	
				1、當(dāng)前的事件標(biāo)志位
				2、要等待觸發(fā)的事件標(biāo)志位
				3、觸發(fā)邏輯???
			返回值:	
				pdFALSE  pdTRUE
		*/
		xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits );

		if( xWaitConditionMet != pdFALSE )
		{
			
			/* 已經(jīng)觸發(fā) */
			uxReturn = uxCurrentEventBits;
			xTicksToWait = ( TickType_t ) 0;

			/* 清楚已經(jīng)觸發(fā)的標(biāo)志 */
			if( xClearOnExit != pdFALSE )
			{
				pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}
		}
		else if( xTicksToWait == ( TickType_t ) 0 )
		{
			/* 不需要超時(shí),直接返回標(biāo)志位. */
			uxReturn = uxCurrentEventBits;
		}
		else
		{
			/* 事件沒有觸發(fā),并且需要超時(shí)*/
			if( xClearOnExit != pdFALSE )
			{
				//uxControlBits = 0x01000000UL;
				uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			if( xWaitForAllBits != pdFALSE )
			{
				//uxControlBits = 0x05000000UL;
				uxControlBits |= eventWAIT_FOR_ALL_BITS;
			}
			else
			{
				mtCOVERAGE_TEST_MARKER();
			}

			/* 把任務(wù)添加到事件列表中
				參數(shù):
					1、列表的地址
					2、傳入列表項(xiàng)值
					3、任務(wù)阻塞時(shí)間

			*/
			vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait );

			uxReturn = 0;

			traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor );
		}
	}
	//恢復(fù)調(diào)度器
	xAlreadyYielded = xTaskResumeAll();
	//再次判斷是否需要超時(shí)
	if( xTicksToWait != ( TickType_t ) 0 )
	{
		if( xAlreadyYielded == pdFALSE )
		{
			//進(jìn)行上下文切換 ->pendSV
			portYIELD_WITHIN_API();
		}
		else
		{
			mtCOVERAGE_TEST_MARKER();
		}

		/* 
			任務(wù)已經(jīng)恢復(fù)
			1、復(fù)位列表項(xiàng)中的值  復(fù)位為任務(wù)有優(yōu)先級(jí)
		*/
		uxReturn = uxTaskResetEventItemValue();
		//是不是通過事件置位解除的任務(wù)
		if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 )
		{
			//進(jìn)入臨界段
			taskENTER_CRITICAL();
			{
				/* 獲取當(dāng)前事件位. */
				uxReturn = pxEventBits->uxEventBits;

				/* 再此判斷是否已經(jīng)置位 */
				if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE )
				{
					//如果需要清除,清除觸發(fā)后的標(biāo)志位
					if( xClearOnExit != pdFALSE )
					{
						pxEventBits->uxEventBits &= ~uxBitsToWaitFor;
					}
					else
					{
						mtCOVERAGE_TEST_MARKER();
					}
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			taskEXIT_CRITICAL();
			xTimeoutOccurred = pdFALSE;
		}
		else
		{
			/* The task unblocked because the bits were set. */
		}

		/* 返回當(dāng)前事件標(biāo)志位. */
		uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES;
	}
	traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred );

	return uxReturn;
}

3.4 事件標(biāo)志組設(shè)置標(biāo)志位

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

/*
	參數(shù):
		1、事件控制塊
		2、要設(shè)置的事件位
	返回值:
		1、當(dāng)前事件標(biāo)志位
*/
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;

	//獲取事件列表頭
	pxList = &( pxEventBits->xTasksWaitingForBits );
	//獲取列表尾節(jié)點(diǎn)
	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. */
	//掛起調(diào)度器
	vTaskSuspendAll();
	{
		//獲取頭節(jié)點(diǎn)
		pxListItem = listGET_HEAD_ENTRY( pxList );

		/* 設(shè)置事件標(biāo)志位 */
		pxEventBits->uxEventBits |= uxBitsToSet;

		/* 循環(huán)遍歷整個(gè)列表項(xiàng),直到列表頭節(jié)點(diǎn)等于尾節(jié)點(diǎn)(指針) */
		while( pxListItem != pxListEnd )
		{
			//獲取下個(gè)列表項(xiàng)
			pxNext = listGET_NEXT( pxListItem );
			//獲取當(dāng)前列表項(xiàng)的值
			uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem );
			//標(biāo)記,是否找到需要處理的節(jié)點(diǎn)
			xMatchFound = pdFALSE;

			/* 拆分*/
			uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES;
			uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES;

			if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 )
			{
				//或邏輯
				/* 等待位已經(jīng)置位 */
				if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 )
				{
					//找到了已經(jīng)觸發(fā)的節(jié)點(diǎn)
					xMatchFound = pdTRUE;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}
			}
			//表示所有等待的位都已經(jīng)觸發(fā)
			else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor )
			{
				/*找到觸發(fā)的節(jié)點(diǎn) */
				xMatchFound = pdTRUE;
			}
			else
			{
				/* Need all bits to be set, but not all the bits were set. */
			}

			if( xMatchFound != pdFALSE )
			{
				/* 是否需要清除 */
				if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 )
				{
					//做個(gè)標(biāo)記
					uxBitsToClear |= uxBitsWaitedFor;
				}
				else
				{
					mtCOVERAGE_TEST_MARKER();
				}

				/* 把任務(wù)從事件列表中移除
					參數(shù):	
						1、列表項(xiàng)
						2、事件標(biāo)志位+解鎖處理標(biāo)志位  內(nèi)部寫入了列表項(xiàng)的value里面

				*/
				( void ) xTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET );
			}

			/* 當(dāng)前列表項(xiàng)指向下個(gè),繼續(xù)遍歷*/
			pxListItem = pxNext;
		}

		/* 清除設(shè)置后的標(biāo)志位 */
		pxEventBits->uxEventBits &= ~uxBitsToClear;
	}
	//開啟調(diào)度器
	( void ) xTaskResumeAll();

	return pxEventBits->uxEventBits;
}

	/*
		參數(shù):
		1、事件控制塊
		2、要設(shè)置的標(biāo)志位
		3、NULL
	*/
	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken )
	{
	BaseType_t xReturn;
		//調(diào)用軟件定時(shí)器函數(shù),,用于發(fā)送消息到軟件定時(shí)器任務(wù),進(jìn)行處理
		xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken );

		return xReturn;
	}
	/*
		設(shè)置事件標(biāo)志位的回調(diào)函數(shù),內(nèi)部其實(shí)就是調(diào)用xEventGroupSetBits
	*/
	void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet )
	{
	( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet );
	}
	
	BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken )
	{
	DaemonTaskMessage_t xMessage;
	BaseType_t xReturn;

		/* 封裝消息 */
		xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR;
		xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend;
		xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1;
		xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2;
		//通過消息隊(duì)列和軟件定時(shí)器任務(wù)進(jìn)行通信
		xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken );
		/*
			分析:
				軟件定時(shí)器任務(wù)要等待消息隊(duì)列,之后解析處理,最終調(diào)用xEventGroupSetBits
		
		*/

		return xReturn;
	}

3.5 事件標(biāo)志組任務(wù)同步

FreeRTOS源碼分析-10 互斥信號(hào)量,FreeRTOS源碼分析,物聯(lián)網(wǎng),單片機(jī),stm32

?待完成文章來源地址http://www.zghlxwxcb.cn/news/detail-631935.html

到了這里,關(guān)于FreeRTOS源碼分析-10 互斥信號(hào)量的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 二、操作系統(tǒng)進(jìn)程管理(10)——用信號(hào)量機(jī)制實(shí)現(xiàn)進(jìn)程互斥、同步、前驅(qū)關(guān)系

    二、操作系統(tǒng)進(jìn)程管理(10)——用信號(hào)量機(jī)制實(shí)現(xiàn)進(jìn)程互斥、同步、前驅(qū)關(guān)系

    ?? ?(1)分析并發(fā)進(jìn)程的關(guān)鍵活動(dòng),劃定臨界區(qū)。(如對(duì)臨界區(qū)資源打印機(jī)的訪問就應(yīng)放在臨界區(qū)) ?? ?(2)設(shè)置互斥信號(hào)量mutex,初值為1。 ?? ?(3)在臨界區(qū)之前執(zhí)行P(mutex)。? ? ? //即使用資源前先申請(qǐng)(P操作) ?? ?(4)在臨界區(qū)之后執(zhí)行V(mutex)。 ?? ?(5)對(duì)不

    2023年04月08日
    瀏覽(18)
  • 線程同步-信號(hào)量-互斥量-條件變量

    線程同步-信號(hào)量-互斥量-條件變量

    線程同步其實(shí)實(shí)現(xiàn)的是線程排隊(duì)。 防止線程同步訪問共享資源造成沖突。 多個(gè)線程訪問共享資源的代碼有可能是同一份代碼,也有可能是不同的代碼;無論是否執(zhí)行同一份代碼,只要這些線程的代碼訪問同一份可變的共享資源,這些線程之間就需要同步。 1. 問題 同一個(gè)進(jìn)程

    2023年04月16日
    瀏覽(22)
  • TinyWebServer學(xué)習(xí)筆記-互斥鎖、信號(hào)量、條件變量

    網(wǎng)站不可能是單線程的,否則網(wǎng)站的性能和響應(yīng)都會(huì)收到嚴(yán)重的影響。因此,這個(gè)項(xiàng)目一定是運(yùn)行在多線程條件下的。而在多線程條件下,對(duì)共享資源的互斥訪問就極其重要。 首先,我們要明確資源的使用一般有三個(gè)步驟: 1、獲取資源 2、使用資源 3、釋放資源 然而,大多

    2024年02月07日
    瀏覽(19)
  • FreeRTOS教程5 信號(hào)量

    正點(diǎn)原子stm32f407探索者開發(fā)板V2.4 STM32CubeMX軟件(Version 6.10.0) Keil μVision5 IDE(MDK-Arm) 野火DAP仿真器 XCOM V2.6串口助手 一個(gè)滑動(dòng)變阻器 本文主要學(xué)習(xí) FreeRTOS 信號(hào)量的相關(guān)知識(shí), 包括創(chuàng)建/刪除信號(hào)量、釋放信號(hào)量、獲取信號(hào)量等知識(shí) 信號(hào)量是進(jìn)程間用于通信的一種手段,其是

    2024年03月15日
    瀏覽(15)
  • 【系統(tǒng)編程】線程安全(POSIX信號(hào)量、互斥鎖、讀寫鎖等)

    【系統(tǒng)編程】線程安全(POSIX信號(hào)量、互斥鎖、讀寫鎖等)

    (??? ),Hello我是 祐言QAQ 我的博客主頁:C/C++語言,數(shù)據(jù)結(jié)構(gòu),Linux基礎(chǔ),ARM開發(fā)板,網(wǎng)絡(luò)編程等領(lǐng)域UP?? 快上??,一起學(xué)習(xí),讓我們成為一個(gè)強(qiáng)大的攻城獅! 送給自己和讀者的一句雞湯??: 集中起來的意志可以擊穿頑石! 作者水平很有限,如果發(fā)現(xiàn)錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論區(qū)指

    2024年02月10日
    瀏覽(106)
  • 【STM32】FreeRTOS消息隊(duì)列和信號(hào)量學(xué)習(xí)

    【STM32】FreeRTOS消息隊(duì)列和信號(hào)量學(xué)習(xí)

    一、消息隊(duì)列(queue) 隊(duì)列是一種用于實(shí)現(xiàn)任務(wù)與任務(wù)之間,任務(wù)與中斷之間消息交流的機(jī)制。 注意:1.數(shù)據(jù)的操作是FIFO模式。 2.隊(duì)列需要明確數(shù)據(jù)的大小和隊(duì)列的長度。 3.寫和讀都會(huì)出現(xiàn)堵塞。 實(shí)驗(yàn):創(chuàng)建一個(gè)消息隊(duì)列,兩個(gè)發(fā)送任務(wù),一個(gè)接收任務(wù)。 其中任務(wù)一任務(wù)三

    2024年02月13日
    瀏覽(17)
  • 一文搞定Linux線程間通訊 / 線程同步方式-互斥鎖、讀寫鎖、自旋鎖、信號(hào)量、條件變量、信號(hào)等等

    目錄 線程間通訊 / 線程同步方式 鎖機(jī)制 互斥鎖(Mutex) 讀寫鎖(rwlock) 自旋鎖(spin) 信號(hào)量機(jī)制(Semaphore) 條件變量機(jī)制 信號(hào)(Signal) 線程間通訊 / 線程同步方式 p.s 以下有很多段落是直接引用,沒有使用 markdown 的 “引用” 格式,出處均已放出。 參考 / 引用: 100as

    2024年02月10日
    瀏覽(24)
  • 【Linux】詳解進(jìn)程通信中信號(hào)量的本質(zhì)&&同步和互斥的概念&&臨界資源和臨界區(qū)的概念

    【Linux】詳解進(jìn)程通信中信號(hào)量的本質(zhì)&&同步和互斥的概念&&臨界資源和臨界區(qū)的概念

    ???????? 訪問資源在安全的前提下,具有一定的順序性,就叫做同步 。在多道程序系統(tǒng)中,由于資源有限,進(jìn)程或線程之間可能產(chǎn)生沖突。同步機(jī)制就是為了解決這些沖突,保證進(jìn)程或線程之間能夠按照既定的順序訪問共享資源。同步機(jī)制有助于避免競態(tài)條件和死鎖(

    2024年04月25日
    瀏覽(91)
  • 第三章 Linux多線程開發(fā) 線程取消 屬性 同步 互斥鎖 死鎖 讀寫鎖 生產(chǎn)者消費(fèi)者 信號(hào)量
  • 6.物聯(lián)網(wǎng)操作系統(tǒng)信號(hào)量

    6.物聯(lián)網(wǎng)操作系統(tǒng)信號(hào)量

    一。信號(hào)量的概念與應(yīng)用 信號(hào)量定義 FreeRTOS信號(hào)量介紹 FreeRTOS信號(hào)量工作原理 1.信號(hào)量的定義 ? ? ? ? 多任務(wù)環(huán)境下使用,用來協(xié)調(diào)多個(gè)任務(wù)正確合理使用臨界資源。 2.FreeRTOS信號(hào)量介紹 ????????Semaphore包括Binary,Count,Mutex; ? ? ? ? Mutex包括RecursiveMutex,Mutex。 3.Free

    2024年02月14日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包