在说之前,先说明任务初始化函数OSInit,几个列表的初始化
一:OS_InitRdyList();
初始化就绪列表,任务就绪列表主要用于
抢占式调度器快速的从就绪列表中找出当前就绪的最高优先级
任务。
http://s11/mw690/98ee3a93td806287266ea&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
下面这个图是任务就绪列表的位图查找法,下面这个图是64个任务的位图
查找,现在UCOS-II支持256级任务抢占,方法和下面的类似
64个任务的位图查找
y
= OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y << 3u) +
OSUnMapTbl[OSRdyTbl[y]]);
256个任务的位图查找,下面的if-else语句正好组成4中选择,
一种选择
是一块,一共是4块,每一块是64个任务,计算方法和上面是一样的。
if
((OSRdyGrp & 0xFFu) != 0u) {
y = OSUnMapTbl[OSRdyGrp & 0xFFu];
} else
{
y = OSUnMapTbl[(OS_PRIO)(OSRdyGrp >>
8u) & 0xFFu] + 8u;
}
ptbl = &OSRdyTbl[y];
if ((*ptbl
& 0xFFu) != 0u) {
OSPrioHighRdy = (INT8U)((y << 4u) +
OSUnMapTbl[(*ptbl & 0xFFu)]);
} else
{
OSPrioHighRdy = (INT8U)((y << 4u) +
OSUnMapTbl[(OS_PRIO)(*ptbl
>>
8u) & 0xFFu] +
8u);
}
http://s8/mw690/98ee3a93td806396f3487&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
二:OS_InitTCBList
初始化任务控制块列表,初始化以后如下图所示
http://s8/mw690/98ee3a93td80656ae7fc7&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
(1)初始化的TCB空闲列表是单向的,而开始使用的列表都做成双向的,
主要是方便添加信任和删除任务,而且 滴答中断函数,在遍历查
的时候也很方便,
(2)加入OSTCBPrioTbl[prio] =
ptcb;也有很多的好处,主要是可快
速的执向需要执行的任务下图是加入任务以后的TCB表
http://s14/mw690/98ee3a93td806697c240d&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
三:OS_InitEventList
初始化事件控制块列表,事件控制块主要包括
#define
OS_EVENT_TYPE_UNUSED
0u
#define
OS_EVENT_TYPE_MBOX
1u
#define
OS_EVENT_TYPE_Q
2u
#define
OS_EVENT_TYPE_SEM
3u
#define
OS_EVENT_TYPE_MUTEX
4u
#define
OS_EVENT_TYPE_FLAG
5u
#define
OS_TMR_TYPE
100u
typedef struct
os_event {
INT8U
OSEventType;
void
*OSEventPtr;
INT16U
OSEventCnt;
OS_PRIO
OSEventGrp;
OS_PRIO
OSEventTbl[OS_EVENT_TBL_SIZE];
#if OS_EVENT_NAME_EN > 0u
INT8U *OSEventName;
#endif
} OS_EVENT;
http://s16/mw690/98ee3a93td80677b25f4f&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
四:OS_FlagInit(); 初始化事件标志组列表
typedef struct
os_flag_grp
{
INT8U
OSFlagType;
void
*OSFlagWaitList;
OS_FLAGS
OSFlagFlags;
#if OS_FLAG_NAME_EN > 0u
INT8U
*OSFlagName;
#endif
} OS_FLAG_GRP;
typedef struct
os_flag_node
{
void
*OSFlagNodeNext;
void
*OSFlagNodePrev;
void
*OSFlagNodeTCB;
void
*OSFlagNodeFlagGrp;
OS_FLAGS
OSFlagNodeFlags;
INT8U
OSFlagNodeWaitType;
} OS_FLAG_NODE;
五:
OS_MemInit(); 初始化内存管理
typedef struct
os_mem
{
void
*OSMemAddr;
void
*OSMemFreeList;
INT32U
OSMemBlkSize;
INT32U
OSMemNBlks;
INT32U
OSMemNFree;
#if OS_MEM_NAME_EN > 0u
INT8U
*OSMemName;
#endif
} OS_MEM;
http://s14/mw690/98ee3a93td8068a8871ed&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
六:OS_QInit();
初始化消息队列
typedef struct os_q
{
struct
os_q
*OSQPtr;
void
**OSQStart;
void
**OSQEnd;
void
**OSQIn;
void
**OSQOut;
INT16U
OSQSize;
INT16U
OSQEntries;
} OS_Q;
http://s14/mw690/98ee3a93td8069144ae8d&690任务的创建,挂起,恢复,删除" TITLE="第三篇:uCOS-II 任务的创建,挂起,恢复,删除" />
列表初始化之前和之后的结果
http://s16/middle/98ee3a934b937c37c6e9f&690
http://s16/middle/98ee3a934b937c5126fef&690
1.任务的建立函数
OSTaskCreate(
Task1,
(void
*)0,
&Task1Stk[1023],
25);
OSTaskCreateExt(AppTaskStart,
(void
*)0,
(OS_STK
*)&AppTaskStartStk[APP_TASK_START_STK_SIZE -
1],
APP_TASK_START_PRIO,
APP_TASK_START_PRIO,
(OS_STK
*)&AppTaskStartStk[0],
APP_TASK_START_STK_SIZE,
(void
*)0,
OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR);
OS_TASK_OPT_STK_CHK
使能检测任务栈,统计任务栈已用的和未用的
OS_TASK_OPT_STK_CLR
在创建任务时,清零任务栈
OS_TASK_OPT_SAVE_FP
如果CPU有浮点寄存器,则在任务切换时保存浮点寄存器的内容
2.任务的挂起。
OSTaskSuspend(16);
//挂起自己是OS_PRIO_SELF;
任务的挂起函数应用很简单的,直接指定优先级号就可以了,如果挂起的是任务本身的话可以指定本任务的优先级,也可以用OS_PRIO_SELF或本任务的优先级。如果任务被
挂起的时候,这个任务真正执行延时的话,那么任务恢复的时候,将继续的执行延时。
http://s4/middle/98ee3a934b937c696c463&690
http://s10/middle/98ee3a934b937cef1ae59&690
3.任务的恢复
OSTaskResume(16);
//只能在其它的任务里面调用此函数来恢复
http://s16/middle/98ee3a934b937d0bbe84f&690
4.任务的删除
一般的情况下我们不会的直接调用OSTaskDel,这样的调用是不安全的,这个函数里面可以填要删除的任务的优先级,如果是任务本身的话,还可以填OS_PRIO_SELF。
下面提供一个标准的删除范例:这样的好处就在于别的任务请求删除这个任务,这个任务可以接受到请求后再删除自己,不会出事自己的信号量之类的东西还没有释放就被删除了。
http://s16/middle/98ee3a934b937d153f6cf&690
http://s2/middle/98ee3a934b937d1dd6c51&690
5.调度器的枷锁和解锁
OSSchedLock();
//必须的成对的来使用 禁止任务的调度,但是可以执行中断
OSSchedUnlock();
//否则会在枷锁的任务里面无限的执行
下面的是一个典型的调用范例
http://s7/middle/98ee3a934b937d2916476&690
6.任务优先级的修改
OSTaskChangePrio(
16,
2
);
加载中,请稍候......