建立任務,OSTaskCreate 原始碼解析

2021-07-08 20:04:14 字數 3475 閱讀 6106

想讓uc/os-ⅱ管理使用者的任務,使用者必須要先建立任務。使用者可以通過傳遞任務位址和其它引數到以下兩個函式之一來建立任務:ostaskcreate() 或 ostaskcreateext()。ostaskcreate()與uc/os是向下相容的,ostaskcreateext()是ostaskcreate()的擴充套件版本,提供了一些附加的功能。用兩個函式中的任何乙個都可以建立任務。

任務可以在多任務排程開始前建立,也可以在其它任務的執行過程中被建立。在開始多任務排程(即呼叫osstart())前,使用者必須建立至少乙個任務。任務不能由中斷服務程式(isr)來建立。

ostaskcreate()的**如程式清單 l4.1所述。從中可以知道,ostaskcreate()需要四個引數:

task是任務**的指標,

pdata是當任務開始執行時傳遞給任務的引數的指標,

ptos是分配給任務的堆疊的棧頂指標(參看4.02,任務堆疊),

prio是分配給任務的優先順序。

//建立乙個新任務  

#if os_task_create_en > 0 //允許生成ostaskcreate()函式

int8u ostaskcreate (void (*task)(void *pd), void *pdata, os_stk *ptos, int8u prio)

#endif

os_enter_critical(); //關閉中斷

if (ostcbpriotbl[prio] == (os_tcb *)0)

} else

return (err); //返回(獲得並定義初始化任務控制塊是否成功)

} os_exit_critical(); //開啟中斷

return (os_prio_exist); //返回(具有該優先順序的任務已經存在)

} #endif

ostaskcreate()一開始先檢測分配給任務的優先順序是否有效[l4.1(1)]。任務的優先順序必須在0到os_lowest_prio之間。接著,ostaskcreate()要確保在規定的優先順序上還沒有建立任務[l4.1(2)]。在使用uc/os-ⅱ時,每個任務都有特定的優先順序。如果某個優先順序是空閒的,uc/os-ⅱ通過放置乙個非空指標在ostcbpriotbl中來保留該優先順序[l4.1(3)]。這就使得ostaskcreate()在設定任務資料結構的其他部分時能重新允許中斷[l4.1(4)]。

然後,ostaskcreate()呼叫ostaskstkinit()[l4.1(5)],它負責建立任務的堆疊。該函式是與處理器的硬體體系相關的函式,可以在os_cpu_c.c檔案中找到。有關實現ostaskstkinit()的細節可參看第8章——移植uc/os-ⅱ。如果已經有人在你用的處理器上成功地移植了uc/os-ⅱ,而你又得到了他的**,就不必考慮該函式的實現細節了。ostaskstkinit()函式返回新的堆疊棧頂(psp),並被儲存在任務的0s_tcb中。注意使用者得將傳遞給ostaskstkinit()函式的第四個引數opt置0,因為ostaskcreate()與ostaskcreateext()不同,它不支援使用者為任務的建立過程設定不同的選項,所以沒有任何選項可以通過opt引數傳遞給ostaskstkinit()。

uc/os-ⅱ支援的處理器的堆疊既可以從上(高位址)往下(低位址)遞減也可以從下往上遞增。使用者在呼叫ostaskcreate()的時候必須知道堆疊是遞增的還是遞減的(參看所用處理器的os_cpu.h中的os_stack_growth),因為使用者必須得把堆疊的棧頂傳遞給ostaskcreate(),而棧頂可能是堆疊的最高位址(堆疊從上往下遞減),也可能是最低位址(堆疊從下往上長)。

一旦ostaskstkinit()函式完成了建立堆疊的任務,ostaskcreate()就呼叫ostcbinit()[l4.1(6)],從空閒的os_tcb池中獲得並初始化乙個os_tcb。ostcbinit()的**如程式清單 l4.2所示,它存在於0s_core.c檔案中而不是os_task.c檔案中。

ostcbinit()函式首先從os_tcb緩衝池中獲得乙個os_tcb[l4.2(1)],如果os_tcb池中有空閒的os_tcb[l4.2(2)],它就被初始化[l4.2(3)]。注意一旦os_tcb被分配,該任務的建立者就已經完全擁有它了,即使這時核心又建立了其它的任務,這些新任務也不可能對已分配的os_tcb作任何操作,所以ostcbinit()在這時就可以允許中斷,並繼續初始化os_tcb的資料單元。

//建立乙個新任務。與ostaskcreate()不同的是,ostaskcreateext()允許使用者設定更多的細節  

//內容。任務的建立可以在多工環境啟動之前,也可以在正在執行的任務中建立,但中斷處理

//程式中不能建立新任務。乙個任務必須為無限迴圈結構,且不能有返回點。

#if os_task_create_ext_en > 0 //允許生成ostaskcreateext()函式

int8u ostaskcreateext (void (*task)(void *pd), //建立擴充套件任務(任務**指標)

void *pdata, //傳遞引數指標

os_stk *ptos, //分配任務堆疊棧頂指標

int8u prio, //分配任務優先順序

int16u id, //(未來的)優先順序標識(與優先順序相同)

os_stk *pbos, //分配任務堆疊棧底指標

int32u stk_size, //指定堆疊的容量(檢驗用)

void *pext, //指向使用者附加的資料域的指標

int16u opt) //建立任務設定選項

#endif

os_enter_critical(); //關閉中斷

if (ostcbpriotbl[prio] == (os_tcb *)0)

psp = (os_stk *)ostaskstkinit(task, pdata, ptos, opt); //初始化任務堆疊

err = os_tcbinit(prio, psp, pbos, id, stk_size, pext, opt); //獲得並初始化任務控制塊

if (err == os_no_err)

} else

return (err); //返回(獲得並定義初始化任務控制塊是否成功)

} os_exit_critical(); //開啟中斷

return (os_prio_exist); //具有該優先順序的任務已經存在

} #endif

quartz任務定時任務建立

排程器 任務排程器類 author wwr public class taskscheduler 任務排程 param jobclass 任務類 param job1 任務名 param job1group 任務組別 param trigger1 觸發器名字 param triggergroup 觸...

任務建立和刪除

在freertos移植到cortex m3硬體平台的文章中,我們已經見過任務建立api,但那篇文章的重點在於如何移植freertos,本文將重點放在任務的建立和刪除api函式上面。任務建立和刪除api函式位於檔案task.c中,需要包含task.h標頭檔案。1.1函式描述 objc view pla...

ucos ii動態建立任務

ucos ii 是乙個應用比較廣泛的嵌入式實時系統,核心可剝奪,執行時按照任務優先順序進行核心搶占,從而保證了多工的高實時性。並且可應用於許多嵌入式晶元中,比如51微控制器,arm,以及飛思卡爾power 架構的mpc系列晶元等等。大家都知道 ostaskcreate void task void ...