uCOS-II程序設計基礎版本2—周立功_第1頁
uCOS-II程序設計基礎版本2—周立功_第2頁
uCOS-II程序設計基礎版本2—周立功_第3頁
uCOS-II程序設計基礎版本2—周立功_第4頁
uCOS-II程序設計基礎版本2—周立功_第5頁
已閱讀5頁,還剩161頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第1章 C/OS-II微小內核分析 本章導讀 為了方便初學者學習嵌入式實時操作系統的基本原理,作者將C/OS-II V2.52由小到大裁減為幾個只具備基本功能的微小內核。 通過分析僅僅418行的操作系統最小內核,帶領初學者盡快入門。 作者建議在學習或教授本章的過程中,初學者或教師要邊閱讀原碼,邊畫圖,深刻理解過程,因為“過程比結論更重要!”。目錄概述最小內核臨界區(qū)與中斷管理任務的結束信號量刪除信號量目錄概述最小內核臨界區(qū)與中斷管理任務的結束信號量刪除信號量1.1 概述 C/OS-II微小內核簡介C/OS-II 體系結構C/OS-II與處理器無關的代碼 OS_Q.COS_CORE.C OS_SE

2、M.COS_FLAG.C OS_TASK.COS_MBOX.C OS_TIME.COS_MEM.C uCOS_H.C OS_MUTEX.C uCOS_H.H CPU定時器硬 件軟 件C/OS-II與處理器相關的代碼 (移植時需要修改)OS_CPU.HOS_CPU_A_ASMOS_CPU_C.CC/OS-II與應用程序相關的代碼OS_CFG.H INCLUDES.H用戶應用程序C/OS-II C/OS-II 嵌入式實時操作系統的源代碼可以分成三部分:與硬件無關的內核代碼、與處理器有關的移植代碼和用戶配置文件。1.1 概述 C/OS-II微小內核簡介內核代碼 內核代碼位于source目錄下,提供了

3、4個微小內核。它們分別位于sourceSOURCE1(包含建立任務和延時功能)、sourceSOURCE2(增加刪除任務功能)、sourceSOURCE3(增加信號量文件)和sourceSOURCE4(增加刪除信號量功能)。它們的功能依次增強,代碼也依次增大。 以上代碼并沒有完全裁減到最小,還包含了一些參數校驗代碼等非必需代碼,C/OS-II的代碼裁減功能也同時保留,這些代碼大約50多行。 1.1 概述 C/OS-II微小內核簡介移植代碼 本書提供基于ARM的移植代碼,位于arm目錄下,分別為OS_CPU_C.C(移植代碼C語言部分)、OS_CPU_a.S(移植代碼匯編語言部分)、OS_CPU

4、.H(移植代碼頭文件)和IRQ.INC(移植代碼與芯片無關的中斷處理接口程序)4個文件。 1.1 概述 C/OS-II微小內核簡介配置文件 配置文件是每個C/OS-II程序必備的文件,而且不同的程序一般不一樣,但大小基本上相同。配置文件范例位于H目錄下,分別為INCLUDES.H(內核需要的頭文件,對于特定的移植,一般不需要改變)和OS_CFG.H(內核配置的頭文件,一般需要根據程序的需求修改其常量的內容)文件。 一般來說,每個應用程序都有自己的配置文件拷貝,并很可能與范例不同。1.1 概述 函數說明 C/OS-II 微小內核SOURCE4提供OSInit函數。 函數名稱函數名稱OSInit

5、所屬文件所屬文件OS_CORE.C函數原型函數原型void OSInit(void) 功能描述功能描述初始化C/OS-,無函數參數和返回值 特殊說明特殊說明必須在調用OSStart()函數之前調用OSInit(),而只有在調用OSStart()函數之后,C/OS-才真正開始運行多任務1.1 概述 函數說明 C/OS-II 微小內核SOURCE4提供OSStart函數。 函數名稱函數名稱OSStart 所屬文件所屬文件OS_CORE.C函數原型函數原型void OSStart(void)功能描述功能描述啟動C/OS-II的多任務環(huán)境,無函數參數和返回值特殊說明特殊說明在調用OSStart( )之

6、前必須先調用OSInit ( )。在用戶程序中OSStart( )只能被調用一次,第二次調用OSStart( )將不執(zhí)行任何操作1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSTaskCreate函數。 函數名稱函數名稱OSTaskCreate 所屬文件所屬文件OS_TASK.C函數原型函數原型INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)功能描述功能描述建立一個新任務。既可以在多任務環(huán)境啟動之前,也可以在正在運行的任務中創(chuàng)建任務函數參數函數參數task:指

