成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

七,F(xiàn)reeRTOS之——隊列同步與互斥

Yu_Huang / 3524人閱讀

摘要:聲明本專欄參考韋東山,野火,正點(diǎn)原子以及其他博主的教程,如若侵權(quán)請告知,馬上刪帖致歉,個人總結(jié),如有不對,歡迎指正。

聲明:本專欄參考韋東山,野火,正點(diǎn)原子以及其他博主的FreeRTOS教程,如若侵權(quán)請告知,馬上刪帖致歉,個人總結(jié),如有不對,歡迎指正。

轉(zhuǎn):同步與互斥概念理解link






實驗一:同步

還是來看看同步實驗怎么做吧

實驗代碼

/**   FreeRTOS v9.0.0 + STM32 動態(tài)創(chuàng)建任務(wù)   實驗平臺:韋東山 STM32F103ZE開發(fā)板 **/  #include "FreeRTOS.h"#include "task.h"#include "queue.h"/* 開發(fā)板硬件bsp頭文件 */#include "bsp_led.h"#include "bsp_usart.h"/* 任務(wù)句柄 */static TaskHandle_t AppTaskCreate_Handle = NULL;static TaskHandle_t Task1_Handle = NULL;static TaskHandle_t Task2_Handle = NULL;static TaskHandle_t Task3_Handle = NULL;static xQueueHandle MsgQueue;  /*隊列句柄*//* 函數(shù)聲明 */static void AppTaskCreate(void);/* 用于創(chuàng)建任務(wù) */static void Flag1_Task(void* pvParameters);/* LED1_Task任務(wù)實現(xiàn) */static void Flag2_Task(void* pvParameters);/* LED2_Task任務(wù)實現(xiàn) */static void Flag3_Task(void* pvParameters);/* LED3_Task任務(wù)實現(xiàn) */static void BSP_Init(void);/* 用于初始化板載相關(guān)資源 *//*****************************************************************  * @brief  主函數(shù)  * @param  無  * @retval 無  * @note   第一步:開發(fā)板硬件初始化             第二步:創(chuàng)建APP應(yīng)用任務(wù)            第三步:啟動FreeRTOS,開始多任務(wù)調(diào)度  ****************************************************************/int main(void){	  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為pdPASS */  /* 開發(fā)板硬件初始化 */  BSP_Init();  printf("這是一個STM32F103ZE開發(fā)板-FreeRTOS-動態(tài)創(chuàng)建任務(wù)!/r/n");		MsgQueue=xQueueCreate(1,sizeof(int));/*創(chuàng)建隊列:參數(shù),隊列長度,每個長度大小(字節(jié))*/				   /* 創(chuàng)建AppTaskCreate任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* 任務(wù)入口函數(shù) */                        (const char*    )"AppTaskCreate",/* 任務(wù)名字 */                        (uint16_t       )512,  /* 任務(wù)棧大小 */                        (void*          )NULL,/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )1, /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* 任務(wù)控制塊指針 */   /* 啟動任務(wù)調(diào)度 */             if(pdPASS == xReturn)    vTaskStartScheduler();   /* 啟動任務(wù),開啟調(diào)度 */  else    return -1;      while(1);   /* 正常不會執(zhí)行到這里 */    }/***********************************************************************  * @ 函數(shù)名  : AppTaskCreate  * @ 功能說明: 為了方便管理,所有的任務(wù)創(chuàng)建函數(shù)都放在這個函數(shù)里面  * @ 參數(shù)    : 無    * @ 返回值  : 無  **********************************************************************/static void AppTaskCreate(void){  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為pdPASS */    taskENTER_CRITICAL();           //進(jìn)入臨界區(qū)    /* 創(chuàng)建Flag1_Task任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )Flag1_Task, /* 任務(wù)入口函數(shù) */                        (const char*    )"Flag1_Task",/* 任務(wù)名字 */                        (uint16_t       )512,   /* 任務(wù)棧大小 */                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )2,	    /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&Task1_Handle);/* 任務(wù)控制塊指針 */  if(pdPASS == xReturn)    printf("創(chuàng)建Flag1_Task任務(wù)成功!/r/n");		 /* 創(chuàng)建Flag2_Task任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )Flag2_Task, /* 任務(wù)入口函數(shù) */                        (const char*    )"Flag2_Task",/* 任務(wù)名字 */                        (uint16_t       )512,   /* 任務(wù)棧大小 */                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )2,	    /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&Task2_Handle);/* 任務(wù)控制塊指針 */  if(pdPASS == xReturn)    printf("創(chuàng)建Flag2_Task任務(wù)成功!/r/n");			 /* 創(chuàng)建Flag3_Task任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )Flag3_Task, /* 任務(wù)入口函數(shù) */                        (const char*    )"Flag3_Task",/* 任務(wù)名字 */                        (uint16_t       )512,   /* 任務(wù)棧大小 */                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )1,	    /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&Task3_Handle);/* 任務(wù)控制塊指針 */  if(pdPASS == xReturn)    printf("創(chuàng)建Flag3_Task任務(wù)成功!/r/n");    vTaskDelete(AppTaskCreate_Handle); //刪除AppTaskCreate任務(wù)    taskEXIT_CRITICAL();            //退出臨界區(qū)}/**********************************************************************  * @ 函數(shù)名  : LED_Task  * @ 功能說明: LED_Task任務(wù)主體  ********************************************************************/uint8_t flag1;uint8_t flag2;uint8_t flag3;/*優(yōu)先級2*/static void Flag1_Task(void* parameter){	static int value,i;	 while (1)    {						  for(i=10000;i>1;i--)			  flag1=1;        flag2=0;			  flag3=0;			  /* 向隊列中填充內(nèi)容 */  						  value++;			  printf("Task1 Running! value=%d/r/n",value);			  xQueueSend( MsgQueue, ( void* )&value, queueSEND_TO_BACK);  /*發(fā)送隊列消息,*/						 // vTaskDelay(10);   /* 延時1個tick */    }}/*優(yōu)先級2*/static void Flag2_Task(void* parameter){	static int value1;  	while (1)    {		  /*如果讀取到隊列消息*/			if(xQueueReceive(MsgQueue,(void *)&value1,pdFALSE)==pdPASS)			{			    flag1=0;          flag2=1;			    flag3=0;				  printf("Task2 Running! value=%d/r/n",value1);/*將讀取到的數(shù)值打印出來*/			}			      //vTaskDelay(10);   /* 延時1個tick */		 		         }}/*優(yōu)先級2*/static void Flag3_Task(void* parameter){	static int value2;  	while (1)    {		  flag1=0;      flag2=0;			flag3=1;		  printf("Task3 Running! value=%d/r/n",value2);		  vTaskDelay(10);   /* 延時1個tick */		 		         }}/***********************************************************************  * @ 函數(shù)名  : BSP_Init  * @ 功能說明: 板級外設(shè)初始化,所有板子上的初始化均可放在這個函數(shù)里面  * @ 參數(shù)    :     * @ 返回值  : 無  *********************************************************************/static void BSP_Init(void){	/*	 * STM32中斷優(yōu)先級分組為4,即4bit都用來表示搶占優(yōu)先級,范圍為:0~15	 * 優(yōu)先級分組只需要分組一次即可,以后如果有其他的任務(wù)需要用到中斷,	 * 都統(tǒng)一用這個優(yōu)先級分組,千萬不要再分組,切忌。	 */	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );		/* LED 初始化 */	LED_GPIO_Config();	/* 串口初始化	*/	USART_Config();  }/********************************END OF FILE****************************/

