一、UCOSIII任務堆棧
1、任務堆棧的創建
堆棧是在RAM中按照“先進先出(FIFO)”的原則組織的一塊連續的存儲空間。為了滿足任務切換和響應中斷時保存CPU寄存器中的內容及任務調用其它函數時的需要,每個任務都應該有自己的堆棧。
如何創建?
#define START_STK_SIZE 512 //堆棧大小
CPU_STK START_TASK_STK[START_STK_SIZE]; //定義一個數組來作為任務堆棧
可查看main.c的29行,跳轉可知堆棧大小:
CPU_STK為CPU_INT32U類型,也就是unsigned int類型,為4字節的,那么任務堆棧START_TASK_STK的大小就為:512 X 4=2048字節!
2、任務堆棧的初始化
任務如何才能切換回上一個任務并且還能接著從上次被中斷的地方開始運行?
恢復現場即可,現場就是CPU的內部各個寄存器。因此在創建一個新任務時,必須把系統啟動這個任務時所需的CPU各個寄存器初始值事先存放在任務堆棧中。這樣當任務獲得CPU使用權時,就把任務堆棧的內容復制到CPU的各個寄存器,從而可以任務順利地啟動并運行。
把任務初始數據存放到任務堆棧的工作就叫做任務堆棧的初始化,UCOSIII提供了完成堆棧初始化的函數:OSTaskStkInit():
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task,
void *p_arg,
CPU_STK *p_stk_base,
CPU_STK *p_stk_limit,
CPU_STK_SIZE stk_size,
OS_OPT opt)
用戶一般不會直接操作堆棧初始化函數,任務堆棧初始化函數由任務創建函數OSTaskCreate()調用。不同的CPU對于的寄存器和對堆棧的操作方式不同,因此在移植UCOSIII的時候需要用戶根據各自所選的CPU來編寫任務堆棧初始化函數。
可查看UCOSIII_PORT中的os_cpu_c.c中227行
3、如何使用創建的任務堆棧?
作為任務創建函數OSTaskCreate()的參數,函數OSTaskCreate()如下:
void OSTaskCreate (OS_TCB *p_tcb, //任務控制塊
CPU_CHAR *p_name, //任務名字
OS_TASK_PTR p_task, //任務函數
void *p_arg, //傳遞給任務函數的參數
OS_PRIO prio, //任務優先級
CPU_STK *p_stk_base, //任務堆棧基地址 一般0
CPU_STK_SIZE stk_limit, //任務堆棧棧深 一般堆棧大小/10
CPU_STK_SIZE stk_size, //任務堆棧大小 前面創建的
OS_MSG_QTY q_size,
OS_TICK time_quanta,
void *p_ext, //用戶補充的存儲區
OS_OPT opt,
OS_ERR *p_err) //存放該函數錯誤時的返回值
可查看main.c中79行的任務開始函數
4、堆棧增長方式
函數OSTaskCreate()中的參數p_stk_base如何確定?
根據堆棧的增長方式,堆棧有兩種增長方式:
向上增長:堆棧的增長方向從低地址向高地址增長。
向下增長:堆棧的增長方向從高地址向低地址增長。
函數OSTaskCreate()中的參數p_stk_base是任務堆棧基地址,那么如果CPU的堆棧是向上增長的話那么基地址就&START_TASK_STK[0],如果CPU堆棧是向下增長的話基地址就是&START_TASK_STK[START_STK_SIZE-1]STM32的堆棧是向下增長的!
二、UCOSIII任務控制塊
1、任務控制塊結構
任務控制塊是用來記錄與任務相關的信息的數據結構,每個任務都要有自己的任務控制塊。任務控制塊由用戶自行創建,如下代碼為創建一個任務控制塊:
OS_TCB StartTaskTCB; //創建一個任務控制塊
OS_TCB為一個結構體,描述了任務控制塊,任務控制塊中的成員變量用戶不能直接訪問,更不可能改變他們。
OS_TCB為一個結構體,其中有些成員采用了條件編譯的方式來確定
struct os_tcb
{
CPU_STK *StkPtr; //指向當前任務堆棧棧頂
void *ExtPtr; //指向用戶可定義的數據取
CPU_STK *StkLimitPtr;//可指向任務堆棧中的某個位置
OS_TCB *NextPtr; //NexPtr和PrevPtr用于在任務就緒表建立OS_TCB
OS_TCB *Prev
…… //此處省略N個成員變量
#if OS_CFG_DBG_EN > 0u
OS_TCB *DbgPrevPtr;//下面三個成員變量用于調試
OS_TCB *DbgNextPtr;
CPU_CHAR *DbgNamePtr;
#endif
}
可查看main.c中26行進行跳轉,里面有很多的成員變量
2、任務控制塊初始化
函數OSTaskCreate()在創建任務的時候會對任務的任務控制塊進行初始化。
函數OS_TaskInitTCB()用與初始化任務控制塊。用戶不需要自行初始化任務控制塊。
可查看os_task.c中341行
三、UCOSIII任務就緒表
1、優先級:
UCOSIII中任務優先級數由宏OS_CFG_PRIO_MAX來配置,UCOSIII中數值越小,優先級越高,最低可用優先級就是OS_CFG_PRIO_MAX-1。
可查看UCOSIII_CONFIG中os_cfg.c中47行
2、就緒表
UCOSIII中就緒表由2部分組成:
1、優先級位映射表OSPrioTbl[]:用來記錄哪個優先級下有任務就緒。
2、就緒任務列表OSRdyList[]:用來記錄每一個優先級下所有就緒的任務。
OSPrioTbl[]在os_prio.c中有定義:
CPU_DATA OSPrioTbl[OS_PRIO_TBL_SIZE]; //UCOSIII_CORE中os_prio.c中41行
跳轉可知:
在STM32中CPU_DATA為unsigned int,有4個字節,32位。因此表OSPrioTbl每個參數有32位,其中每個位對應一個優先級。
OS_PRIO_TBL_SIZE=((OS_CFG_PRIO_MAX - 1u) / DEF_INT_CPU_NBR_BITS)+ 1)
其中OS_CFG_PRIO_MAX由用戶自行定義,默認為64。
DEF_INT_CPU_NBR_BITS= CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS
CPU_CFG_DATA_SIZE=CPU_WORD_SIZE_32=4。
DEF_OCTET_NBR_BITS=8。
所以,當系統有64個優先級的時候:
OS_PRIO_TBL_SIZE=((64-1)/(4*8)+1)=2。
2.1、如何找到已經就緒了的最高優先級的任務?
函數OS_PrioGetHighest()用于找到就緒了的最高優先級的任務:源碼在UCOSIII_CORE中os_prio.c中85行
OS_PRIO OS_PrioGetHighest (void)
{
CPU_DATA *p_tbl;
OS_PRIO prio;
prio = (OS_PRIO)0;
p_tbl = &OSPrioTbl[0];//從OSProTb[0]開始掃描映射表,一直遇到非零項
while (*p_tbl == (CPU_DATA)0) {
//當數組OSProTb[]中某個元素為0時,就繼續掃描下一個素組元素,prio加DEF_INT_CPU_NBR_BITS位
prio += DEF_INT_CPU_NBR_BITS;
p_tbl++;// p_tbl加一,繼續尋找OSProTb[]中下一個元素
}
//一旦找到一個非0項,再加上該項的前導0數量就找到了最高優先級任務了
prio += (OS_PRIO)CPU_CntLeadZeros(*p_tbl); //計算前導0:計算0的個數
return (prio);
2.2就緒任務列表
通過上一步我們已經知道了哪個優先級的任務已經就緒了,但是UCOSIII支持時間片輪轉調度,同一個優先級下可以有多個任務,因此我們還需要在確定是優先級下的哪個任務就緒了
struct os_rdy_list {
OS_TCB *HeadPtr //用于創建鏈表,指向鏈表頭
OS_TCB *TailPtr; //用于創建鏈表,指向鏈表尾
OS_OBJ_QTY NbrEntries; //此優先級下的任務數量
}; //全局變量查找:在os.h中1184行
同一優先級下如果有多個任務的話,最先運行的永遠是HeadPtr所指向的任務!達到左右任務輪詢執行。
UCOSIII內部使用的幾個函數:
上一篇:UCOSIII系統初始化和啟動
下一篇:UCOSIII任務管理中的幾個關鍵名詞解釋(任務及任務狀態)
推薦閱讀
史海拾趣
進入20世紀90年代,電子行業的技術革新日新月異。Connor-Winfield敏銳地捕捉到了市場的變化,開始將產品線擴展到其他領域,以滿足更多客戶的需求。除了石英計時電路和振蕩器,公司還開始研發和生產一系列與電子應用緊密相關的產品。這些新產品的推出,不僅進一步鞏固了公司在行業內的地位,也為其開拓了更廣闊的市場空間。
面對不斷變化的市場環境和客戶需求,Euroquartz始終保持敏銳的洞察力和快速的反應能力。公司不斷投入研發力量,推動產品創新和技術升級。同時,Euroquartz也注重與客戶的溝通和合作,深入了解市場需求,為客戶提供更加專業和貼心的服務。這種持續發展的動力,使Euroquartz在電子行業始終保持領先地位,并為公司的未來發展奠定了堅實的基礎。
請注意,由于篇幅限制,以上每個故事都是基于Euroquartz公司的重要事件和事實進行概括和簡化的。如果需要更詳細的信息或更深入的分析,建議查閱相關報道或公司官方資料。
隨著公司的發展,Coherent Inc.開始通過收購和整合來增強自身實力。1998年,公司以6500億美金收購了Palomar Medical Technologies的部分業務,這一舉措進一步拓寬了公司的業務范圍和技術領域。此外,公司還陸續收購了多家具有技術優勢的公司,如Positive Light和Lambda Physik,這些收購不僅增強了公司的技術實力,也使其在激光技術領域的地位更加穩固。
盡管電子行業競爭激烈,市場變化莫測,但Coherent Inc.始終保持著堅定的前行步伐。公司不斷適應市場變化,調整戰略方向,積極應對各種挑戰。同時,公司也注重與合作伙伴的緊密合作,共同推動激光技術的創新和應用。這種堅定前行的態度,使得Coherent Inc.在電子行業中始終保持著領先的地位。
這五個故事只是Coherent Inc.發展歷程中的一部分,但它們足以展示公司在電子行業中的崛起和發展。通過不斷的探索、創新、收購與整合,以及堅定的前行態度,Coherent Inc.已經成為了激光技術領域的佼佼者,為電子行業的發展做出了重要貢獻。
盡管電子行業競爭激烈,市場變化莫測,但Coherent Inc.始終保持著堅定的前行步伐。公司不斷適應市場變化,調整戰略方向,積極應對各種挑戰。同時,公司也注重與合作伙伴的緊密合作,共同推動激光技術的創新和應用。這種堅定前行的態度,使得Coherent Inc.在電子行業中始終保持著領先的地位。
這五個故事只是Coherent Inc.發展歷程中的一部分,但它們足以展示公司在電子行業中的崛起和發展。通過不斷的探索、創新、收購與整合,以及堅定的前行態度,Coherent Inc.已經成為了激光技術領域的佼佼者,為電子行業的發展做出了重要貢獻。
uClinux在ARM開發板44b0芯片上運行程序,提示中斷異常錯誤? 請教高人,在44B0的ARM開發板上uClinux操作系統下,調試ADC與LCD應用程序。 兩個程序分別運行的時候,都正常。但是把ADC與LCD應用程序都加入到一個文件work中,編譯后運行,就提示如下問題: Unhandled fault: alignment exception ...… 查看全部問答∨ |
|
大家好,剛剛接觸WINCE,什么都不懂,現請教幾個問題: 我使用一個軟件(西門子WinCC flexible)來開發監控程序,然后下載到觸摸屏(MP370)上。下載程序的功能是WinCC flexible自身提供的。 在觸摸屏上運行的是windows se 3.1英文系統。觸摸屏提供了RS2 ...… 查看全部問答∨ |
|
void TIM_Configuration(void)//TIM初始化函數{ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定時器初始化結構 TIM_OCInitTypeDef TIM_OCInitStructure;//通道輸出初始化結構 //TIM3初始化 TIM_DeInit(TIM2) ...… 查看全部問答∨ |
(轉自深度技術)讓Ubuntu也能運行Windows程序-Wine的安裝與使用 花了這么多心血才搞好的,我覺得此貼已經具備了置頂的素質,望版主把此貼置頂,讓更多的人能來學習Linux,用好Linux。轉載請注明出處。 安好了ubuntu,擺弄了幾天,基本上手了,已經愛上了Linux,但因為用Windows這么長時間了 ...… 查看全部問答∨ |
設計資源 培訓 開發板 精華推薦
- 高通攜手中國“汽車朋友圈”亮相2025上海車展: 加速駕駛輔助普惠,推動艙駕創新升級
- 工業市場正在快速回暖,德州儀器如何重塑電力電子市場?
- 特斯拉:美國交付的Model Y/3電池包已實現100%美國生產
- 地平線與博世深化合作,攜手為多家車企提供輔助駕駛產品
- 強化中國市場戰略布局,德州儀器正靈活應對全球關稅挑戰
- Molex莫仕通過本地合作和創新加強支持中國汽車行業
- 貿澤開售Texas Instruments適用于高分辨率AR HUD的 全新DLP4620S-Q1 0.46"汽車數字微鏡器件
- ROHM推出高功率密度的新型SiC模塊,將實現車載充電器小型化!
- 用上車規級UFS 4.0,讓出行變得高效且可靠
- 車載測試技術解析:聚焦高帶寬、多通道同步采集與協議分析