7、向任務代碼的指針(函數指針) pdata:傳遞給任務的參數(一個變量指針)ptos :指向任務堆棧棧頂的指針 prio :任務的優(yōu)先級 特殊說明特殊說明任務堆棧必須聲明為OS_STK類型。注意:在中斷處理程序中不能建立任務。在任務中必須調用C/OS提供的下述過程之一:延時等待、任務掛起、等待事件發(fā)生(等待信號量,消息郵箱、消息隊列),以便其它任務也能獲得CPU的使用權 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSTimeDly函數。 函數名稱函數名稱OSTimeDly 所屬文件所屬文件OS_TIME.C函數原型函數原型void OSTimeDly (INT16U tic

8、ks)功能描述功能描述將一個任務延時若干個時鐘節(jié)拍,無函數返回值。延時時間的長度可從0到65535個時鐘節(jié)拍,延時時間0表示不進行延時,函數將立即返回調用者,延時的具體時間依賴于系統每秒鐘有多少時鐘節(jié)拍(由文件OS_CFG.H中的常量OS_TICKS_PER _SEC設定) 函數參數函數參數 ticks:要延時的時鐘節(jié)拍數 特殊說明特殊說明延時時間0表示不進行延時操作,而立即返回調用者。為了確保設定的延時時間,建議用戶設定的時鐘節(jié)拍數加1。例如,希望延時10個時鐘節(jié)拍,可設定參數為11 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSTimeTick函數。 函數名稱函數名稱

9、OSTimeTick 所屬文件所屬文件OS_CORE.C函數原型函數原型void OSTimeTick(void)功能描述功能描述在每次時鐘節(jié)拍中斷服務程序中被調用,無函數參數和返回值。OSTimeTick()檢查處于延時狀態(tài)的任務是否達到延時時間,或正在等待事件的任務是否超時特殊說明特殊說明OSTimeTick()的運行時間和系統中的任務數直接相關,在任務或中斷中都可以調用。如果在任務中調用,任務的優(yōu)先級應該很高(優(yōu)先級數字很小),這是因為OSTimeTick()負責所有任務的延時操作 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSTaskDel函數。 函數名稱函數名稱

10、OSTaskDel 所屬文件所屬文件OS_TASK.C函數原型函數原型INT8U OSTaskDel (INT8U prio)功能描述功能描述刪除一個指定優(yōu)先級的任務。被刪除的任務將回到休眠狀態(tài),任務被刪除后可以用函數OSTaskCreate()重新建立函數參數函數參數prio :指定要刪除任務的優(yōu)先級,如果為OS_PRIO_SELF則刪除自身 函數返回值函數返回值OS_NO_ERR:函數調用成功OS_TASK_DEL_IDLE:錯誤,試圖刪除空閑任務(Idle task)OS_TASK_DEL_ ERR:錯誤,指定要刪除的任務不存在OS_PRIO_INVALID:參數指定的優(yōu)先級大于OS_L

11、OWEST_PRIOOS_TASK_DEL_ISR:錯誤,試圖在中斷處理程序中刪除任務 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSIntEnter函數。 函數名稱函數名稱OSIntEnter 所屬文件所屬文件OS_CORE.C函數原型函數原型void OSIntEnter (void)功能描述功能描述通知C/OS-一個中斷服務已開始執(zhí)行,這有助于C/OS-掌握中斷嵌套的情況。通常OSIntExit()和OSIntEnter()聯合使用,無函數參數和返回值 特殊說明特殊說明在中斷服務程序中,如果保證直接遞增OSIntNesting“原子操原子操作作”,中斷服務程序使用直

12、接遞增OSIntNesting的方法而不調用OSIntEnter()函數何為原子操作?在一個任務的執(zhí)行過程中,如果有某些操作何為原子操作?在一個任務的執(zhí)行過程中,如果有某些操作不希望在執(zhí)行過程中被別的任務或中斷打斷,那么這些不希不希望在執(zhí)行過程中被別的任務或中斷打斷,那么這些不希望被打斷的操作就是原子操作望被打斷的操作就是原子操作1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSIntExit函數。 函數名稱函數名稱OSIntExit 所屬文件所屬文件OS_CORE.C函數原型函數原型void OSIntExit(void)功能描述功能描述通知C/OS-一個中斷服務已執(zhí)行完畢