劃重點(diǎn)

創(chuàng)建三個任務(wù),優(yōu)先級為321,

創(chuàng)建隊列任務(wù)句柄,在這之前得要加入隊列頭文件

創(chuàng)建隊列函數(shù)

xQueueCreate();

各任務(wù)處理事件

flag1Task

flag2Task

flag3Task

根據(jù)以上信息可以猜想任務(wù)運(yùn)行過程是怎樣的???

任務(wù)一和任務(wù)二在執(zhí)行過程中都沒有進(jìn)入到阻塞狀態(tài),任務(wù)3的優(yōu)先級是要比任務(wù)一和任務(wù)二要低的,所以任務(wù)三肯定不會運(yùn)行,那么任務(wù)一和任務(wù)二相同優(yōu)先級要如何運(yùn)行呢??

直接仿真看看

神奇的是串口居然不亂了,任務(wù)一先運(yùn)行,接著任務(wù)二打印了信息,這就是通過隊列傳遞信息來實現(xiàn)任務(wù)同步

再來做個實驗看看任務(wù)互斥

實驗二:互斥

實驗代碼

/**   FreeRTOS v9.0.0 + STM32 動態(tài)創(chuàng)建任務(wù)   實驗平臺:韋東山 STM32F103ZE開發(fā)板 **/  #include "FreeRTOS.h"#include "task.h"#include "queue.h"/* 開發(fā)板硬件bsp頭文件 */#include "bsp_led.h"#include "bsp_usart.h"/* 任務(wù)句柄 */static TaskHandle_t AppTaskCreate_Handle = NULL;static TaskHandle_t Task1_Handle = NULL;static TaskHandle_t Task2_Handle = NULL;//static TaskHandle_t Task3_Handle = NULL;//static QueueHandle_t xQueueCalcHandle;static QueueHandle_t xQueueUARTcHandle;/* 函數(shù)聲明 */static void AppTaskCreate(void);/* 用于創(chuàng)建任務(wù) */static void Flag1_Task(void* pvParameters);/* LED1_Task任務(wù)實現(xiàn) */static void Flag2_Task(void* pvParameters);/* LED2_Task任務(wù)實現(xiàn) *///static void Flag3_Task(void* pvParameters);/* LED3_Task任務(wù)實現(xiàn) */static void BSP_Init(void);/* 用于初始化板載相關(guān)資源 *//*創(chuàng)建隊列*/int InitUARTLock(void){		int val;	xQueueUARTcHandle = xQueueCreate(1, sizeof(int));/*創(chuàng)建隊列*/	if (xQueueUARTcHandle == NULL)	{		printf("can not create queue/r/n");		return -1;/*創(chuàng)建失敗*/	}	xQueueSend(xQueueUARTcHandle, &val, portMAX_DELAY);/*死等*/	return 0;/*創(chuàng)建成功*/}/*接收隊列消息*/void GetUARTLock(void){		int val;	xQueueReceive(xQueueUARTcHandle, &val, portMAX_DELAY);}/*發(fā)送隊列消息*/void PutUARTLock(void){		int val;	xQueueSend(xQueueUARTcHandle, &val, portMAX_DELAY);}/*****************************************************************  * @brief  主函數(shù)  * @param  無  * @retval 無  * @note   第一步:開發(fā)板硬件初始化             第二步:創(chuàng)建APP應(yīng)用任務(wù)            第三步:啟動FreeRTOS,開始多任務(wù)調(diào)度  ****************************************************************/int main(void){	  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為pdPASS */  /* 開發(fā)板硬件初始化 */  BSP_Init();  printf("這是一個STM32F103ZE開發(fā)板-FreeRTOS-動態(tài)創(chuàng)建任務(wù)!/r/n");		InitUARTLock();/*調(diào)用創(chuàng)建隊列函數(shù)*/					   /* 創(chuàng)建AppTaskCreate任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,  /* 任務(wù)入口函數(shù) */                        (const char*    )"AppTaskCreate",/* 任務(wù)名字 */                        (uint16_t       )512,  /* 任務(wù)棧大小 */                        (void*          )NULL,/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )1, /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&AppTaskCreate_Handle);/* 任務(wù)控制塊指針 */   /* 啟動任務(wù)調(diào)度 */             if(pdPASS == xReturn)    vTaskStartScheduler();   /* 啟動任務(wù),開啟調(diào)度 */  else    return -1;      while(1);   /* 正常不會執(zhí)行到這里 */    }/***********************************************************************  * @ 函數(shù)名  : AppTaskCreate  * @ 功能說明: 為了方便管理,所有的任務(wù)創(chuàng)建函數(shù)都放在這個函數(shù)里面  * @ 參數(shù)    : 無    * @ 返回值  : 無  **********************************************************************/static void AppTaskCreate(void){  BaseType_t xReturn = pdPASS;/* 定義一個創(chuàng)建信息返回值,默認(rèn)為pdPASS */    taskENTER_CRITICAL();           //進(jìn)入臨界區(qū)    /* 創(chuàng)建Flag1_Task任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )Flag1_Task, /* 任務(wù)入口函數(shù) */                        (const char*    )"Flag1_Task",/* 任務(wù)名字 */                        (uint16_t       )512,   /* 任務(wù)棧大小 */                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )2,	    /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&Task1_Handle);/* 任務(wù)控制塊指針 */  if(pdPASS == xReturn)    printf("創(chuàng)建Flag1_Task任務(wù)成功!/r/n");		 /* 創(chuàng)建Flag2_Task任務(wù) */  xReturn = xTaskCreate((TaskFunction_t )Flag2_Task, /* 任務(wù)入口函數(shù) */                        (const char*    )"Flag2_Task",/* 任務(wù)名字 */                        (uint16_t       )512,   /* 任務(wù)棧大小 */                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) */                        (UBaseType_t    )2,	    /* 任務(wù)的優(yōu)先級 */                        (TaskHandle_t*  )&Task2_Handle);/* 任務(wù)控制塊指針 */  if(pdPASS == xReturn)    printf("創(chuàng)建Flag2_Task任務(wù)成功!/r/n");			 /* 創(chuàng)建Flag3_Task任務(wù) *///  xReturn = xTaskCreate((TaskFunction_t )Flag3_Task, /* 任務(wù)入口函數(shù) *///                        (const char*    )"Flag3_Task",/* 任務(wù)名字 *///                        (uint16_t       )512,   /* 任務(wù)棧大小 *///                        (void*          )NULL,	/* 任務(wù)入口函數(shù)參數(shù) *///                        (UBaseType_t    )1,	    /* 任務(wù)的優(yōu)先級 *///                        (TaskHandle_t*  )&Task3_Handle);/* 任務(wù)控制塊指針 *///  if(pdPASS == xReturn)//    printf("創(chuàng)建Flag3_Task任務(wù)成功!/r/n");    vTaskDelete(AppTaskCreate_Handle); //刪除AppTaskCreate任務(wù)    taskEXIT_CRITICAL();            //退出臨界區(qū)}/**********************************************************************  * @ 函數(shù)名  : LED_Task  * @ 功能說明: LED_Task任務(wù)主體  ********************************************************************/uint8_t flag1;uint8_t flag2;uint8_t flag3;/*優(yōu)先級2*/static void Flag1_Task(void* parameter){	 while (1)    {			GetUARTLock();/*調(diào)用接收消息函數(shù)獲得使用權(quán)*/  						printf("Task1 Running!/r/n");						PutUARTLock();/*調(diào)用發(fā)送消息函數(shù)釋放使用權(quán)*/			  					vTaskDelay(1);   /* 延時1個tick */		 		    }}/*優(yōu)先級2*/static void Flag2_Task(void* parameter){  	while (1)    {      GetUARTLock();/*調(diào)用接收消息函數(shù)獲得使用權(quán)*/						printf("Task2 Running!/r/n");						PutUARTLock();/*調(diào)用發(fā)送消息函數(shù)釋放使用權(quán)*/			      vTaskDelay(1);   /* 延時1個tick */		 		         }}/*優(yōu)先級1*///static void Flag3_Task(void* parameter)//{//	static int value2;//  	while (1)//    {//		  flag1=0;//      flag2=0;//			flag3=1;//		  printf("Task3 Running! value=%d/r/n",value2);//		  vTaskDelay(10);   /* 延時1個tick */		 		//     //    }//}/***********************************************************************  * @ 函數(shù)名  : BSP_Init  * @ 功能說明: 板級外設(shè)初始化,所有板子上的初始化均可放在這個函數(shù)里面  * @ 參數(shù)    :     * @ 返回值  : 無  *********************************************************************/static void BSP_Init(void){	/*	 * STM32中斷優(yōu)先級分組為4,即4bit都用來表示搶占優(yōu)先級,范圍為:0~15	 * 優(yōu)先級分組只需要分組一次即可,以后如果有其他的任務(wù)需要用到中斷,	 * 都統(tǒng)一用這個優(yōu)先級分組,千萬不要再分組,切忌。	 */	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );		/* LED 初始化 */	LED_GPIO_Config();	/* 串口初始化	*/	USART_Config();  }/********************************END OF FILE****************************/

