關於裸機多任務
阿新 • • 發佈:2018-05-06
不發送 display 關於 定時器中斷 ber 函數 splay 賦值 mps
不過就是心理有疑問:不用OS能不能很好的解決這些問題呢?又不用額外開個定時器呢?
之前裸跑做復雜應用的時候難道都是像mini的綜合歷程一樣很費勁的寫菜單數據結構再來個大循環?要真是這樣上OS確實是上上之策
總想把不懂得東西搞清楚……有時候太愛鉆牛角尖,自己跟自己過不去 都說ucos商業要錢,freertos不要錢……那麽ucos怎麽知道我在產品上用沒用他的系統呢?
“小的延時通過死等實現,對於大於最小時間片(1ms)的延時,是不是在delay的地方重新對TaskComps.Timer進行賦值呢?”
這個問題是你提出來的吧?別的不說,先考慮IIC時序,有部分延時是超過1ms的,那請問你怎麽解決這個時序的延時?想不通的話看看我上面的截圖吧,我的測試代碼是最小延時節拍是1ms,只要你的IIC延時大於1ms,可以直接像操作系統那樣子調用PROCESS_DELAY來實現 樓主,你貼的代碼,是屬於時間觸發的嵌入式系統構架!
然而,樓主你的理解本質上是錯的!
原因:TaskProcess這個函數就不應該在中斷裏運行,而是應該在主循環運行!
結構是:IRQ:TaskRemarks
Main Loop:TaskProcess
這是典型的前臺負責系統滴答,後臺負責任務輪詢調度!
然後:在設計任務的時候,設計任務時單次運行時間應該越短越好!
除時序延時外的延時都盡量去除而采用狀態轉移(狀態機)來處理!
假如要發送一個hello
如果while(print(hello))這種形式是最笨的設計方法!
用switch ---h---e---l---l---o把hello分成5次發送,發送不要死等標記,發送成功退出,不發送成功照樣退出!
設計的時候考慮消費者生產者原則!認清輔助和主線任務,必要的時候要做取舍(偏心)!
出問題那是設計者笨!
任務的運行期間出現中斷是必然的事情,這個時候就需要你來保護了(原子保護)
這個正點原子保護在你們用的OS中有個名詞,叫臨界區!
// 任務結構
typedef
struct
_TASK_COMPONENTS
{
uint8 Run;
// 程序運行標記:0-不運行,1運行
uint8 Timer;
// 計時器
uint8 ItvTime;
// 任務運行間隔時間
void
(*TaskHook)(
void
);
// 要運行的任務函數
} TASK_COMPONENTS;
// 任務定義
//定時器中斷函數
void
TaskRemarks(
void
)
{
uint8 i;
for
(i=0; i<TASKS_MAX; i++)
// 逐個任務時間處理
{
if
(TaskComps[i].Timer)
// 時間不為0
{
TaskComps[i].Timer--;
// 減去一個節拍
if
(TaskComps[i].Timer == 0)
// 時間減完了
{
TaskComps[i].Timer = TaskComps[i].ItvTime;
// 恢復計時器值,從新下一次
TaskComps[i].Run = 1;
// 任務可以運行
}
}
}
}
/**************************************************************************************
* FunctionName : TaskProcess()
* Description : 任務處理
* EntryParameter : None
* ReturnValue : None
**************************************************************************************/
void
TaskProcess(
void
)
{
uint8 i;
for
(i=0; i<TASKS_MAX; i++)
// 逐個任務時間處理
{
if
(TaskComps[i].Run)
// 時間不為0
{
TaskComps[i].TaskHook();
// 運行任務
TaskComps[i].Run = 0;
// 標誌清0
}
}
}
static
TASK_COMPONENTS TaskComps[] =
{
{0, 60, 60, TaskDisplayClock},
// 顯示時鐘
{0, 20, 20, TaskKeySan},
// 按鍵掃描
{0, 30, 30, TaskDispStatus},
// 顯示工作狀態
// 這裏添加你的任務。。。。
};
這個就要靠你自己編碼了 ,既然在滴答中斷中做任務調度,那麽只需在延時的滴答時間內不去做該任務的調度即可,這樣不就是實現了延時掛起任務了嗎 做一個實現延時並且掛起任務的函數api
剛才找到了那個案例,看了下還真是大循環……並不適合我現在做的這個多任務並行產品上,會考慮用OS去解決這個問題……不過就是心理有疑問:不用OS能不能很好的解決這些問題呢?又不用額外開個定時器呢?
之前裸跑做復雜應用的時候難道都是像mini的綜合歷程一樣很費勁的寫菜單數據結構再來個大循環?要真是這樣上OS確實是上上之策
總想把不懂得東西搞清楚……有時候太愛鉆牛角尖,自己跟自己過不去 都說ucos商業要錢,freertos不要錢……那麽ucos怎麽知道我在產品上用沒用他的系統呢?
“小的延時通過死等實現,對於大於最小時間片(1ms)的延時,是不是在delay的地方重新對TaskComps.Timer進行賦值呢?”
這個問題是你提出來的吧?別的不說,先考慮IIC時序,有部分延時是超過1ms的,那請問你怎麽解決這個時序的延時?想不通的話看看我上面的截圖吧,我的測試代碼是最小延時節拍是1ms,只要你的IIC延時大於1ms,可以直接像操作系統那樣子調用PROCESS_DELAY來實現 樓主,你貼的代碼,是屬於時間觸發的嵌入式系統構架!
然而,樓主你的理解本質上是錯的!
原因:TaskProcess這個函數就不應該在中斷裏運行,而是應該在主循環運行!
結構是:IRQ:TaskRemarks
Main Loop:TaskProcess
這是典型的前臺負責系統滴答,後臺負責任務輪詢調度!
然後:在設計任務的時候,設計任務時單次運行時間應該越短越好!
除時序延時外的延時都盡量去除而采用狀態轉移(狀態機)來處理!
假如要發送一個hello
如果while(print(hello))這種形式是最笨的設計方法!
用switch ---h---e---l---l---o把hello分成5次發送,發送不要死等標記,發送成功退出,不發送成功照樣退出!
設計的時候考慮消費者生產者原則!認清輔助和主線任務,必要的時候要做取舍(偏心)!
出問題那是設計者笨!
任務的運行期間出現中斷是必然的事情,這個時候就需要你來保護了(原子保護)
這個正點原子保護在你們用的OS中有個名詞,叫臨界區!
關於裸機多任務