13、,這有助于C/OS-掌握中斷嵌套的情況。通常OSIntExit()和OSIntEnter()聯合使用。當最后一層嵌套的中斷執(zhí)行完畢后,如果有更高優(yōu)先級的任務準備就緒,C/OS-會調用任務調度函數,在這種情況下,中斷返回到更高優(yōu)先級的任務而不是被中斷了的任務。無函數參數和返回值 特殊說明特殊說明在任務級不能調用該函數。即使中斷服務程序使用直接遞增OSIntNesting的方法(沒有調用OSIntEnter()),也必須調用OSIntExit()函數 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供禁止/允許中斷函數。 函數名稱函數名稱OS_ENTER_CRITICAL()和OS_

14、EXIT_CRITICAL() 所屬文件所屬文件移植代碼函數原型函數原型由移植代碼決定 功能描述功能描述一般來說,OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()為定義的宏,用來禁止、打開CPU的中斷,無函數參數和返回值 特殊說明特殊說明OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()必須成對使用 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSSemCreate函數。 函數名稱函數名稱OSSemCreate 所屬文件所屬文件OS_SEM.C函數原型函數原型OS_EVENT *OSSemCreate (INT16U c

15、nt)功能描述功能描述建立并初始化一個信號量函數參數函數參數cnt :建立的信號量的初始值,可以取0到65535之間的任何值函數返回值函數返回值正常 : 指向分配給所建立的信號量的事件控制塊的指針NULL :沒有可用的事件控制塊 特殊說明特殊說明必須先建立信號量,然后使用 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSSemPend函數。 函數名稱函數名稱OSSemPend 所屬文件所屬文件OS_SEM.C函數原型函數原型void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)功能描述功能描述等待信號量:當

16、任務調用OSSemPend()函數時,如果信號量的值大于零,那么OSSemPend()函數對該值減一并返回:如果調用時信號量等于零,那么OSSemPend()函數將任務加入該信號量的等待列表,任務將等待直到獲得信號量或超時 函數參數函數參數cnt :建立的信號量的初始值,可以取0到65535之間的任何值特殊說明特殊說明必須先建立信號量,然后使用,不允許在中斷中調用該函數,因為中斷不能被掛起 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSSemPost函數。 函數名稱函數名稱OSSemPost 所屬文件所屬文件OS_SEM.C函數原型函數原型INT8U OSSemPost

17、(OS_EVENT *pevent)功能描述功能描述發(fā)送信號量:如果指定的信號量是零或大于零,OSSemPost()函數遞增該信號量并返回。如果有任務在等待信號量,則最高優(yōu)先級的任務將得到信號量并進入就緒狀態(tài)。然后進行任務調度,決定當前運行的任務是否仍然為處于最高優(yōu)先級的就緒態(tài)的任務函數參數函數參數pevent :指向信號量的指針,OSSemCreate()的返回值函數返回值函數返回值OS_NO_ERR :發(fā)送信號量成功OS_SEM_OVF :信號量的值溢出OS_ERR_EVENT_TYPE :pevent 不是指向信號量的指針OS_ERR_PEVENT_NULL :錯誤,pevent為NUL

18、L 特殊說明特殊說明必須先建立信號量,然后使用 1.1 概述 函數說明C/OS-II 微小內核SOURCE4提供OSSemDel函數。 函數名稱函數名稱OSSemDel 所屬文件所屬文件OS_SEM.C函數原型函數原型OS_EVENT *OSSemDel (OS_EVENT *pevent, INT8U opt, INT8U *err)功能描述功能描述刪除信號量:在刪除信號量之前,應當刪除可能會使用這個信號量的任務函數參數函數參數pevent:指向信號量的指針,OSSemCreate()的返回值opt:定義信號量刪除條件 OS_DEL_NO_PEND:沒有任何任務等待信號量才刪除 OS_DEL

19、_ALWAYS:立即刪除err:用于返回錯誤碼特殊說明特殊說明(1)使用這個函數調用時,必須特別小心,因為其它任務可能還要用這個信號量(2)當掛起任務就緒時,中斷關閉時間與掛起任務數目有關(3)其它任務并不知道信號量被刪除,除非檢查pevent是否指向NULL 目錄概述最小內核臨界區(qū)與中斷管理任務的結束信號量刪除信號量1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒

20、算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.2 最小內核 基本概念什么是任務 在實時多任務系統下運行的應用軟件程序就是任務。在沒有使用OS的前后臺系統中,我們可以認為main函數以及通過main函數調用的全體函數為一個任務。 通常將“并行程序執(zhí)行的基本邏輯單位”稱之為“任務”,也就是說任務是可以被分割為獨立的且可并行執(zhí)行的基本邏輯單位程序。一個任務的程序是順序執(zhí)行的,而不同任務的程序卻是并行執(zhí)行的。任務必須包括相互“獨立”和“并行”執(zhí)行兩個方面。1.2 最小內核 基本概念

21、獨立 獨立具體指任務不能彼此直接調用,也不能直接進行數據交換。 void task0 (void) task1( );void task1 (void) void task0 (void) task1( );void task1 (void) 內核通過調用調用執(zhí)行任務,因此可以看成整體整體。void task0 (void) 系統調用中斷內核任務任務任務通過內核內核進行任務調度和數據交換。1.2 最小內核 基本概念獨立 獨立具體指任務不能彼此直接調用,也不能直接進行數據交換。 void task0 (void) task1( );void task1 (void) void task0 (vo

22、id) 系統調用void task1 (void) 內核1.2 最小內核 基本概念并行執(zhí)行 想象相互獨立的任務各自擁有一個CPU,每個CPU各自執(zhí)行各自的任務,此即任務的并行執(zhí)行。但實際上CPU只有一個,我們認為操作系統為每個任務虛擬了一個CPU。void task0 (void) 可并列執(zhí)行void task1 (void) 可并列執(zhí)行CPUCPUvoid task0 (void) void task1 (void) C/OS-II CPU1.2 最小內核 基本概念任務的狀態(tài) 在C/OS-中,任務有5種狀態(tài),分別為睡眠狀態(tài)、就緒狀態(tài)、運行狀態(tài)、等待狀態(tài)和被中斷狀態(tài)。 睡眠狀態(tài)等待狀態(tài)就緒狀態(tài)

23、被中斷狀態(tài)運行狀態(tài)任務駐留在內存中尚未創(chuàng)建任務已經準備好但尚未運行任務掌握CPU的控制權任務等待事件的而尚未發(fā)生中斷服務程序執(zhí)行打斷任務1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.2 最小內核 案例分析P0.10P0.9LPC2000VCCLED1LED2R1R2T/s10Task10.51CPUTask0Task1TaskIdleT/s10Task00.51P0.9P0.10 在前后臺系統中,一個“模塊”可以調用

24、另一個“模塊”,因此各模塊在執(zhí)行時間上相互錯開,且信息傳遞“同步”。1.2 最小內核 案例分析 在操作系統中,程序設計就象記流水帳一樣簡單。主程序開始uC/OS-II初始化建立任務啟動多任務環(huán)境(讓任務開始執(zhí)行)結束(永遠不可能執(zhí)行到這里)任務0初始化目標板初始化GPIO點亮LED1等待1/4秒熄滅LED1等待1/4秒任務1初始化GPIO點亮LED2等待1/3秒熄滅LED2等待1/3秒1.2 最小內核 案例分析 注意:在進入首個運行的任務之前要禁止產生任何受操作系統管理的中斷,包括節(jié)拍定時器的中斷。因為這類中斷產生后操作系統會對任務進行掃描,并嘗試進行任務切換,這將會導致程序出錯,甚至引起系統

25、崩潰。所以通常將硬件初始化函數放在首個運行任務開始的地方執(zhí)行。 void Task0(void *pdata) pdata = pdata; TargetInit( ); while (1) 1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.2 最小內核 任務控制塊 C/OS-是通過任務控制塊來管理任務的。任務控制塊是一個基于鏈表的數據結構,任務控制塊主要用于記錄任務的堆棧棧頂指針、指向下一個任務控制塊的指針、任務等待的

26、延遲時間、任務的當前狀態(tài)標志與任務的優(yōu)先級別等一些與任務管理有關的屬性。 當任務的CPU使用權被剝奪時,C/OS-用任務控制塊來保存該任務的狀態(tài),從而保證任務重新獲得CPU使用權時從斷點處執(zhí)行。1.2 最小內核 任務控制塊typedef struct os_tcb OS_STK *OSTCBStkPtr; struct os_tcb *OSTCBNext; INT16U OSTCBDly; INT8U OSTCBStat; INT8U OSTCBPrio; INT8U OSTCBX; INT8U OSTCBY; INT8U OSTCBBitX; INT8U OSTCBBitY; OS_TCB;

