大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
函数原型来自OS_TASK.C
/**********************************************************************************************************
* CREATE A TASK
**********************************************************************************************************/
//uC/OS-II是通过任务控制块来管理任务的,因此创建任务的工作实质上是给任务的代码分配一个任务控制块,并通过任务控制块把任务代码和任务堆栈关联起来形成一个完整的任务.当然还要使刚创建的任务进入就绪状态,并接着引发一次任务调度.
//uC/OS-II有两个用来创建任务的函数:OSTaskCreate()和OSTaskCreateExt().
//其中函数OSTaskCreateExt()是OSTaskCreate()的扩展,并提供一些附加功能.
//用户可根据需要使用这两个函数之一来完成任务的创建工作.
//OSTaskCreate ()函数主要完成3项工作:任务堆栈的初始化,任务控制块的初始化和任务调度.任务代码的指针并不是存放在任务控制块中的,而是存放在任务堆栈里面.
//一般来说,任务可在调用函数OSStart()启动任务调度之前来创建,也可在任务中来创建.但是,uC/OS-II有一个规定:在调用启动任务函数OSStart()之前,必须已经创建了最少一个任务.因此,习惯上在调用函数OSStart()之前先创建一个任务,并赋予它最高的优先级别,从而使它成为起始任务,然后在这个起始任务中,再创建其他各任务.
#if OS_TASK_CREATE_EN > 0 //OS_CFG配置文件.配置一些常数,编译时根据这些常数决定某代码段是否编译
//task是任务代码指针,pdata是传递给任务的参数的指针,ptos是分配给任务的堆栈栈顶指针,prio是分配给任务的优先级
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_STK *psp;
INT8U err;
#if OS_ARG_CHK_EN > 0 //OS_CFG配置文件.配置一些常数,编译时根据这些常数决定某代码段是否编译
//检测分配给任务的优先级是否有效,任务的优先级必须在0到OS_LOWEST_PRIO之间
if (prio > OS_LOWEST_PRIO) { /* Make sure priority is within allowable range */
return (OS_PRIO_INVALID);//uCOS_II.h→ERROR CODES
}
#endif
OS_ENTER_CRITICAL();//代码临界段,不允许中断
//确保在规定的优先级上还没有建立任务-uCOS_II.h→GLOBAL VARIABLES→OS_TCB *OSTCBPrioTbl[OS_LOWEST_PRIO + 1]
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn’t already exist at this priority */
//通过放置一个非空指针在OSTCBPrioTbl[]中来保留该优先级
//如果规定的优先级为空,即还没有被用于任务,那么就可以用该优先级,设为(OS_TCB *)1
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing … */
/* … the same thing until task is created. */
OS_EXIT_CRITICAL();//设置任务数据结构的其他部分时重新允许中断
//建立任务的堆栈,OSTaskStkInit()函数返回新的堆栈栈顶(psp),并保存在任务的0S_TCB中
//任务堆栈初始化就是对栈顶指针和寄存器进行初始化,OSTaskStkInit()函数的定义在OS_CPU_C.C文件中.
psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task’s stack */
//调用OS_CORE.c→OSTCBInit(),从空闲的OS_TCB池中获得并初始化一个OS_TCB
err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);
//返回一个代码表明OS_TCB已经被分配和初始化
if (err == OS_NO_ERR) {//uCOS_II.h→ERROR CODES
OS_ENTER_CRITICAL();//代码临界段,不允许中断
//如果OSTCBInit()返回成功,就增加OSTaskCtr(用于保存产生的任务数目)
OSTaskCtr++;/* Increment the #tasks counter */
//OSTaskCreateHook(OSTCBPrioTbl[prio]);//用户自己定义的函数,用来扩展OSTaskCreate()的功能
OS_EXIT_CRITICAL();//退出临界段 (开中断)
//如果OSTaskCreate()函数是在某个任务的执行过程中被调用(即OSRunning置为True)
if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */
OS_Sched();//调用任务调度函数以判断是否新建立的任务比原来的任务有更高的优先级
}
}
else {
OS_ENTER_CRITICAL();//代码临界段,不允许中断
//如果OSTCBInit()返回失败,就置OSTCBPrioTbl[prio]的入口为0,以放弃该任务的优先级
OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
OS_EXIT_CRITICAL();//退出临界段 (开中断)
}
return (err);
}
OS_EXIT_CRITICAL();//退出临界段 (开中断)
return (OS_PRIO_EXIST);//uCOS_II.h→ERROR CODES
}
#endif
函数原型来自OS_CORE.C
//任务控制块初始化函数
INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
//OSInit()→OS_InitTCBList();/* 初始化任务控制块 */→OSTCBFreeList
//获得空闲任务控制块列表头指针
ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */
//如果缓冲池有空余TCB,这个TCB被初始化
if (ptcb != (OS_TCB *)0) {
//将控制块列表头交给新建任务,OSTCBFreeList指向该任务的下一个控制块
//OSTCBFreeList指向TCB的双向链接的后链接
OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
OS_EXIT_CRITICAL();
//初始化控制块各个参数
//指向当前TCB的栈顶指针
ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
//保存当前TCB的优先级别
ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
//设定当前TCB的状态字
ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
//设定当前TCB的延时时间-允许任务等待的最大字节节拍为0
ptcb->OSTCBDly = 0; /* Task is not delayed */
#if OS_TASK_CREATE_EXT_EN > 0
//指向用户定义的任务控制块(扩展指针)
ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */
//设定堆栈的容量
ptcb->OSTCBStkSize = stk_size; /* Store stack size */
//指向堆栈栈底的指针
ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */
//保存OS_TCB的选择项
ptcb->OSTCBOpt = opt; /* Store task options */
//保存任务标志符
ptcb->OSTCBId = id; /* Store task ID */
#else
//扩展指针
pext = pext; /* Prevent compiler warning if not used */
//堆栈的容量
stk_size = stk_size;
//栈底的指针
pbos = pbos;
//选择项
opt = opt;
//任务标志符
id = id;
#endif
#if OS_TASK_DEL_EN > 0
//定义表示该任务是否删除
ptcb->OSTCBDelReq = OS_NO_ERR;
#endif
//优先级所在行
ptcb->OSTCBY = prio >> 3; /* Pre-compute X, Y, BitX and BitY */
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
//优先级所在列
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
#if OS_EVENT_EN > 0
ptcb->OSTCBEventPtr = (OS_EVENT *)0; /* Task is not pending on an event */
#endif
//针对的事件为信号量,互斥型信号量,消息邮箱,消息队列,当满足版本大于2.51且事件标志允许且有最大事件标志及允许删除任务
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0) && (OS_TASK_DEL_EN > 0)
//指向事件标志节点的指针被初始化为空指针
ptcb->OSTCBFlagNode = (OS_FLAG_NODE *)0; /* Task is not pending on an event flag */
#endif
#if (OS_MBOX_EN > 0) || ((OS_Q_EN > 0) && (OS_MAX_QS > 0))
//满足以上条件,指向传递给任务的消息指针初始化为0空指针
ptcb->OSTCBMsg = (void *)0; /* No message received */
#endif
#if OS_VERSION >= 204
OSTCBInitHook(ptcb);
#endif
OSTaskCreateHook(ptcb); /* Call user defined hook */
OS_ENTER_CRITICAL();
//prio优先级匹配对应的任务控制块指针
OSTCBPrioTbl[prio] = ptcb;
//链接到任务控制块链接串
ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */
ptcb->OSTCBPrev = (OS_TCB *)0;
//由此看出,任务总是不停的向前添加
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;//当前新创建的任务控制块指针
}
OSTCBList = ptcb;//OSTCBList指针更新
//这里用了’|’或运算.
//因为任务可能不止一个,但是基于任务的数量,行号只会在0-7之间
//eg:prio=12,那么该任务处在行号1,对应OSMapTab[1]=0000 0010
//eg:prio=23,那么该任务处在行号2,对应OSMapTab[2]=0000 0100
//那么OSRdyGrp=0000 0010|0000 0100=0000 0110
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
//同理
//eg:prio=12,那么该任务处在列号4,对应OSMapTab[1]=0001 0000
//eg:prio=23,那么该任务处在列号7,对应OSMapTab[2]=1000 0000
//因为不同的行拥有同样的列号0-7,所以采用OSRdyTbl[OSRdyGrp],进行或运算的必然属于同行
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
//调用成功,最后让此函数返回到调用函数[OSTaskCreate()或OSTaskCreateExt()函数]
//返回值表示分配到任务控块,并初始化了
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
//没有更多的任务控制块被分配,将无法创建新的任务
return (OS_NO_MORE_TCB);
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196738.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...