freeRtos学习笔记 (7)信号量
freeRtos學(xué)習(xí)筆記
freeRtos信號(hào)量
信號(hào)量種類
信號(hào)量分為四種:二值信號(hào)量,互斥信號(hào)量,計(jì)數(shù)信號(hào)量和遞歸互斥信號(hào)量,其中計(jì)數(shù)信號(hào)量用于管理系統(tǒng)多個(gè)共享資源,用計(jì)數(shù)值表示可用資源數(shù)目;二值信號(hào)量是一種特殊的計(jì)數(shù)信號(hào)量,和事件組類似,相當(dāng)于裸機(jī)中的標(biāo)志位,常用于任務(wù)之間的同步;互斥信號(hào)量和二值信號(hào)量類似,相比二值信號(hào)量避免了任務(wù)優(yōu)先級(jí)翻轉(zhuǎn)問(wèn)題,因此常用來(lái)保護(hù)臨界資源,但是互斥信號(hào)量不可以在中斷中使用,只能在任務(wù)中使用;遞歸互斥信號(hào)量是一種特殊的互斥信號(hào)量,如果任務(wù)獲取到遞歸互斥信號(hào)量后,該任務(wù)中不需要等待遞歸互斥信號(hào)量釋放就可以再次獲取遞歸互斥信號(hào)量,只需遞歸層數(shù)加一.
計(jì)數(shù)信號(hào)量創(chuàng)建
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, /* 支持最大計(jì)數(shù)值 */UBaseType_t uxInitialCount);/* 初始計(jì)數(shù)值 */創(chuàng)建計(jì)數(shù)信號(hào)量函數(shù)
- 第一個(gè)參數(shù)設(shè)置技術(shù)信號(hào)量最大計(jì)數(shù)值
- 第二個(gè)參數(shù)設(shè)置初始計(jì)數(shù)值
- 返回值 如果創(chuàng)建成功會(huì)返回計(jì)數(shù)信號(hào)量句柄,如果heap不足則返回NULL
- 注意 信號(hào)量底層都是調(diào)用消息隊(duì)列實(shí)現(xiàn)的
二值信號(hào)量創(chuàng)建
SemaphoreHandle_t xSemaphoreCreateBinary( void );二值信號(hào)量創(chuàng)建函數(shù)
- 返回值 如果創(chuàng)建成功會(huì)返回計(jì)數(shù)信號(hào)量句柄,如果heap不足則返回NULL
- 注意 創(chuàng)建成功后 二值信號(hào)量初始值為0
- 一般使用任務(wù)消息通知來(lái)代替二值信號(hào)量,效率會(huì)更高
互斥信號(hào)量創(chuàng)建
SemaphoreHandle_t xSemaphoreCreateMutex( void );互斥信號(hào)量創(chuàng)建函數(shù)
- 返回值 如果創(chuàng)建成功會(huì)返回計(jì)數(shù)信號(hào)量句柄,如果heap不足則返回NULL
- 注意 創(chuàng)建成功后 互斥信號(hào)量初始值為0
- 一般用來(lái)保護(hù)任務(wù)中的臨界資源
遞歸互斥信號(hào)量創(chuàng)建
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )遞歸互斥信號(hào)量創(chuàng)建函數(shù)
- 返回值 如果創(chuàng)建成功會(huì)返回計(jì)數(shù)信號(hào)量句柄,如果heap不足則返回NULL
- 注意 創(chuàng)建成功后 互斥信號(hào)量初始值為0
釋放信號(hào)量
/* 釋放一個(gè)信號(hào)量, 該函數(shù)適用于計(jì)數(shù)信號(hào)量 二值信號(hào)量 互斥信號(hào)量 */ BaseType_t xSemaphoreGive(SemphoreHandle_t xSemaphore)/* 在中斷中釋放一個(gè)信號(hào)量, 該函數(shù)適用于計(jì)數(shù)信號(hào)量 二值信號(hào)量 */ BaseType_t xSemaphoreGiveFromISR(SemphoreHandle_t xSemaphore, BaseType_t * const pxHigherPriorityTaskWoken)/* 釋放一個(gè)信號(hào)量, 該函數(shù)適用于遞歸互斥信號(hào)量 */ BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )釋放信號(hào)量函數(shù)
- 第一個(gè)參數(shù)信號(hào)量句柄
- 在中斷中使用FormISR結(jié)尾的函數(shù),在中斷中 第 2 個(gè)參數(shù)是釋放信號(hào)量后,是否有更高級(jí)別的任務(wù)就緒,如果有更高級(jí)別任務(wù)就緒(優(yōu)先級(jí)更高的任務(wù)堵塞在獲取信號(hào)量上,這里釋放了信號(hào)量,導(dǎo)致任務(wù)從堵塞態(tài)轉(zhuǎn)變?yōu)榫途w態(tài)),則pxHigherPriorityTaskWoken變?yōu)閜dTRUE,然后在中斷結(jié)束處可以調(diào)用taskYIELD()進(jìn)行任務(wù)調(diào)度。
- 返回值 pdTRUE釋放成功
- 注意 不同信號(hào)量使用不同的信號(hào)量釋放函數(shù),互斥信號(hào)量不可以在中斷中使用,只能在任務(wù)中使用;
獲取信號(hào)量
/* 獲取一個(gè)信號(hào)量, 該函數(shù)適用于計(jì)數(shù)信號(hào)量 二值信號(hào)量 互斥信號(hào)量 */ BaseType_t xSemaphoreTake( SemaphoreHandle_t xSemaphore,TickType_t xTicksToWait );/* 在中斷中獲取一個(gè)信號(hào)量, 該函數(shù)適用于計(jì)數(shù)信號(hào)量 二值信號(hào)量 */ BaseType_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,signed BaseType_t *pxHigherPriorityTaskWoken)/* 獲取一個(gè)信號(hào)量, 該函數(shù)適用于遞歸互斥信號(hào)量 */ BaseType_t xSemaphoreTakeRecursive( SemaphoreHandle_t xMutex,TickType_t xTicksToWait );獲取信號(hào)量函數(shù)
- 第一個(gè)參數(shù)信號(hào)量句柄
- 第二個(gè)參數(shù)為等待時(shí)間,信號(hào)量底層調(diào)用消息隊(duì)列實(shí)現(xiàn),如果消息隊(duì)列滿,則進(jìn)行等待的時(shí)間
- 在中斷中 第 2 個(gè)參數(shù)是獲取信號(hào)量后,是否有更高級(jí)別的任務(wù)就緒,如果有更高級(jí)別任務(wù)就緒(優(yōu)先級(jí)更高的任務(wù)堵塞在釋放信號(hào)量上,這里獲取了一個(gè)信號(hào)量,導(dǎo)致該任務(wù)從堵塞態(tài)轉(zhuǎn)變?yōu)榫途w態(tài)),則pxHigherPriorityTaskWoken變?yōu)閜dTRUE,然后在中斷結(jié)束處可以調(diào)用taskYIELD()進(jìn)行任務(wù)調(diào)度。
- 返回值 pdTRUE獲取成功
- 注意 不同信號(hào)量使用不同的信號(hào)量獲取函數(shù),互斥信號(hào)量不可以在中斷中使用,只能在任務(wù)中使用;
優(yōu)先級(jí)翻轉(zhuǎn)問(wèn)題
如果使用普通的二值信號(hào)量進(jìn)行臨界資源保護(hù)會(huì)出現(xiàn)一下問(wèn)題.
仔細(xì)觀察步驟5 6 7會(huì)發(fā)現(xiàn),task2優(yōu)先級(jí)明明比task1低,但是task2卻先執(zhí)行,這就是任務(wù)優(yōu)先級(jí)翻轉(zhuǎn)
互斥信號(hào)量為了解決這個(gè)問(wèn)題,在二值信號(hào)量的基礎(chǔ)上增加了優(yōu)先級(jí)繼承功能. 在步驟4 task1由掛起態(tài)轉(zhuǎn)變?yōu)榫途w態(tài)獲取串口資源時(shí),會(huì)將正在持有該資源的task3優(yōu)先級(jí)改為和task1一樣高. 步驟5 task2就緒,但是task3的優(yōu)先級(jí)已經(jīng)和task1一樣,所以task3繼續(xù)執(zhí)行,task3執(zhí)行完畢后,釋放串口資源時(shí),會(huì)將task3優(yōu)先級(jí)改會(huì)原來(lái),然后task1得到執(zhí)行,taks1執(zhí)行結(jié)束后task2才會(huì)得到執(zhí)行.
本文參考 freertos官方文檔 https://freertos.org/a00110.html
 《安富萊 STM32-V6 開(kāi)發(fā)板 FreeRTOS 教程》
總結(jié)
以上是生活随笔為你收集整理的freeRtos学习笔记 (7)信号量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: keil 使用AC6 中文警告解决办法
- 下一篇: freeRtos学习笔记 (8) 任务