27、任務控制塊定義任務控制塊成員示意圖OSTCBTblOSTCBStkPtrOSTCBNextOSTCBDlyOSTCBStatOSTCBPrioOSTCBXOSTCBYOSTCBBitXOSTCBBitY指向當前任務棧棧頂的指針。C/OS-允許每個任務有自己的棧,尤為重要的是,每個任務的堆棧的容量可以是任意的。指向下一個任務控制塊的指針。用于任務控制塊OS_TCB的鏈接。任務等待的延時時間變量。用于將任務掛起一段時間以等待某事件的發(fā)生,這種等待是有超時限制的。 任務的當前狀態(tài)標志變量。其為0時,任務進入就緒態(tài) 。宏名定義值說明OS_STAT_RDY 0 x00 運行準備就緒 OS_STAT_SE

28、M 0 x01在信號量時掛起 OS_STAT_MBOX 0 x02在郵箱時掛起 OS_STAT_Q 0 x04在隊列時掛起 OS_STAT_SUSPEND 0 x08任務被暫停 OS_STAT_MUTEX 0 x10在互斥信號量時掛起 OS_STAT_FLAG 0 x20在事件標志組時掛起 任務優(yōu)先級變量。變量值越小,任務的優(yōu)先級越高。 1.2 最小內核 任務控制塊 C/OS-最小內核定義了4個指針、 1個數組和1個指針數組 。OSTCBCur指向“當前任務控制塊”的指針;OSTCBFreeList“空任務控制塊”鏈表的表頭指針;OSTCBHighRdy 指向“將要運行最高優(yōu)先級任務控制塊”的

29、指針;OSTCBList“已使用任務控制塊”鏈表的表頭指針;1.2 最小內核 任務控制塊OSTCBPrioTbl任務控制塊優(yōu)先級表,專門用來存放指向各任務控制塊的指針,并按任務的優(yōu)先級別將這些指針存放在數組的各個元素里。 NULLNULLNULLNULL&OSTCBTbl1&OSTCBTbl2NULLOSTCBPrioTbl 012345OS_LOWEST_PRIO-1OS_LOWEST_PRIO&OSTCBTbl0OSTCBStkPtrOSTCBTbl2OSTCBNextOSTCBStkPtrOSTCBTbl1OSTCBNextOSTCBStkPtrOSTCBTbl0OSTCBNextOST

30、CBListNULLTask0Task1OS_TaskIdleOSTCBPrioTbl指向各任務控制塊的起始地址,即OSTCBStkPtr地址。 1.2 最小內核 任務控制塊OSTCBStkPtrOSTCBTbl0OSTCBNextOSTCBStkPtrOSTCBTbl1OSTCBNextOSTCBStkPtrOSTCBTbl2OSTCBNextOSTCBStkPtrOSTCBTblOS_MAX_TASKS+OS_N_SYS_TASKS-1OSTCBNextOSTCBFreeListNULLOSTCBTbl任務控制塊數組,所有的任務控制塊都保存在這個數組中。 任務控制塊初始狀態(tài)建立“單向空任務

31、塊鏈表” 鏈表頭指針存放“節(jié)點”地址存放下一個節(jié)點地址用戶數據表尾存放“空指針”1.2 最小內核 任務控制塊OSTCBTbl任務控制塊數組,所有的任務控制塊都保存在這個數組中。 建立一個用戶任務后的狀態(tài)OSTCBStkPtrOSTCBTbl1OSTCBNextOSTCBStkPtrOSTCBTbl0OSTCBNextOSTCBListNULLOSTCBStkPtrOSTCBTbl2OSTCBNextOSTCBStkPtrOSTCBTblOS_MAX_TASKS+OS_N_SYS_TASKS-1OSTCBNextNULLOSTCBFreeList系統空閑任務用戶任務 初始化空OS_TCB鏈表OS

