新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 基于單片機的協程多任務

        基于單片機的協程多任務

        作者: 時間:2016-11-25 來源:網絡 收藏
        在很多的單片機項目中,由于操作系統的體積以及使用的背景知識,如果采用的話,可能讓項目脫離主要業務方向,這個時候很有必要使用簡單的協程多任務
        1協程多任務的特點
        每個任務優先級平等
        每個任務主動釋放CPU控制權
        2 UCOS等操作系統的特點
        任務存在不同優先級,很方便進行CPU資源的分配。
        對于ucos的任務來說,每個任務都認為自己是獨占cpu的,可以隨便休眠之類,這樣對于代碼的風格的限制比較小,比較好修改現存的模塊。
        操作系統一般提供比較多的服務,對于復雜應用比較好。
        3 協程多任務的應用場合
        協程方式適合簡單的多任務,每個任務要確認其符合協程的模型,不能阻塞cpu運行,要主動釋放CPU,如果考慮到多人合作,或者引入第三方的代碼,進來,那么協程方式恐怕工作量過大(模型改造檢查),這時最好使用操作系統。
        協程或者操作系統的平臺的建立,這些都需要積累,也沒有什么高級和低級的區別,只是針對不同的場景和開發人員選擇不同而已。
        4協程多任務的實現
        為了使用方便,并且將來便于系統升級,多任務采用基于接口的方式定義和實現。
        4.1 任務的定義
        每個任務會管理自己的數據,提供對外接口,每個任務提供以下形式結構
        Struct _task1
        {
        //任務對外接口,函數指針
        Void (*start)(Struct _task1*handle);
        Void (*run)(Struct _task1*handle);
        Void (*stop)(Struct _task1*handle);
        //其他對外接口
        ...
        //任務私有數據
        } task1;
        之所以將對外接口放在任務結構體中,是為了強調這些是任務的對外接口,而且客戶只能調用這里面的接口,另外函數指針也很方便的提供了一個接口和實現的分隔層
        4.2 任務的實現
        任務的實現層面,用戶可以根據對系統和業務的理解,做系統演化,而不會影響到外部接口的使用
        //任務接口實現函數
        Void task1_start(Struct _task1*handle)
        {
        //設置任務開始標識
        }
        Void task1_run(Struct _task1*handle)
        {
        If(handle->status1)
        {
        //處理
        }
        Else if(handle->status2)
        {
        //處理
        }
        }
        Void task1_stop(Struct _task1*handle)
        {
        //設置任務結束標識
        }
        //任務初始化函數,構造任務結構體
        Void task1_init(Struct _task1*handle)
        {
        Handle->start = task_start;
        Handle->run = task_run;
        Handle->stop= task_stop;
        }
        4.3 調用形式
        4.3.1 定義全局任務結構體
        Struct _task1
        {
        //任務對外接口,函數指針
        Void (*start)(Struct _task1*handle);
        Void (*run)(Struct _task1*handle);
        Void (*stop)(Struct _task1*handle);
        //其他對外接口
        ...
        //任務私有數據
        } task1;
        4.3.2 任務初始化
        Task1_init(&task1);
        4.3.3 開始任務
        Task1->start(&task1);
        4.3.4 結束任務
        Task1->stop(&task1);
        4.3.5 任務運行
        一般系統在啟動后運行的一個無限循環語句中有
        While(1)
        {
        Task1->run(&task1);
        Task2->run(&task2)
        ...其他任務運行
        }
        5 定時器以及延時的實現方法
        協程多任務不會在代碼中使用sleep()阻塞CPU的方法做定時器或者休眠,定時器會有一個單獨的任務,任務提供新增定時器、刪除定時器、查詢定時器值等接口來提供軟件定時器功能。
        6 任務間通訊
        原則上通過任務提供的接口來通訊,當然如果通訊工作量過大,不反對使用第三方任務來完成通訊。
        7 驅動層模塊任務例子
        對于務來說,應用層和驅動層是優先級相同的任務,對于很多的驅動來說,例如UART驅動,其發送和接收很多采用的是查詢的方式來進行,下面簡單的使用多任務的結構方式來說明驅動的寫作
        Struct _com{
        //任務對外接口,函數指針
        Void (*start)(Struct _com*handle);
        Void (*run)(Struct _com*handle);
        Void (*stop)(Struct _com*handle);
        //其他對外接口
        Void read(char* ch)
        Void write(char* ch)
        ...
        //任務私有數據
        //驅動狀態,
        Char status;
        }com1;
        //運行代碼
        Void Com_run(Struct _com * handle)
        {
        If(read)
        {
        If(register1)
        {
        }
        Else if(register2)
        {
        }
        }
        Else if(write)
        {
        If(register3)
        {
        }
        Else if(register4)
        {
        }
        }
        }
        從上面代碼可見,驅動模塊其實和普通的任務沒有區別。


        關鍵詞: 單片機協程多任

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 应城市| 米易县| 龙陵县| 龙川县| 洛阳市| 兰考县| 哈密市| 九龙坡区| 延庆县| 桦南县| 濮阳市| 方城县| 奉新县| 从化市| 高唐县| 奉节县| 乳山市| 咸丰县| 遂川县| 西丰县| 尚义县| 禄劝| 会理县| 清远市| 宁波市| 汾阳市| 天峨县| 分宜县| 沙田区| 平度市| 河东区| 南丹县| 黑河市| 佛坪县| 海宁市| 万安县| 合山市| 凤翔县| 新竹市| 临城县| 吉安县|