|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機 | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計 | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
μCOS-II下OSTimeDly()實現(xiàn)任務(wù)切換的疑問? |
| 作者:上善若水 欄目:ARM技術(shù) |
1.在μCOS-II中調(diào)用延時函數(shù)是導(dǎo)致任務(wù)切換的一種方式?我的理解是,只要在一個任務(wù)中第一次出現(xiàn)了OSTimeDly()調(diào)用,此任務(wù)處于等待狀態(tài),系統(tǒng)中除它以外的,優(yōu)先級最高且處于就緒態(tài)的任務(wù)就立即運行。但如果按照這個理解,以下這個用于控制蜂鳴的任務(wù): void Task2(void *pdata) { pdata = pdata; /* 避免編譯警告 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ OSTimeDly(OS_TICKS_PER_SEC / 8); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ OSTimeDly(OS_TICKS_PER_SEC / 4); /* 延時 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ OSTimeDly(OS_TICKS_PER_SEC / 8); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ OSTaskDel(OS_PRIO_SELF); /* 刪除自己 */ } 在程序中無限循環(huán)中的第一個OSTimeDly(OS_TICKS_PER_SEC / 8);就會造成任務(wù)切換,下面的任務(wù)還如何運行?那么蜂鳴器還如何實現(xiàn)蜂鳴? 2.為什么這個任務(wù)沒寫成無限循環(huán)的? 3.在基于μCOS-II的程序中是不是所有要用延時的地方就調(diào)用μCOS-II自帶的延時函數(shù),用不到自己編寫的延時子程序? * - 本貼最后修改時間:2006-2-6 10:05:14 修改者:上善若水 |
| 2樓: | >>參與討論 |
| 作者: 云中月8888 于 2006/2/6 10:27:00 發(fā)布:
我的理解 本例中task2這個任務(wù)只執(zhí)行一次,執(zhí)行完后調(diào)用 OSTaskDel(OS_PRIO_SELF); 將自己刪除了 蜂鳴器響幾下后,停止 除非程序在其它地方重新激活該任務(wù) 呵呵,沒用過μCOS-II,瞎猜的 * - 本貼最后修改時間:2006-2-6 10:29:06 修改者:云中月8888 |
|
| 3樓: | >>參與討論 |
| 作者: hotpower 于 2006/2/6 10:48:00 發(fā)布:
自毀的任務(wù)不需循環(huán) OS的定時都是靠節(jié)拍的,一般取10mS. 所謂任務(wù)切換,就是當前任務(wù)可能要延時或自己的級別太高不好意思長期占用而將任務(wù)控制權(quán)暫交OS管理. OS可能又轉(zhuǎn)交控制權(quán)給另外一個需要執(zhí)行的任務(wù)(也可能是個低級任務(wù)). 每個任務(wù)必須用死循環(huán)套住,否則不知道該到那里運行. while(1)的目的就是要在必要是進行任務(wù)切換. 這就象前后臺子程序的互相調(diào)用一樣. 自毀的任務(wù)一般做為一個單獨的初始化任務(wù),它在完成各個任務(wù)的建立后就沒必要再活著了---活著也白活,難道還要它再建立一個已存在并運行的任務(wù)??? 這樣肯定發(fā)暈~~~ 在小于1個節(jié)拍的延時,肯定要用戶自己在編寫延時函數(shù)了,如10uS的延時. 而且OS的延時及利用OS的節(jié)拍肯定是不準確的,除非這個任務(wù)的級別最高. 在級別高也沒用,因為在低級別任務(wù)運行期間,而且在節(jié)拍中斷未到來前,天王老子也管不了低級別任務(wù)在干什么!!! |
|
| 4樓: | >>參與討論 |
| 作者: 上善若水 于 2006/2/6 14:29:00 發(fā)布:
感謝hotpower多次給我解答: 1.上面的蜂鳴的任務(wù)和下面這個按鍵掃描的任務(wù)配合使用: void Task1(void *pdata) { pdata = pdata; /* 避免編譯警告 */ for (;;) //(1) { OSTimeDly(OS_TICKS_PER_SEC / 50); /* 延時20毫秒 */ //(2) if (GetKey() != KEY1) /* GetKey用于獲取鍵盤當前狀態(tài) */ { continue; /* 不是KEY1不理會 */ } OSTimeDly(OS_TICKS_PER_SEC / 50); /* 延時20毫秒,用于去抖 */ //(3) if (GetKey() != KEY1) /* 還是KEY1才正確 */ { continue; } OSTaskCreate(Task2, (void *)0, &TaskStk[TASK_STK_SIZE - 1], 10); //(4) while (GetKey() != 0) /* 等待松開按鍵 */ { OSTimeDly(OS_TICKS_PER_SEC / 50); /* 延時20毫秒 */ //(5) } } } 那么,在蜂鳴任務(wù)運行過程中,沒遇到一次OSTimeDly();就會切換到這個鍵盤掃描任務(wù)(因為鍵盤掃描任務(wù)的優(yōu)先級比它高),如果恰巧這時又有按鍵按下,于是就又重新建了個新的蜂鳴任務(wù)并立即運行,這樣,蜂鳴不就亂套了嗎? 2、按此說來,把蜂鳴任務(wù)改為: void Task2(void *pdata) { pdata = pdata; /* 避免編譯警告 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ OSTaskDel(OS_PRIO_SELF); /* 刪除自己 */ } 豈不是更合理? 3、推廣到μCOS-II下的一切的任務(wù)中,有以下原則: 所有希望發(fā)生任務(wù)切換的地方都調(diào)用μCOS-II自帶的延時函數(shù),在不希望發(fā)生任務(wù)切換,但還需要延時的地方就用自己的延時子程序,這樣可以提高系統(tǒng)的運行效率。 我這個理解對嗎? * - 本貼最后修改時間:2006-2-6 14:31:46 修改者:上善若水 |
|
| 5樓: | >>參與討論 |
| 作者: hotpower 于 2006/2/6 15:02:00 發(fā)布:
長延時不必自己編寫,這樣將違反OS的原則 2、按此說來,把蜂鳴任務(wù)改為: void Task2(void *pdata) { pdata = pdata; /* 避免編譯警告 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeMoo(); /* 使蜂鳴器鳴叫 */ 自己的延時子函數(shù); /* 延時 */ BeeNoMoo(); /* 使蜂鳴器停止鳴叫 */ OSTaskDel(OS_PRIO_SELF); /* 刪除自己 */ } 豈不是更合理? 非也!!! 因為蜂鳴器一般需要100MS切換才好聽,這樣肯定要大于節(jié)拍中斷所需要的定時時間. 它和OS的延時程序不同,它將占用CPU的實際時間,而OS的延時程序是假延時(可以說沒延時). 它不過是每次節(jié)拍中斷的計數(shù)值.若某任務(wù)調(diào)用OS的延時程序后,CPU的控制權(quán)將暫時由OS接管. 任務(wù)不知也無權(quán)過問OS想干什么. OS可以將控制再轉(zhuǎn)交其他任務(wù),哪怕是最低的任務(wù)(一般為空閑任務(wù),用于掉電進入低功耗). 這個和自己編寫的延時程序是有本質(zhì)的不同. 由于自己編寫的延時程序,低級別的任務(wù)會賴著不交出控制權(quán)來,這樣只能等待 節(jié)拍中斷由OS法庭來搶奪控制權(quán)了. 由于(因為鍵盤掃描任務(wù)的優(yōu)先級比它高),故鍵盤掃描任務(wù)可被執(zhí)行. 如果任務(wù)低的話,則鍵盤掃描任務(wù)在Task2中遇到OSTaskDel(OS_PRIO_SELF); /* 刪除自己 */ 前是不會交權(quán)的... 在你改寫后,空閑任務(wù)不會得到執(zhí)行,其他低級任務(wù)也無法運行. 實際上我只看過μCOS-II,實話說不太喜歡,我只是以自己的觀點來分析此主題的... |
|
| 6樓: | >>參與討論 |
| 作者: 上善若水 于 2006/2/6 16:05:00 發(fā)布:
再次請教hotpower: “由于鍵盤掃描任務(wù)的優(yōu)先級比蜂鳴任務(wù)的高,故鍵盤掃描任務(wù)可被執(zhí)行.”那么對與上面那個由鍵盤掃描任務(wù)和蜂鳴任務(wù)組成的系統(tǒng),在切換到蜂鳴任務(wù)并運行完第一個 BeeMoo(); /* 使蜂鳴器鳴叫 */函數(shù)后,我設(shè)想內(nèi)核的調(diào)度如下: 內(nèi)核得知運行到了蜂鳴任務(wù)中的第一個OSTimeDly(OS_TICKS_PER_SEC / 8);根據(jù)優(yōu)先級高低,立即將控制權(quán)切換給鍵盤掃描任務(wù),恰巧此時鍵盤按下,在鍵盤掃描任務(wù)中的OSTaskCreate(Task2, (void *)0, &TaskStk[TASK_STK_SIZE - 1], 10);語句前共有2個OSTimeDly(OS_TICKS_PER_SEC / 50);延時,2個1/50秒的延時肯定小于BeeMoo();和BeeNoMoo();間的那個1/8秒延時。那么鍵盤掃描任務(wù)繼續(xù)執(zhí)行OSTaskCreate(Task2……),又重新建立了蜂鳴任務(wù),并轉(zhuǎn)到蜂鳴任務(wù)運行,蜂鳴任務(wù)又從頭開始執(zhí)行,運行到第一個延時處又發(fā)生切換,這樣的結(jié)果,豈不是蜂鳴器一直響著?我這樣的推理錯在哪里? |
|
| 7樓: | >>參與討論 |
| 作者: hotpower 于 2006/2/6 16:24:00 發(fā)布:
哈哈,我記得任務(wù)是不能覆蓋建立的 即便是可以再次創(chuàng)建一個正在運行的任務(wù),也不會發(fā)生長鳴之事. 因為在BeeNoMoo()后運行OSTimeDly(OS_TICKS_PER_SEC / 8),很可能切換到鍵盤掃描任務(wù)繼續(xù)執(zhí)行并且到OSTaskCreate(Task2……),這里假定可以再次創(chuàng)建(實際是不可能的,如果可以就暈到了). 接著會執(zhí)行 while (GetKey() != 0) /* 等待松開按鍵 */ { OSTimeDly(OS_TICKS_PER_SEC / 50); /* 延時20毫秒 */ //(5) } 由于OSTimeDly()將會將控制權(quán)交給Task2,這種交替任務(wù)的切換肯定能到關(guān)閉BEEP的時候,不過它可能實行很長的時間(肯定小于1S),所以是不會受影響的... |
|
| 8樓: | >>參與討論 |
| 作者: 上善若水 于 2006/2/6 17:23:00 發(fā)布:
總結(jié)一下: 歸根到底一句話: 在μCOS-II下的所有延時,只要不是短于一個時鐘節(jié)拍,那么都要調(diào)用μCOS-II自帶的延時函數(shù)。 這種說法嚴密嗎? |
|
| 9樓: | >>參與討論 |
| 作者: hotpower 于 2006/2/6 17:35:00 發(fā)布:
1個半節(jié)拍不玩了---別的定時器在吃閑飯??? 在比較精準的長定時中(相對),可以采用硬件定時中斷. 當然也可以建立一個處理任務(wù),如果不想在中斷中干活的話. 這個處理任務(wù)由于只接收這個定時服務(wù)的處理,所以它可以安排的級別較高. 這樣退出硬件定時中斷后,由于"龜殼"的作用,中斷退出后會立即在這個任務(wù)中處理的. 就象在中斷里處理一樣,只不過有些延遲,只要你能容許即可. |
|
| 10樓: | >>參與討論 |
| 作者: 上善若水 于 2006/2/6 20:35:00 發(fā)布:
那我修改一下: 除去需要用硬件定時器延時和節(jié)拍數(shù)不為整數(shù)的延時外,都要調(diào)用μCOS-II自帶的延時函數(shù)。那種通過累加或累減來實現(xiàn)軟件延時的子程序是不必要的。 對嗎? |
|
|
|
| 免費注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點此進入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號 |