32、TCBListOSTCBNext OSTCBTbl OS_MAX_TASKS+OS_N_SYS_TASKS-1OSTCBFreeListOSTCBNextOSTCBTbl0OSTCBNextOSTCBTbl1NULLOSTCBNextOSTCBTbl2OSTCBPrioTbl 012345OS_LOWEST_PRIO-1OS_LOWEST_PRIONULLNULLptcb2ptcb1 OS_TCB *ptcb1; OS_TCB *ptcb2;OSTCBList = (OS_TCB *)0; for(i=0;i(OS_LOWEST_PRIO+1);i+) OSTCBPrioTbli = (OS_

33、TCB *)0; ptcb1 = &OSTCBTbl0; ptcb2 = &OSTCBTbl1;for (i = 0; i OSTCBNext = ptcb2; ptcb1+; ptcb2+; ptcb1-OSTCBNext = (OS_TCB *)0; OSTCBFreeList = &OSTCBTbl0;NULLNULLNULLNULLNULLNULLNULLNULL1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.

34、2 最小內核 任務就緒算法 所謂就緒狀態(tài)是指任務準備運行但CPU沒空,任務等待運行的狀態(tài)。 任務就緒算法涉及“任務就緒表OSRdyTbl、映射表OSMapTbl、優(yōu)先級判定表OSUnMapTbl以及變量OSRdyGrp和相關的任務優(yōu)先級prio”,其中映射表OSMapTbl和優(yōu)先級判定表OSUnMapTbl是2個常數表,用于查表算法。 優(yōu)先級19的任務放入就緒表0 0 0 1 0 0 1 1任務優(yōu)先級Prio0 0 0 0 0 0 0 10 0 0 0 0 0 1 00 0 0 0 0 1 0 00 0 0 0 1 0 0 00 0 0 1 0 0 0 00 0 1 0 0 0 0 00 1

35、0 0 0 0 0 01 0 0 0 0 0 0 0OSMapTbl 0123456700000000OSRdyGrpXY0000000000000000000000000000000000000000000000000000000000000000OSRdyTbl 01234567bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit06362616059585756555453525150494847464544434241403938373635343332313029282726252423222120191817161514131211109876543210O

36、SRdyGrp|= OSMapTblPrio 3;OSRdyTblPrio 3 |= OSMapTblPrio & 0 x07;0000010000001000就緒的任務在任務就緒表相應位置置11映射表變量任務就緒表 優(yōu)先級19的任務脫離就緒表0 0 0 1 0 0 1 1任務優(yōu)先級Prio0 0 0 0 0 0 0 10 0 0 0 0 0 1 00 0 0 0 0 1 0 00 0 0 0 1 0 0 00 0 0 1 0 0 0 00 0 1 0 0 0 0 00 1 0 0 0 0 0 01 0 0 0 0 0 0 0OSMapTbl 0123456700000100OSRdyGrpX

37、Y0000000000000000000000000000000000000000000010000000000000000000OSRdyTbl 01234567bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit06362616059585756555453525150494847464544434241403938373635343332313029282726252423222120191817161514131211109876543210If (OSRdyTblPrio 3 &= OSMapTblPrio & 0 x07) = 0) OSRdyGrp &=

38、OSMapTblPrio3;1111101111110111&0000100000000000=000000100&=000000000該優(yōu)先級任務脫離就緒表 優(yōu)先級判定表XY00000000000002n1xxxxxxx100004n2xxxxxx1000118n4xxxxx100010216n8xxxx1000011332n16xxx10000100464n32xx1000001015128n64x100000011061281000000011178線3線優(yōu)先編碼表INT8U const OSUnMapTbl = /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b

39、, c, d, e, f */*0 x00*/0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x10*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x20*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x30*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x40*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,

40、/*0 x50*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x60*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x70*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x80*/ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x90*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xA0*/ 5,

41、0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xB0*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xC0*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xD0*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 xE0*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 xF0*/ 4, 0, 1, 0, 2, 0

42、, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 ;優(yōu)先級判定表計算48在表中的對應值?321 16 4848O 30H01101001OSRdyGrpINT8U const OSUnMapTbl = /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */*0 x00*/0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x10*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x20*/ 5, 0, 1, 0, 2, 0,

43、1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x30*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x40*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x50*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x60*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 x70*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1

44、, 0, 2, 0, 1, 0,/*0 x80*/ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 x90*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xA0*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xB0*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,/*0 xC0*/ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1,

45、0,/*0 xD0*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 xE0*/ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*0 xF0*/ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 ; 所在任務的Y值越小優(yōu)先級越高,所在任務的X值越小優(yōu)先級越高,由此可見最小的Y、X值所對應的任務就是進入就緒態(tài)優(yōu)先級最高的的任務。 查找就緒態(tài)優(yōu)先級最高的任務y= OSUnMapTblOSRdyGrp;x= OSUnMapTblOSRdyTbly;