劃重點(diǎn)

這次實驗創(chuàng)建了兩個任務(wù),任務(wù)優(yōu)先級相同都為2


創(chuàng)建這幾個函數(shù)

在任務(wù)處理事件中,像臨界保護(hù)一樣進(jìn)行首先調(diào)用接收消息的函數(shù)獲得使用權(quán),再調(diào)用發(fā)送消息函數(shù)釋放使用權(quán)。(隊列里面有數(shù)據(jù)表示別人可以讀這個隊列)

仿真來看看實驗效果

git倉庫源碼地址:https://gitee.com/he-dejiang/free-rtos.git

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/121365.html

相關(guān)文章

  • Java 并發(fā)學(xué)習(xí)筆記(二)

    摘要:請參看前一篇文章并發(fā)學(xué)習(xí)筆記一原子性可見性有序性問題六等待通知機(jī)制什么是等待通知機(jī)制當(dāng)線程不滿足某個條件,則進(jìn)入等待狀態(tài)如果線程滿足要求的某個條件后,則通知等待的線程重新執(zhí)行。經(jīng)極客時間并發(fā)編程實戰(zhàn)專欄內(nèi)容學(xué)習(xí)整理 請參看前一篇文章:Java 并發(fā)學(xué)習(xí)筆記(一)——原子性、可見性、有序性問題 六、等待—通知機(jī)制 什么是等待通知—機(jī)制?當(dāng)線程不滿足某個條件,則進(jìn)入等待狀態(tài);如果線程滿足要...

    zgbgx 評論0 收藏0
  • 常見物聯(lián)網(wǎng)操作系統(tǒng)介紹

    摘要:相比之下,物聯(lián)網(wǎng)操作系統(tǒng)領(lǐng)域的碎片化問題則非常嚴(yán)重,并沒有哪幾個操作系統(tǒng)占據(jù)絕對優(yōu)勢,正處于百花齊放百家爭鳴的階段。在年被公司正式收購,將自己的服務(wù)內(nèi)嵌到系統(tǒng)中,并于年推出了集成無線連接安全等功能的物聯(lián)網(wǎng)操作系統(tǒng)。 物聯(lián)網(wǎng)操作系統(tǒng)是運(yùn)行在物聯(lián)網(wǎng)設(shè)備上的提供物物相連能力的操作系統(tǒng),其核心在于...

    AdolphLWQ 評論0 收藏0
  • PHP進(jìn)程通信

    摘要:一進(jìn)程間通信理解間進(jìn)程通信機(jī)制,先了解下進(jìn)程間有哪些通訊機(jī)制歷史發(fā)展按照歷史來源主要有兩大塊的管道,,信號的消息隊列,共享內(nèi)存,信號燈。信號量主要作為進(jìn)程間,以及進(jìn)程內(nèi)部線程之間的通訊手段。主要依賴,兼容擴(kuò)展實現(xiàn)方式的進(jìn)程間通信之消息隊列。 PHP間進(jìn)程如何通信,PHP相關(guān)的服務(wù)的IPC是實現(xiàn)方式,IPC的思想如何用到項目中。 一、linux進(jìn)程間通信 理解php間進(jìn)程通信機(jī)制,先了解...

    haobowd 評論0 收藏0
  • setTimeoutsetInterval

    摘要:工作線程執(zhí)行異步任務(wù),執(zhí)行完成后把對應(yīng)額回調(diào)函數(shù)封裝成一條消息放到消息隊列中主線程不斷地從消息隊列中取消息并執(zhí)行。當(dāng)消息隊列為空時,主線程阻塞,直到消息隊列再次非空。取決于何時被主線程的事件循環(huán)取到,并執(zhí)行。 轉(zhuǎn)自:http://palmer.arkstack.cn/201...一:平時簡單使用 1.setTimeout延遲一段時間執(zhí)行一次(only one) setTimeout(f...

    Tangpj 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<