在基于RTOS開發(fā)項目時,通常都會遇到互斥的情況,比如:幾個任務都要使用一個UART串口進行發(fā)送數(shù)據。
如果不加互斥鎖,優(yōu)先級高的任務,會搶占串口并發(fā)送數(shù)據,則有可能會出現(xiàn)發(fā)送數(shù)據“亂碼”的情況。
今天就說說在RTOS開發(fā)中,互斥鎖一個常見的問題。
什么是Mutex互斥鎖?
學習過RTOS的讀者應該對互斥不陌生,互斥鎖就是為了避免任務之間互相搶占某種資源而設計的一種“鎖”。
就如上面說的,一個串口,被兩個任務搶占,如果不加鎖,則會出現(xiàn)兩個任務交叉發(fā)送數(shù)據,即“亂碼”;
但是,如果加了互斥鎖,則會等待其他任務發(fā)送完成之后才繼續(xù)發(fā)送,保證了數(shù)據的完整(而不是亂碼);
嵌入式專欄
2
Mutex互斥鎖例子
這里以三個任務、兩個互斥鎖為例,代碼如下:
void task1(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 /*加鎖處理事情*/ OSMutex1_Post(); //互斥鎖1解鎖} void task2(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖2解鎖 OSMutex1_Post(); //互斥鎖1解鎖} void task3(){ /*do something*/ OSMutex2_Pend(); //互斥鎖2加鎖/*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖1解鎖}
這樣設計,大家看出問題了嗎?
老司機應該看出來了,新手可能摸不著頭腦。
在任務2中,進行了2次加鎖、解鎖,而且“環(huán)環(huán)相扣”。
Mutex互斥鎖問題
假如任務1、 任務2、任務3優(yōu)先級分別為:1、 2、 3。
優(yōu)先級順序就是:任務1 >任務2>任務3(數(shù)字越小代表任務優(yōu)先級越高)。
假設:任務1和任務2處于等待事件狀態(tài),也就是處于阻塞狀態(tài), task 3 處于運行狀態(tài)。
當任務3在“加鎖處理事情”的時候,任務2搶占了任務3(任務2掛起時間到了),此時任務3掛起,任務2處于運行狀態(tài);
如果任務2在“互斥鎖1加鎖”之后,任務1搶占了任務2,此時,任務1處于運行狀態(tài);
這個時候,你發(fā)現(xiàn)問題了沒有?
任務1在執(zhí)行“OSMutex1_Pend();”會等待“互斥鎖1解鎖”,如果其他方式沒有對“互斥鎖1解鎖”,則會出現(xiàn)“死鎖”的情況。
分享一張圖片,你就會明白什么是死鎖了:
解決辦法
比如對任務2加鎖方式進行改善:
void task2(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 /*do something*/ OSMutex1_Post(); //互斥鎖1解鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*do something*/ OSMutex2_Post(); //互斥鎖1解鎖}
或者對低優(yōu)先級的任務3加鎖方式進行改善:
void task3(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖2解鎖 OSMutex1_Post(); //互斥鎖1解鎖}
出問題的原因, 當一個任務獲得了臨界區(qū)資源的鎖,在沒有釋放這個鎖的前提下又去獲得另外一塊臨界區(qū)資源,這個時候就要引起足夠的注意了,設計成敗在于你是否徹底理解了之前的問題。 但是,歸根到底這樣的問題還是要求用戶在設計階段去避免,一個系統(tǒng)不可能是萬能的,正確的設計才是最重要的。
-
數(shù)據
+關注
關注
8文章
7256瀏覽量
91830 -
RTOS
+關注
關注
24文章
851瀏覽量
121154 -
Uart串口
+關注
關注
0文章
29瀏覽量
7145
原文標題:RTOS 任務間互斥的問題
文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。
發(fā)布評論請先 登錄
評論