日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 單片機 > 單片機
[導讀]直接開始說明ucos創(chuàng)建任務時的步驟:1, 初始化任務堆棧2, 初始化任務控制塊3, 把剛創(chuàng)建的任務設置為就緒態(tài)(即置位就緒表)上面提到的任務堆棧,控制塊,就緒表我們前面已經說過了,下面就直接看代碼。INT8U OSTa

直接開始說明ucos創(chuàng)建任務時的步驟:

1, 初始化任務堆棧

2, 初始化任務控制塊

3, 把剛創(chuàng)建的任務設置為就緒態(tài)(即置位就緒表)

上面提到的任務堆棧,控制塊,就緒表我們前面已經說過了,下面就直接看代碼。

INT8U OSTaskCreate (void (*task)(void *pd), void *p_arg, OS_STK *ptos, INT8U prio)

{

OS_STK *psp;

INT8U err;

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */

OS_CPU_SR cpu_sr;

cpu_sr = 0; /* Prevent compiler warning */

#endif

#if OS_ARG_CHK_EN > 0

if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */

return (OS_PRIO_INVALID);

}

#endif

OS_ENTER_CRITICAL(); //關閉中斷

if (OSIntNesting > 0) { /* Make sure we don't create the task from within an ISR */

OS_EXIT_CRITICAL();

return (OS_ERR_TASK_CREATE_ISR);

}

if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */

OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */

/* ... the same thing until task is created. */

OS_EXIT_CRITICAL();

psp = (OS_STK *)OSTaskStkInit(task, p_arg, ptos, 0); /* Initialize the task's stack *///初始化任務的堆棧

err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);

if (err == OS_NO_ERR) {

if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */

OS_Sched(); //如果創(chuàng)建任務時ucos已經開始任務調度,那么創(chuàng)建完任務后需要進行任務調度

}

} else {

OS_ENTER_CRITICAL();

OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */

OS_EXIT_CRITICAL();

}

return (err);

}

OS_EXIT_CRITICAL();

return (OS_PRIO_EXIST);

}

下面是初始化堆棧的函數:

OS_STK * OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)

{//函數需要4個參數,一個指向任務函數的指針,任務運行時需要的參數,堆棧指針,擴展參數

unsigned int * stk;

stk = (unsigned int *)ptos; /* Load stack pointer */

//USE_ARG(opt);

opt++;

/* build a stack for the new task */

*--stk = (unsigned int) task; /* pc */

*--stk = (unsigned int) task; /* lr */

*--stk = 12; /* r12 */

*--stk = 11; /* r11 */

*--stk = 10; /* r10 */

*--stk = 9; /* r9 */

*--stk = 8; /* r8 */

*--stk = 7; /* r7 */

*--stk = 6; /* r6 */

*--stk = 5; /* r5 */

*--stk = 4; /* r4 */

*--stk = 3; /* r3 */

*--stk = 2; /* r2 */

*--stk = 1; /* r1 */

*--stk = (unsigned int) pdata; /* r0 */

*--stk = (SUPMODE); /* cpsr */

*--stk = (SUPMODE); /* spsr */

return ((OS_STK *)stk);

}

關于堆棧,我們前面已經講過,這里用的即遞減的滿堆棧。

對于任務,其實就是一個無限循環(huán)的函數,那怎么控制它的運行那,這就是操作系統(tǒng)要干的活,操作系統(tǒng)根據調度算法實現對任務的調度以及任務的切換。實現了多個任務共享cpu。

我們已經知道,堆棧對任務的重要性,一:c語言執(zhí)行需要堆??臻g。二:當發(fā)生任務切換時需要把程序運行的現場保存到任務的堆棧中。

也就是說,任務堆棧中應該保存的是任務運行時函數調用的情況以及被打斷時的狀態(tài)信息,可是問題來了,我們剛創(chuàng)建一個任務時,這個任務并沒有運行過呀。這個好辦,我們就模擬這個任務被打斷過的跡象,任務沒執(zhí)行過,那么這個函數調用棧幀就不復存在。我們只模擬函數運行環(huán)境的保存。看上面代碼,我們首先保存的是PC和LR,因為任務函數還沒有執(zhí)行過,因此這個PC和LR就應該是函數的首地址,也就是函數的名稱指針。比如說你定義了一個任務函數

void Task1(void *Id)

{

for(;;){

printf("run task1n");

OSTimeDly(1000);

}

}

那就把Task1這個函數指針賦給PC和LR。接著是R1~R12這些通用寄存器,由于函數還沒有執(zhí)行過,這些通用寄存器的值是什么就不太重要,可以隨便賦值,你看,這里就是給R1賦值1,給R2賦值2 ………… 給R12賦值12。當然你也可以給這些寄存器賦其他值,這些無關緊要,但當任務運行過后,那再保存程序執(zhí)行現場時就要按章程來了,即這些寄存器被切換的時候里面的值是什么就應該保存什么。下面就要初始化CPSR和SPSR了,這兩個值要根據你的操作系統(tǒng)要運行在處理器的那種模式下,任務運行時應該開中斷的。你像我們這個把CPSR的值賦成SUPMODE(這個宏的值是0x13),就是說這個任務運行時在SVC模式下并且開中斷。咱們原來說過ucos初始化過程CPSR的中斷一直是關著的,CPSR的中斷位就是當最高優(yōu)先級任務運行時就已經開中斷了。

一句話說那,現

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯系該專欄作者,如若文章內容侵犯您的權益,請及時聯系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀
關閉