46、Prio= (y 3) + x;XY0000000000001000000010100000000011100100000000000000000000110000OSRdyTbl 01234567bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0636261605958575655545352515049484746454443424140393837363534333231302928272625242322212019181716151413121110987654321001101001B 69H00110000B 30HY = 0X = 4Prio = 4

47、04Y3 就緒表初始化OSRdyGrpXYOSRdyTbl 01234567bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit06362616059585756555453525150494847464544434241403938373635343332313029282726252423222120191817161514131211109876543210 OSRdyGrp = 0 x00; 00000000prdytbl = &OSRdyTbl0;for (i=0; i1表示發(fā)生嵌套。1.2 最小內核 OS初始化 OS_InitTaskIdle()創(chuàng)建空閑任務

48、函數比較重要,當所有用戶任務都可能未處于就緒狀態(tài)的時候,此時CPU將運行空閑任務,以防程序跑飛。 #define OS_IDLE_PRIO (OS_LOWEST_PRIO)#define OS_STK_GROWTH 1#define OS_TASK_IDLE_STK_SIZE 512 空閑任務優(yōu)先級堆棧由高地址往低地址生長空閑任務堆棧大小1.2 最小內核 OS初始化void OS_TaskIdle (void *pdata) pdata = pdata; for (;) static void OS_InitTaskIdle (void) #if OS_STK_GROWTH = 1 (void

49、)OSTaskCreate(OS_TaskIdle, (void *)0, &OSTaskIdleStkOS_TASK_IDLE_STK_SIZE - 1, OS_IDLE_PRIO); #else (void)OSTaskCreate(OS_TaskIdle, (void *)0, &OSTaskIdleStk0, OS_IDLE_PRIO); #endif創(chuàng)建空閑任務空閑任務 OS初始化后狀態(tài)OSTCBFreeListXYOSRdyTbl 01Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0151413121110 9 87 6 5 4 3 2 1 0OSRdyGrpOST

50、CBStkPtrOSTCBTbl0OSTCBNextOSTCBPrioTbl 012345OS_LOWEST_PRIO-1OS_LOWEST_PRIOOSTCBStkPtrOSTCBTbl1OSTCBNextOSTCBStkPtrOSTCBTbl2OSTCBNextOSTCBStkPtrOSTCBTbl3OSTCBNextOSTCBStkPtrOSTCBTblOS_MAX_TASKS+OS_N_SYS_TASKS-1OSTCBNextOSTCBListNULL0 0 0 0 0 0 1 00 0 0 0 0 0 1 00 0 0 0 0 0 0 0OSPrioCurOSTCBCurNULLOS

51、PrioHighRdy0 0 0 0 0 0 0 00OSIntNestingFALSEOSRunningOSTCBHighRdyNULL任務堆棧1.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結1.2 最小內核 任務管理 C/OS-通過任務控制塊對任務進行管理,創(chuàng)建任務實際上就是給任務代碼分配一個任務控制塊,通過調用函數OSTaskCreate()實現。 任務可以在多任務調度開始前建立,也可以在其它任務的執(zhí)行過程中建立。在

52、開始多任務調度之前,用戶必須至少創(chuàng)建一個任務,但任務不能在中斷服務程序(ISR)中建立。任務創(chuàng)建函數OSTaskCreate()需要4個參數:l tasktask:指向任務代碼的指針,即任務函數名,指向任務的代碼地址;l pdatapdata:當任務開始執(zhí)行時傳遞給任務的參數的指針;l ptosptos:分配給任務的堆棧的棧頂指針;l prioprio:分配給任務的優(yōu)先級。 1.2 最小內核 任務管理 任務管理開始同優(yōu)先級任務存在標明“任務正在創(chuàng)建”初始化任務堆棧設置任務控制塊設置成功標明這個優(yōu)先級的任務不存在返回錯誤代碼返回“同優(yōu)先級任務存在”已啟動多任務環(huán)境調度任務返回“成功”YNYNYN

