|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測(cè)控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
我的簡(jiǎn)易操作系統(tǒng),希望能體現(xiàn)所長(zhǎng)的編程思想 |
| 作者:lansy 欄目:單片機(jī) |
剛學(xué)單片機(jī)的時(shí)候,很喜歡看所長(zhǎng)跟別人吵架,因?yàn)闉榱私逃?xùn)別人,說程序應(yīng)該如何如何寫,如何讓整個(gè)程序只需在一處喂狗。氣得實(shí)在不可教時(shí),所長(zhǎng)就甩出一些程序,喏!程序是這樣的!!我就跟在后邊,把程序copy下來,然后在那里竊喜。后來巨人及小師(所長(zhǎng)早期的ID)網(wǎng)上所發(fā)的程序都被我收刮下來了。 現(xiàn)在終于學(xué)到點(diǎn)皮毛,寫了個(gè)程序,希望能與各位多多交流。 (我的blog 當(dāng)中有更詳細(xì)的介紹) 這個(gè)簡(jiǎn)易操作系統(tǒng)的核心思想是:通過在程序當(dāng)中添加狀態(tài)機(jī)的方法,把單片機(jī)操作當(dāng)中那些死的延時(shí)去掉,如此類for (i = 0; i < delay; i++)延時(shí)的蠢笨辦法。當(dāng)碰到需要延時(shí)的時(shí)候,就讓單片機(jī)去睡大覺。 核心程序如下: (下面程序是基于凌陽(yáng)單片機(jī)的;也有51的,只是程序是大二的時(shí)候?qū)懙,沒有規(guī)范化,此處就不貼了) /******************************************************************************* COPYRIGHT(C)桂林電子工業(yè)學(xué)院電子工程系科技協(xié)會(huì) All right reserved 文件名: os_core.h 描 述: 微型操作系統(tǒng) 作 者: lansy 日 期: 8/15/2005 函數(shù)聲明清單: 1. void OSInit(); 2. void OSTimeTick(); 3. BOOL OSTaskCreate(void (* pfnTask)(void), INT16U ivTaskID) 4. void OSStart(void); 5. void OSTimeDly(INT16U ticks); 6. void SendMessage(INT16U msg); 7. void PostMessage(INT16U msg); 8. void WaitMessage(INT16U msg); 9. INT16U OSActiveTask(INT16U ivTaskID); 10.INT16U OSTaskSuspend(INT16U ivTaskID). *******************************************************************************/ #ifndef _OSCORE__H #define _OSCORE__H #include "..\include\main.h" /********************************************************************* 函數(shù)名稱: void OSInit() 函數(shù)功能: 操作系統(tǒng)初始化 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 *********************************************************************/ void OSInit(void); /********************************************************************* 函數(shù)名稱: BOOL OSTaskCreate(void (*pfnTask)(void), INT16U prio) 函數(shù)功能: 創(chuàng)建任務(wù) 輸入?yún)?shù): *pfnTask 指向要?jiǎng)?chuàng)建的任務(wù)(函數(shù)); prio-->任務(wù)優(yōu)先級(jí) 輸出參數(shù): 無 返回值: 1-->創(chuàng)建成功;0-->創(chuàng)建失敗 其他: *********************************************************************/ BOOL OSTaskCreate(void (*pfnTask)(void *pData), INT16U prio); /********************************************************************* 函數(shù)名稱: void OSTimeDly(INT16U ticks) 函數(shù)功能: 延時(shí)當(dāng)前任務(wù) 輸入?yún)?shù): ticks -->延時(shí)個(gè)數(shù),單位為ms 輸出參數(shù): 無 返回值: 無 其他: *********************************************************************/ void OSTimeDly(const INT16U ticks); /********************************************************************* 函數(shù)名稱: void OSShed(void) 函數(shù)功能: 啟動(dòng)操作系統(tǒng),并進(jìn)行調(diào)度 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 其他: *********************************************************************/ void OSStart(void); /********************************************************************* 函數(shù)名稱: void OSTimeTick(void) 函數(shù)功能: 把標(biāo)志位gTickFlag置1, 表明1ms時(shí)間到 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 其他: 由ISR.C中的void IRQ2(void)調(diào)用 *********************************************************************/ void OSTimeTick(void); // This function will be use in ISR /********************************************************************* 函數(shù)名稱: INT16U OSActiveTask(INT16U ivTaskID) 函數(shù)功能: 使任務(wù)進(jìn)入就緒狀態(tài) 輸入?yún)?shù): ivTaskID -->任務(wù)ID號(hào) 輸出參數(shù): 無 返回值: 任務(wù)狀態(tài)值 其他: *********************************************************************/ INT16U OSActiveTask(INT16U ivTaskID); /********************************************************************* 函數(shù)名稱: INT16U OSTaskSuspend(INT16U ivTaskID) 函數(shù)功能: 使任務(wù)進(jìn)入掛起狀態(tài) 輸入?yún)?shù): ivTaskID -->任務(wù)ID號(hào) 輸出參數(shù): 無 返回值: 任務(wù)狀態(tài)值 其他: *********************************************************************/ INT16U OSTaskSuspend(INT16U ivTaskID); /********************************************************************* 函數(shù)名稱: void SendMessage(INT16U msg) 函數(shù)功能: 把消息發(fā)送給正在等待消息的任務(wù),并立即運(yùn)行該任務(wù) 輸入?yún)?shù): msg-->消息 輸出參數(shù): 無 返回值: 無 其他: *********************************************************************/ BOOL SendMessage(INT16U msg); /********************************************************************* 函數(shù)名稱: void PostMessage(INT16U msg) 函數(shù)功能: 把消息發(fā)送給正在等待消息的任務(wù),使任務(wù)從等待消息狀態(tài)進(jìn)入就緒狀態(tài) 輸入?yún)?shù): msg-->消息 輸出參數(shù): 無 返回值: 1: 其他: *********************************************************************/ BOOL PostMessage(INT16U msg); /********************************************************************* 函數(shù)名稱: void WaitMessage(INT16U msg) 函數(shù)功能: 使當(dāng)前任務(wù)進(jìn)入等待消息的狀態(tài) 輸入?yún)?shù): msg-->消息 輸出參數(shù): 無 返回值: 無 其他: *********************************************************************/ void WaitMessage(INT16U waitMsg, INT16U timeout); ////////////////////////////////////////////////////////////////////////////////// // 任務(wù)狀態(tài)值(用于操作系統(tǒng)使用) #define NO_TASK_RDY 0x0000 #define TASK_RDY 0x0001 #define TASK_DELAY 0x0002 #define TASK_SUSPEND 0x0003 #define TASK_INVALITE 0x0004 //////////////////////////////////////////////////// |
| 2樓: | >>參與討論 |
| 作者: lansy 于 2006/4/15 22:14:00 發(fā)布:
下面是源程序: 歡迎進(jìn)入我的BLOG查看更詳細(xì)的信息http://blog.21ic.com/blog.asp?NAME=lansy /******************************************************************************* COPYRIGHT(C)桂林電子工業(yè)學(xué)院電子工程系科技協(xié)會(huì) All right reserved 文件名: os_core.c 描 述: 微型操作系統(tǒng) 作 者: lansy 日 期: 8/15/2005 函數(shù)定義清單: 1. void OSInit(); 2. void OSTimeTick(); 3. BOOL OSTaskCreate(void (* pfnTask)(void), INT16U ivTaskID) 4. void OSStart(void); 5. void OSTimeDly(INT16U ticks); 6. void SendMessage(INT16U msg); 7. void PostMessage(INT16U msg); 8. void WaitMessage(INT16U msg); 9. INT16U OSActiveTask(INT16U ivTaskID); 10.INT16U OSTaskSuspend(INT16U ivTaskID). *******************************************************************************/ #include "cpu_cfg.h" #include "..\include\os_core.h" #include "..\include\ISR.h" /********************************************************************* 任務(wù)控制塊: *********************************************************************/ typedef struct { void (* pfnTask)(void *pMsg); // 指向任務(wù) INT16U status; // 任務(wù)狀態(tài) INT16U delay; // 任務(wù)延時(shí)時(shí)間 INT16U msg; }OS_TCB; static OS_TCB *pOSTCBCur; /********************************************************************* 本文件全局變量 *********************************************************************/ static OS_TCB OSTCBTbl[OS_MAX_TASKS]; // 任務(wù)控制塊數(shù)組 static BOOL gTickFlag; // 當(dāng)時(shí)標(biāo)中斷產(chǎn)生時(shí),此標(biāo)志位置1 /********************************************************************* 函數(shù)名稱: void OSInit() 函數(shù)功能: 操作系統(tǒng)初始化 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 *********************************************************************/ void OSInit(void) { INT8U i; OS_TCB *pTCBTbl = OSTCBTbl; gTickFlag = 0; for ( i = 0; i < OS_MAX_TASKS; i++ ) { pTCBTbl->pfnTask = 0; pTCBTbl->delay = 0; pTCBTbl->status = NO_TASK_RDY; pTCBTbl++; } SET_SYSCLK(); // 設(shè)置CPU時(shí)鐘,在頭文件cpu_cfg.h中定義 INIT_OS_TIMER(); // 初始化定時(shí)器中斷,在頭文件cpu_cfg.h中定義 RegInterrupt(OSTimeTick, IRQ2_TMB); // 注冊(cè)O(shè)STimeTick(),由中斷調(diào)用 } /********************************************************************* 函數(shù)名稱: void OSTimeTick() 函數(shù)功能: 把標(biāo)志位gTickFlag置1, 表明1ms時(shí)間到 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 其他: 由ISR.C中的void IRQ2(void)調(diào)用 *********************************************************************/ void OSTimeTick(void) { RESET_SYSCLK(); // 凌陽(yáng)單片機(jī)從睡眠狀態(tài)中喚醒時(shí)后, 需要重新設(shè)置CPU時(shí)鐘 gTickFlag = 1; } /********************************************************************* 函數(shù)名稱: BOOL OSTaskCreate(void (*pfnTask)(void), INT16U prio) 函數(shù)功能: 創(chuàng)建任務(wù) 輸入?yún)?shù): *pfnTask 指向要?jiǎng)?chuàng)建的任務(wù)(函數(shù)); prio-->任務(wù)優(yōu)先級(jí) 輸出參數(shù): 無 返回值: 1-->創(chuàng)建成功;0-->創(chuàng)建失敗 其他: *********************************************************************/ BOOL OSTaskCreate(void (*pfnTask)(void *pData), INT16U prio) { if (prio > OS_MAX_TASKS) { return 0; } OSTCBTbl[prio - 1].pfnTask = pfnTask; OSTCBTbl[prio - 1].status = TASK_RDY; // 任務(wù)就緒 OSTCBTbl[prio - 1].msg = FIRST_TRI; // 等待調(diào)度 return 1; } /********************************************************************* 函數(shù)名稱: void OSStart(void) 函數(shù)功能: 啟動(dòng)操作系統(tǒng),并進(jìn)行調(diào)度 輸入?yún)?shù): 無 輸出參數(shù): 無 返回值: 無 其他: *********************************************************************/ void OSStart(void) { INT16U index; ENB_TICK_INT(); // 允許時(shí)標(biāo)中斷,see cpu_cfg.h for detail while(1) { CLEAR_WATCHDOG(); // 清看門狗 IDLE_MODE(); // 使CPU進(jìn)入空閑模 |
|
| 3樓: | >>參與討論 |
| 作者: lansy 于 2006/4/15 22:30:00 發(fā)布:
該簡(jiǎn)易操作系統(tǒng)的一個(gè)實(shí)例 該實(shí)例的功能:在簡(jiǎn)易操作系統(tǒng)地調(diào)度下,單片機(jī)接收紅外鍵盤信號(hào),并把接收到的信號(hào)送到液晶顯示。 #include "..include/os_core.h" #include "../include/RedRevDemo.h" #include "../include/LCD12232.h" #include "../include/main.h" void RedMsgLoop(void *pMsg); void main() { OSInit(); // 初始化操作系統(tǒng) InitRedRev(); // 初始化紅外接收程序 InitLCD(); OSTaskCreate(RedMsgLoop, 1); //創(chuàng)建一個(gè)任務(wù),優(yōu)先級(jí)為1 OSStart(); // 啟動(dòng)任務(wù)調(diào)度 } void RedMsgLoop(void *pMsg) // 只要此任務(wù)處于就緒狀態(tài),就一直不斷地被操作系統(tǒng)調(diào)用 { INT16U keyVal; pMsg = pMsg; if (GetKeyMsg(&keyVal)) // 判斷接收到的鍵值是否有效 { DispStrAt("測(cè)試紅外接收信號(hào)", 0, 0); DispNumSpaceAt(keyVal, 0, 1, 6); // 顯示接收到的紅外鍵盤的鍵值 } WaitMessage(KEY_MSG); // 等待下一個(gè)紅外鍵盤消息,并讓任務(wù)進(jìn)入掛起狀態(tài) } |
|
| 4樓: | >>參與討論 |
| 作者: computer00 于 2006/4/15 23:50:00 發(fā)布:
似乎沒有任務(wù)切換?看起來就像簡(jiǎn)單的函數(shù)調(diào)用。 根據(jù)條件,判斷是否調(diào)用某個(gè)函數(shù),然后一直讓這個(gè)函數(shù)執(zhí)行完畢,再返回,之后再檢查其它條件,并判斷是否運(yùn)行其它函數(shù)。那如果某個(gè)函數(shù)不返回,應(yīng)該就只執(zhí)行它了吧?即高優(yōu)先級(jí)的任務(wù),不能剝奪正在執(zhí)行的任務(wù)使用CPU? 也可以來看看我前段時(shí)間寫的簡(jiǎn)單的OS,大家共同學(xué)習(xí)~~~~~~~ http://blog.21ic.com/more.asp?NAME=computer00&id=9501 |
|
| 5樓: | >>參與討論 |
| 作者: lansy 于 2006/4/16 0:18:00 發(fā)布:
因?yàn)閱纹瑱C(jī)RAM資源實(shí)在寶貴, 所以沒有任務(wù)切換,因此優(yōu)先級(jí)高的任務(wù)不能搶占優(yōu)先級(jí)低的任務(wù)。 任務(wù)的優(yōu)先級(jí)只在延時(shí)等待及消息等待這方面才表現(xiàn)出它的優(yōu)先性。 由于沒有任務(wù)切換,所以寫程序時(shí),不能讓一個(gè)函數(shù)死死的抱住CPU不放,而是通過加入狀態(tài)機(jī)的辦法,讓一個(gè)任務(wù)只占用CPU一小段時(shí)間。 我在Keil上用軟件仿真過,即使 運(yùn)行7或8個(gè)任務(wù),CPU %95 以上的時(shí)間處于空閑狀態(tài)。 我的操作系統(tǒng)的好處就是:沒有任務(wù)切換。 |
|
| 6樓: | >>參與討論 |
| 作者: 逍遙派掌門 于 2006/4/16 10:24:00 發(fā)布:
頂一下 師弟,好樣的! |
|
| 7樓: | >>參與討論 |
| 作者: dengm 于 2006/4/16 10:45:00 發(fā)布:
GOOD! 協(xié)作式os, 實(shí)時(shí)的活留給中斷系統(tǒng) * - 本貼最后修改時(shí)間:2006-4-16 10:48:44 修改者:dengm |
|
| 8樓: | >>參與討論 |
| 作者: hotpower 于 2006/4/16 10:53:00 發(fā)布:
看看~~~ |
|
| 9樓: | >>參與討論 |
| 作者: bs1234 于 2006/4/16 12:48:00 發(fā)布:
頂 |
|
| 10樓: | >>參與討論 |
| 作者: wswh2o 于 2006/4/17 9:03:00 發(fā)布:
這個(gè)還是比較簡(jiǎn)單的, |
|
|
|
| 免費(fèi)注冊(cè)為維庫(kù)電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào) |