新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應用 > uCOS-Ⅱ C51移植筆記

uCOS-Ⅱ C51移植筆記

作者: 時間:2016-11-23 來源:網(wǎng)絡 收藏
(1)實時系統(tǒng)和前/后臺系統(tǒng);

前/后臺系統(tǒng):一個大循環(huán),循環(huán)查詢各種標志位。如果標志位置位,就執(zhí)行相應的服務程序。標志位就是標志事件的發(fā)生,事件響應延時處于不可預測狀態(tài)。最壞的情況是循環(huán)中所有其他的事件服務程序執(zhí)行完,才響應當前事件。中斷服務雖然能即時/優(yōu)先響應,但是它們和主循環(huán)的通訊,也是通過置主循環(huán)中相應的標志位來完成的。

本文引用地址:http://m.butianyuan.cn/article/201611/320408.htm

實時系統(tǒng)(uCOS):整個程序分成一個個看起來好象是并行的任務,每個任務都在等待事件的發(fā)生。除了最低優(yōu)先級任務(在uCOS中是IDLE任務)是死循環(huán)以外,其他的任務都不能死循環(huán),只能在驅(qū)動事件驅(qū)動下工作。任何驅(qū)動事件的產(chǎn)生,都使優(yōu)先級最高的就緒任務運行。任務和任務/任務和中斷的通訊,是通過相應事件驅(qū)動來完成的。

驅(qū)動事件:

不論是什么系統(tǒng),CPU不可能一直在工作。CPU的工作是在各種驅(qū)動事件的驅(qū)動下工作的。CPU在完成一次驅(qū)動事件事件服務程序以后,進入IDLE模式等待新的驅(qū)動事件的發(fā)生。包括實時系統(tǒng)和前/后臺系統(tǒng)都是在驅(qū)動事件的驅(qū)動下運行的。

按照uCOS中的觀點,驅(qū)動事件分為三類:

1、事件 (Event)。包括信號量(Semaphores)、事件標志組(Flag)、郵箱(Message Box)、郵箱隊列(Message Queue)。

2、時間(Time Tick)。包括時間延時和事件超時。

3、中斷(Interrupt)??梢园l(fā)出各種event。

由于第1種事件,通常都是在第2、3種狀態(tài)下發(fā)出的,所以其實事件的驅(qū)動只有兩種:時間(定時)和中斷(各種異步中斷)。

時間實際上也是中斷的一種,可以說程序的驅(qū)動事件只有一種,就是:中斷。

前/后臺系統(tǒng)中還有一種驅(qū)動事件的產(chǎn)生,在主循環(huán)中不斷的查詢。有別與一般的定時查詢,這種查詢是為了將事件的響應時間降到最低,也可以將其歸納于定時(時間)事件。

(2)uCOS C51移植的準備工作;

2004年8月份,我在書城買了一本《uCOS-Ⅱ 第2版》,準備學習RTOS。因為以前沒有玩過RTOS,在工作之余斷斷續(xù)續(xù)的看了3、4章。一直到12月初的時候,公司要重新設(shè)計一個項目,恰好要把uCOS移植到c51上。我的RTOS學習才正式開始。

因為對OS向往以久,我并不想在網(wǎng)上Down一個現(xiàn)成的移植OS程序,做一個OS的應用者。揭開OS的神秘面紗,了解OS的內(nèi)部運行機制,這才是我想要做的。本文的主要目的是討論uCOS的移植,希望對即將進行uCOS c51移植的兄弟有些幫助。對于OS的內(nèi)部運行機制,由于東西比較多,在這里不想太展開。如果以后有時間,也想寫一篇文章來討論討論。

最開始,我的計劃就是看書,看《uCOS-Ⅱ 第2版》??赐赀@本幾百頁的大本本,花了我2個半星期。因為是工作需要,我才可以這樣心安理得的在那里看呀看書^_^,辛苦呀L。在這期間,為了自己的思想不受別人的影響,我堅決沒有從網(wǎng)上下任何uCOS的資料,我手頭的資料就是uCOS-Ⅱ的書和附帶光盤,這些就是最權(quán)威的資料了。在看書的時候,我都堅持做筆記,把每天的重點,明白的東西和心中的疑問都隨時記錄下來。對付這種大本本,前后的知識又相互關(guān)聯(lián),光靠我們的大腦是搞不定啊。

弄懂了uCOS的內(nèi)核,下一本書應該是《單片機高級語言C51Windows環(huán)境編程與應用》。對于Keil C我還是很熟的,還是花了2、3天來復習。這里的重點是C51對匯編的轉(zhuǎn)換結(jié)構(gòu),例于數(shù)據(jù)/系統(tǒng)堆棧的使用,C&Asm混合編程。我想對于任何CPU的uCOS移植,C語言的實現(xiàn)機制,你都是要了解的。這里也是要花大把時間的。

