FreeRTOS多任務之間的通信——四種信號燈
來源:網(wǎng)絡素材
整理:技術讓夢想更偉大?|?李肖遙
四種信號燈的介紹
1.計數(shù)信號燈:計數(shù)信號燈可以看成是長度大于 1 的隊列
2.二值型信號燈:二進制信號燈可以認為長度是 1 的隊列,二值型信號燈是種特殊的計數(shù)信號燈,二值信號燈和互斥鎖十分相像,不過二值型信號燈適合用于同步。
3.互斥信號燈:互斥鎖和二元信號量十分相像,不過兩者間有細微的差別,互斥鎖包含一個優(yōu)先級繼承機制,互斥鎖適合用于互斥
4.遞歸互斥:這個我很少用,只對其API進行介紹
計數(shù)信號燈
API
創(chuàng)建一個計數(shù)信號量:xSemaphoreCreateCounting() 函數(shù)
xSemaphoreHandle xSemaphoreCreateCounting (
unsigned portBASE_TYPE uxMaxCount,
unsigned portBASE_TYPE uxInitialCount
)
uxMaxCount:可以達到的最大計數(shù)值。
uxInitialCount:信號量創(chuàng)建時分配的初始值
返回:已創(chuàng)建的信號量句柄,為xSemaphoreHandle 類型,如果信號量無法創(chuàng)建則為NULL刪除信號量void vSemaphoreDelete()
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore )
xSemaphore:信號量句柄Demo
一個初始化函數(shù),一個獲取函數(shù)
static SemaphoreHandle_t xSemaphore_count_by = NULL;
void count_semaphore_init(void *param)
{
/*信號量的計數(shù)最大值將為5,初始值為1*/
xSemaphore_count_by=xSemaphoreCreateCounting(5,1);
/*再來一個*/
xSemaphoreGive( xSemaphore_count_by );
if(xSemaphore_count_by == NULL)
{
/*創(chuàng)建互斥信號量失敗,可以寫自己的處理機制*/
printf("[%s]can't create count_semaphore_init!\n",__func__);
}
vTaskDelete( NULL );
}void count_semaphore_demo(void *param)
{
for(;;)
{
/*判斷這個互斥信號量是不是被創(chuàng)建*/
if(xSemaphore_count_by != NULL)
{
/*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
if( xSemaphoreTake( xSemaphore_count_by,(TickType_t)10) == pdTRUE )
{
/*獲取了信號量可以進行邏輯操作*/
printf("[%s] Success!\n",__func__);
/*釋放互斥信號量*/
#if 0
if(xSemaphoreGive( xSemaphore_count_by )==pdFALSE)
{
/*錯誤處理*/
printf("[%s]xSemaphoreGive error!\n",__func__);
}
#endif
}
else
{
/*錯誤處理*/
printf("[%s] error!\n",__func__);
}
}
vTaskDelay(500);
}
vTaskDelete( NULL );
}main函數(shù)(只寫了主要的函數(shù))
if(xTaskCreate(count_semaphore_init, "count_semaphore_init", 512, NULL,2, NULL) != pdPASS){
printf("[%s] count_semaphore_init error\n",__func__);
}
if(xTaskCreate(count_semaphore_demo, "mutex_semaphore_demo", 512, NULL,1, NULL) != pdPASS){
printf("[%s] count_semaphore_demo error\n",__func__);
}Log
可以在這里看到獲取了兩次信號量
[count_semaphore_demo] Success!
[count_semaphore_demo] Success!
[count_semaphore_demo] error!
[count_semaphore_demo] error!二值型信號燈
對API的介紹
創(chuàng)建二值型信號量vSemaphoreCreateBinary()
void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore )
xSemaphore :創(chuàng)建的二值型信號量或者是下面的一種方式
xSemaphoreHandle xSemaphoreCreateBinary()
返回值:創(chuàng)建的二值型信號量觸發(fā)二值型信號量:xSemaphoreGive() (我在這里用的是觸發(fā)這兩個字我覺得這個比較合適)
xSemaphoreGive (
xSemaphoreHandle xSemaphore )
xSemaphore 即將釋放的信號量的句柄,在信號量創(chuàng)建是返回
返回值:如果信號量成功釋放返回pdTRUE,如果發(fā)生錯誤則返回pdFALSE。獲取二值型信號量xSemaphoreTake()
xSemaphoreTake (
xSemaphoreHandle xSemaphore,
portTickType xBlockTime
)
xSemaphore,:將被獲得的信號量句柄,此信號量必須已經(jīng)被創(chuàng)建
xBlockTime :等待信號量可用的時鐘滴答次數(shù)
返回值:如果成功獲取信號量則返回pdTRUE, 超時則返回pdFALSEDemo
構建三個任務,一個初始化的任務,一個發(fā)送信號的任務,一個進行接收的任務
static SemaphoreHandle_t xSemaphore_by = NULL;
void semaphore_init(void *param)
{
/*初始化資源*/
xSemaphore_by=xSemaphoreCreateBinary();
if(xSemaphore_by == NULL)
{
/*創(chuàng)建二值信號量失敗,可以寫自己的處理機制 我這里做的打印*/
printf("[%s]can't create xSemaphore!\n",__func__);
}
vTaskDelete( NULL );
}
void semaphore_send(void *param)
{
for(;;)
{
/*判斷是否創(chuàng)建了這個二值信號量*/
if( xSemaphore_by != NULL )
{
/*做個延時這樣可以方便從log看出結果*/
vTaskDelay(4000);
if(xSemaphoreGive( xSemaphore_by )==pdFALSE)
{
/*錯誤處理*/
}
}
vTaskDelay(500);
}
vTaskDelete( NULL );
}
void semaphore_achieve(void *param)
{
for(;;)
{
if( xSemaphore_by != NULL )
{
/*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
if( xSemaphoreTake( xSemaphore_by,(TickType_t)10) == pdTRUE )
{
printf("[%s]achieve Success!\n",__func__);
}
else
{
/*錯誤處理*/
printf("[%s]achieve error!\n",__func__);
}
}
vTaskDelay(100);
}
vTaskDelete( NULL );
}構建一個main函數(shù):創(chuàng)建三個任務(這個是偽代碼沒有對內核啟動等操作)
if(xTaskCreate(semaphore_init, "semaphore_init", 1024, NULL,2, NULL) != pdPASS){
printf("[%s] semaphore_init error\n",__func__);
}
if(xTaskCreate(semaphore_achieve, "semaphore_achieve", 1024,NULL,1, NULL) != pdPASS){
printf("[%s] semaphore_achieve error\n",__func__);
}
if(xTaskCreate(semaphore_send, "semaphore_send", 1024,NULL,1, NULL) != pdPASS){
printf("[%s] semaphore_send error\n",__func__);
}log:(在這里只打印一部分log)
[semaphore_achieve]achieve error!
[semaphore_achieve]achieve error!
[semaphore_achieve]achieve error!
[semaphore_achieve]achieve error!
[semaphore_achieve]achieve Success!互斥信號燈
API
xSemaphoreHandle xSemaphoreCreateMutex(void)
返回:已創(chuàng)建的互斥鎖信號量句柄,需要為xSemaphoreHandle類型
獲取和釋放信號量和上面的二值信號燈是一致的
Demo
構建兩個任務,一個初始化任務,一個獲取和釋放的任務
static SemaphoreHandle_t xSemaphore_mutex_by = NULL;
void mutex_semaphore_init(void *param)
{
xSemaphore_mutex_by=xSemaphoreCreateMutex();
if(xSemaphore_mutex_by == NULL)
{
/*創(chuàng)建互斥信號量失敗,可以寫自己的處理機制*/
printf("[%s]can't create xSemaphore!\n",__func__);
}
vTaskDelete( NULL );
}
void mutex_semaphore_demo(void *param)
{
for(;;)
{
/*判斷這個互斥信號量是不是被創(chuàng)建*/
if(xSemaphore_mutex_by != NULL)
{
/*如果信號量無效,則最多等待10個系統(tǒng)節(jié)拍周期。*/
if( xSemaphoreTake( xSemaphore_mutex_by,(TickType_t)10) == pdTRUE )
{
/*獲取了信號量可以進行邏輯操作*/
printf("[%s] Success!\n",__func__);
/*釋放互斥信號量*/
if(xSemaphoreGive( xSemaphore_mutex_by )==pdFALSE)
{
/*錯誤處理*/
printf("[%s]xSemaphoreGive error!\n",__func__);
}
}
else
{
/*錯誤處理*/
printf("[%s] error!\n",__func__);
}
}
vTaskDelay(500);
}
vTaskDelete( NULL );
}Mian函數(shù):
int main()
{
if(xTaskCreate(mutex_semaphore_init, "mutex_semaphore_init", 512, NULL,2, NULL) !=pdPASS)
{
printf("[%s] mutex_semaphore_init error\n",__func__);
}
if(xTaskCreate(mutex_semaphore_demo, "mutex_semaphore_demo", 512, NULL,1, NULL) != pdPASS)
{
printf("[%s] mutex_semaphore_demo error\n",__func__);
}
vTaskStartScheduler();
for(;;);
}log:(在這里只打印一部分log)
[mutex_semaphore_demo] Success!
[mutex_semaphore_demo] Success!
[mutex_semaphore_demo] Success!
[mutex_semaphore_demo] Success!
[mutex_semaphore_demo] Success!
[mutex_semaphore_demo] Success!遞歸互斥
API
創(chuàng)建:
xSemaphoreHandle xSemaphoreCreateRecursiveMutex( void )
返回:已創(chuàng)建的互斥鎖信號量為xSemaphoreHandle類型句柄接收的釋放和上面的三個不相同
接收:
xSemaphoreTakeRecursive( xSemaphoreHandle xMutex, portTickType xBlockTime )
參數(shù):
xMutex 將被獲得的互斥鎖句柄,此句柄由xSemaphoreCreateRecursiveMutex()返回
xBlockTime 等待信號量可用的時鐘滴答次
返回值:
如果成功獲取信號量則返回pdTRUE,如果xBlockTime超時而信號量還未可用則返回pdFALSE釋放:
xSemaphoreGiveRecursive( xSemaphoreHandle xMutex )
參數(shù):
xMutex:將被釋放的互斥鎖的句柄,由 xSemaphoreCreateRecursiveMutex()返回
返回值:
如果信號量成功釋放則為pdTRUE版權聲明:本文來源網(wǎng)絡,免費傳達知識,版權歸原作者所有。如涉及作品版權問題,請聯(lián)系我進行刪除。
???????????????? ?END ????????????????
關注我的微信公眾號,回復“加群”按規(guī)則加入技術交流群。
點擊“閱讀原文”查看更多分享,歡迎點分享、收藏、點贊、在看。