53、創(chuàng)建任務流程圖INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) OS_STK *psp; INT8U err; OS_ENTER_CRITICAL(); if (OSTCBPrioTblprio = (OS_TCB *)0); OSTCBPrioTblprio = (OS_TCB *)1; OS_EXIT_CRITICAL(); psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); err = OS_TCBInit(prio,

54、psp, (OS_STK *)0, 0, 0, (void *)0, 0); if (err = OS_NO_ERR) if (OSRunning = TRUE); OS_Sched(); else OS_ENTER_CRITICAL(); OSTCBPrioTblprio = (OS_TCB *)0; OS_EXIT_CRITICAL(); return (err); return (OS_PRIO_EXIST); 任務管理創(chuàng)建任務函數進入臨界區(qū)判斷優(yōu)先級沒占用并保留退出臨界區(qū)初始化任務堆棧獲取任務控制塊并初始化初始化成功并判斷系統啟動任務調度初始化不成功并清除優(yōu)先級占用任務控制塊初始化結果

55、返回判斷任務優(yōu)先級存在返回OSTaskStkInit()OSInit()OSTaskCreate()OSStart()return 0OS_TCBInit()建立任務的堆棧,最后返回棧頂指針stk如果系統調用成功,則返回OS_NO_ERR,否則返回OS_NO_MORE_TCB,說明系統中沒有OS_TCB可以分配給其它任務了main ()OSTaskCreat() 任務管理 通過分析創(chuàng)建任務OSTaskCreate()函數得知,OSTaskCreate()調用了OSTaskStkInit()任務堆棧初始化函數和OS_TCBInit()函數獲得并初始化一個OS_TCB。 1.2 最小內核q基本概念

56、q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結 棧是限定僅在表尾進行插入與刪除操作的線性表,表頭端稱為棧底,表尾端稱為棧頂。 棧的修改是按照后進先出的原則,因此稱為后進先出的線性表(簡稱LIFO結構)。插入元素的操作稱為入棧,刪除棧頂元素的操作稱為出棧。1.2 最小內核 任務堆棧初始化1.2 最小內核 任務堆棧初始化 C/OS-使用結構常量OS_STK_GROWTH指定堆棧的生長方式:OS_STK_GROWTH 1OS_STK_GROWTH 0A

57、DS只支持“向下生長”的方式,且必須“滿遞減堆棧”內存高端內存低端堆棧增長方向棧頂棧底內存高端內存低端堆棧增長方向棧底棧頂1.2 最小內核 任務堆棧初始化堆棧初始化OSTaskStkInit()需要4個參數:l task:任務開始執(zhí)行的地址,在C語言中就是任務函數名;l pdata:當任務開始執(zhí)行時傳遞給任務的參數的指針,它應當保存到R0中;l ptos:分配給任務的堆棧棧頂指針;l otp:保留參數,目前沒有使用。函數 任務堆棧初始化函數內存高端內存低端堆棧增長方向TaskEntrytask0000000000000 x1fpdata0PCLRR12R11R10R9R8R7R6R5R4R3R

58、2OsEnterSumCPSRR0R1stkptosstk = &OSTaskIdleStk(OS_TASK_IDLE_STK_SIZE-1)-17OS_STK *OSTaskStkInit(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt) OS_STK *stk; extern void TaskEntry(void); opt = opt; stk = ptos; *stk = (OS_STK) TaskEntry; *-stk = (OS_STK) task; *-stk = 0; *-stk = 0; *-st

59、k = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = 0; *-stk = (unsigned int) pdata; *-stk = 0 x1f; *-stk = 0; return (stk);ptos = &OSTaskIdleStkOS_TASK_IDLE_STK_SIZE-11.2 最小內核q基本概念q案例分析q任務控制塊q任務就緒算法qOS初始化q任務管理q任務堆棧初始化q獲取并初始化TCBq啟動OSqTargetInit 初始化q

60、時間管理q任務調度qSWI軟件中斷異常q任務級的任務調度小結 任務控制塊函數OS_TCBInit()用于從任務控制塊鏈表獲取并初始化一個任務控制塊,再將這個任務控制塊鏈接到任務控制塊鏈表的頭部。 當建立任務時,系統就會將空任務控制塊指針OSTCBFreeList指向的任務控制塊分配給該任務,然后OSTCBFreeList的值便調整為指向鏈表中下一個空的任務塊,OSTCBList總是指向最后建立的任務控制塊。1.2 最小內核 獲取并初始化TCB 函數OS_TCBInit()雖然具有7個參數,但只有2個參數有效,其它參數預留以后升級使用:l prio:任務的優(yōu)先級;l ptos:指向任務堆棧的棧頂

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論