《uCOS-Ⅱ 第2版》和《單片機高級語言C51Windows環(huán)境編程與應用》這兩本書網(wǎng)上都可以下電子檔的,我這里也有(大家需要可以來信索?。?。

uCOS和C51的書都看完了。我就下載了一堆uCOS的C51移植資料。其中的源程序有很多個版本的,不過詳細的移植文檔只有一個版本:巨龍一位大蝦的“uCOS C51移植心得”,相信很多人都看過。這些資料的作者都是我移植過程中的老師,有了這些資料,我才能把心中的朦朧想法變成源程序。但是我也發(fā)現(xiàn)這些資料中大多都有一些錯誤和遺漏,當然這是難免的。這也正是驅(qū)使我寫這篇文章的原因,希望在前輩的基礎(chǔ)上有所進步。歡迎大家來批評!

真正的源代碼移植,我花了大概一個星期時間。

(3)uCOS C51的移植概況;

1、工具:

uCOS 2.52版;

Keil C V6.23a。

2、uCOS V2.52的文件結(jié)構(gòu)與移植所需要的修改:

A、與處理器無關(guān)的文件:

OS_CORE.C

OS_FLAG.C

OS_MBOX.C

OS_MEM.C

OS_MUTEX.C

OS_Q.C

OS_SEM.C

OS_TASK.C

OS_TIME.C

uCOS_II.C

uCOS_II.H

這些文件在c51的移植過程中,只需要給函數(shù)加上重入屬性即可。

B、與應用相關(guān)的文件:

INCLUDES.H: 包含C51的標準庫頭文件;對”pdata”等c51關(guān)鍵字的重定義

OS_CFG.H: “OS_TICKS_PER_SEC”、“ OS_FLAGS”注意可能需要修改。

C、與處理器相關(guān)的文件:

OS_CPU.H: 數(shù)據(jù)類型、關(guān)中斷方法、任務堆棧方向、任務切換的宏定義都需要修改。

OS_CPU_A.ASM: OSTickISR()、OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()這幾個函數(shù)的編寫,是整個移植的關(guān)鍵。

OS_CPU_C.C:OSTaskStkInit()函數(shù)的編寫。

(4)uCOS C51具體的移植過程;

1、C51的堆棧結(jié)構(gòu);

這是整個移植過程中的重中之重,所以特別詳細介紹。

A、 系統(tǒng)堆棧;

c51中,系統(tǒng)堆棧的棧底地址是“?STACK”,棧頂指針就是“SP”拉,棧的生長方向是向上的,??臻g分配在51的內(nèi)部RAM(idata)中。“?STACK”分配在所有內(nèi)部RAM數(shù)據(jù)段的最后面,所以系統(tǒng)堆棧的范圍是從?STACK到內(nèi)部RAM的最高位(0x80或者0xFF)。

B、 數(shù)據(jù)堆棧;

c51中,由于我們使用OS,采用的LARGE編譯模式,所以數(shù)據(jù)堆棧的指針是“?C_XBP”,棧的生長方向是向下的,棧空間分配在51的外部RAM(xdata)中。

C、 C51中斷中堆棧的保護;

研究中斷中堆棧的保護的意義在于,因為uCOS中的任務切換,本身就是模擬一次中斷的發(fā)生:保護Task1的CPU寄存器,SP切換到Task2的堆棧,彈出Task2的CPU寄存器。用C51寫中斷函數(shù)的時候,編譯器會自動保護CPU的寄存器,所以中斷返回時任務調(diào)度OSIntCtxSw(),就不用重新保護寄存器。

C51中斷中調(diào)用函數(shù)可以分為四種情況(中斷函數(shù)本身不設(shè)為reentrant):

一、沒有函數(shù)調(diào)用;

二、調(diào)用非reentrant函數(shù),函數(shù)中沒有嵌套調(diào)用其他函數(shù);

三、調(diào)用非reentrant函數(shù),函數(shù)中嵌套調(diào)用其他函數(shù);

四、調(diào)用reentrant函數(shù)。

t0_isr:

PUSH ACC

PUSH B

PUSH DPH

PUSH DPL

PUSH PSW

MOV PSW,#00H

PUSH AR0

PUSH AR1

PUSH AR2

PUSH AR3

PUSH AR4

PUSH AR5

PUSH AR6

PUSH AR7

用戶代碼

POP AR7

POP AR6

POP AR5

POP AR4

POP AR3

POP AR2

POP AR1

POP AR0

POP PSW

POP DPL

POP DPH

POP B

POP ACC

RETI

因為uCOS中所有的函數(shù)都必須是重入函數(shù),因此我們只需要研究第四種情況下的堆棧保護,對于其他情況有興趣可以在c51中看看。(注意:可能因為c51編譯器的版本不同,上述壓棧的順序可能不同。)

2、uCOS C51任務切換時的堆棧操作;

每個任務都有一個獨立的數(shù)據(jù)堆棧,系統(tǒng)堆棧是公用空間。

保護Task1的CPU寄存器:首先將CPU寄存器按上例壓進Task1系統(tǒng)堆棧,再將整個Task1系統(tǒng)堆棧壓進Task1數(shù)據(jù)堆棧;

SP切換:?C_XBP = Task2 的數(shù)據(jù)堆棧棧頂?shù)刂贰?/p>

彈出Task2的CPU寄存器:從Task2的數(shù)據(jù)堆棧重新恢復整個系統(tǒng)堆棧,然后再從Task2系統(tǒng)堆棧中恢復CPU寄存器值。

實現(xiàn)的方法有很多種,只要遵循uCOS任務切換的原理就可以了。

3、INCLUDES.H的移植;

4、OS_CPU.H的移植;

5、OS_CPU_A.ASM的移植;

6、OS_CPU_C.C的移植;

7、其他的移植;



關(guān)鍵詞: uCOS-ⅡC51移植筆

評論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