1、xilentz 的网络文摘博客园 首页 新随笔 联系 订阅 管理 随笔 - 204 文章 - 0 评论 - 10 trackbacks - 0 OS_TASK.C/* uC/OS-II* The Real-Time Kernel* TASK MANAGEMENT* (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL* All Rights Reserved* File : OS_TASK.C* By : Jean J. Labrosse*/ #ifndef OS_MASTER_FILE#include “includes.h“#endif
2、 /* CHANGE PRIORITY OF A TASK* Description: This function allows you to change the priority of a task dynamically. Note that the new* priority MUST be available.* Arguments : oldp is the old priority* newp is the new priority* Returns : OS_NO_ERR is the call was successful* OS_PRIO_INVALID if the pr
3、iority you specify is higher that the maximum allowed* (i.e. = OS_LOWEST_PRIO)* OS_PRIO_EXIST if the new priority already exist.* OS_PRIO_ERR there is no task with the specified OLD priority (i.e. the OLD task does* not exist.*/*改变任务优先级描述:此函数允许你动态改变一个任务的优先级。但新的优先级必须可行参数:oldp :旧的优先级newp:新的优先级返回:OS_NO
4、_ERR:改变成功OS_PRIO_INVALID:指定的优先级不合法:超过最大值OS_PRIO_EXIST:新优先级已经存在OS_PRIO_ERR:旧优先级任务不存在 */ #if OS_TASK_CHANGE_PRIO_EN 0 /如果 OS_TASK_CHANGE_PRIO_EN 设置为 1,能使包含下面代码INT8U OSTaskChangePrio (INT8U oldprio, INT8U newprio)#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */为 CPU 状态寄存器分配存储器O
5、S_CPU_SR cpu_sr; /OS_CPU_SR 即为 unsigned int #endif #if OS_EVENT_EN 0/OS_EVENT_EN 定义为:(OS_Q_EN 0) #endif OS_TCB *ptcb;INT8U x;INT8U y;INT8U bitx;INT8U bity; #if OS_ARG_CHK_EN 0/允许参数检测if (oldprio = OS_LOWEST_PRIO #endifOS_ENTER_CRITICAL();/如果合法if (OSTCBPrioTblnewprio != (OS_TCB *)0) /* New priority mu
6、st not already exist */OS_EXIT_CRITICAL();return (OS_PRIO_EXIST);/新优先级必须不存在 ,存在就重复了 else OSTCBPrioTblnewprio = (OS_TCB *)1; /* Reserve the entry to prevent others */保留入口,防止其它任务占用此优先级OS_EXIT_CRITICAL();y = newprio 3; /* Precompute to reduce INT. latency */此函数会预先计算新优先级任务的任务控制块中的某些值,使用这些值/可以将任务放入就绪步或者从
7、该表中移除任务 .bity = OSMapTbly;x = newprio bitx = OSMapTblx;OS_ENTER_CRITICAL();if (oldprio = OS_PRIO_SELF) /* See if changing self */如果改变自己oldprio = OSTCBCur-OSTCBPrio; /* Yes, get priority */是的,得到优先级ptcb = OSTCBPrioTbloldprio;/得到该优先级 TCB 指针if (ptcb != (OS_TCB *)0) /* Task to change must exist */优先级存在,如
8、果要改变的是当前任务,由一定会成功OSTCBPrioTbloldprio = (OS_TCB *)0; /* Remove TCB from old priority */通过放入空闲指针,将指向当前任务的 TCB 指针从优先级列表中删除 ,/使当前旧的优先级空闲 ,可以被其它任务占用.if (OSRdyTblptcb-OSTCBY /不能让它就绪,OSRdyGrp |= bity; /* Make new priority ready to run */OSRdyTbly |= bitx;/从就绪表中移除,然后在新优先级下,将任务插入就绪表,/注意:OSTaskChangePrio 是利用预
9、先计算的值(见前面) 将任务插入就绪表中的.#if OS_EVENT_EN 0/#define OS_EVENT_EN (OS_Q_EN 0) if (pevent != (OS_EVENT *)0) /* Remove from event wait list */如果任务没有就绪 ,那么可能在等一个信号量,一个互斥型信号量,一个邮箱,队列/等,如果 OSTCBEventPtr 非空,那么此函数会知道任务正在等以上的某件事 .if (pevent-OSEventTblptcb-OSTCBY pevent-OSEventGrp |= bity; /* Add new priority to w
10、ait list */如果任务正在等某事件发生,OSTCBEventPtr 必须将任务从事件控制块的等待队列 (旧/的优先级下 )中移除,并在新的优先级下将事件插入到等待队列中.任务也可能正/在等待延时时间到 ,或被挂起,上面几行可以省略pevent-OSEventTbly |= bitx;#endifOSTCBPrioTblnewprio = ptcb; /* Place pointer to TCB new priority */将指向任务的 OS-TCB 的指针存到 OSTCBPrioTbl中.ptcb-OSTCBPrio = newprio; /* Set new task prior
11、ity */新的优先级保存在 OSTCB 中,预先值也保存在 OSTCB 中.ptcb-OSTCBY = y;ptcb-OSTCBX = x;ptcb-OSTCBBitY = bity;ptcb-OSTCBBitX = bitx;OS_EXIT_CRITICAL();OS_Sched(); /* Run highest priority task ready */任务调度,运行最高优先级任务,在新的优先级高于旧的优先有或者新的优先级高于调/用此函数任务优先级的时候,此函数会被调用return (OS_NO_ERR); else OSTCBPrioTblnewprio = (OS_TCB *)0
12、; /* Release the reserved prio. */如果任务不存在,释放新优先级的 TCBOS_EXIT_CRITICAL();return (OS_PRIO_ERR); /* Task to change didnt exist */返回#endif/*$PAGE*/ /* CREATE A TASK* Description: This function is used to have uC/OS-II manage the execution of a task. Tasks can either* be created prior to the start of mul
13、titasking or by a running task. A task cannot be* created by an ISR.* Arguments : task is a pointer to the tasks code* pdata is a pointer to an optional data area which can be used to pass parameters to* the task when the task first executes. Where the task is concerned it thinks* it was invoked and
14、 passed the argument pdata as follows:* void Task (void *pdata)* * for (;) * Task code;* * * ptos is a pointer to the tasks top of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). pstk will thus point to th
15、e highest (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, pstk will point to the* lowest memory location of the stack and the stack will grow with increasing* memory locations.* prio is the tasks priority. A unique priority MUST be assigned to each task and the* lower the number
16、, the higher the priority.* Returns : OS_NO_ERR if the function was successful.* OS_PRIO_EXIT if the task priority already exist* (each task MUST have a unique priority).* OS_PRIO_INVALID if the priority you specify is higher that the maximum allowed* (i.e. = OS_LOWEST_PRIO)*/*建立一个任务描述:这个函数用于 ucosII
17、 处理完成一个任务,它要么在多任务处理之前建立,要么运行任务建立,它不够由中断服务程序建立。参数:task: 指向任务代码的指针。pdata:是一个指向非强制性数据区域的指针,当任务优先运行时传递参数给任务。任务有关部分假想它被唤醒,然后按照以下方式传递 pdata:* void Task (void *pdata)* * for (;) * Task code;* * ptos:指向任务堆栈顶部的指针,如果配置常数 OS_STK_GROWTH 设置为 1的话,堆栈则会由高到低增长(由高地址向低地址存储)。所以“pstk”会指向堆栈存储器位置的最高地址;如果 OS_STK_GROWTH 设置为
18、 0 的话,“pstk”将指向堆栈最低存储器位置,堆栈将按存储器位置递增。prio:是任务的优先级,一个独特的优先级必须指定给每个任务,最小的数对应最高优先级。 返回:OS_NO_ERR :如果函数成功。OS_PRIO_EXIT :如果优先级已经存在。OS_PRIO_INVALID:如果定义优先级的数大于最大值*/ #if OS_TASK_CREATE_EN 0 /能使包含任务创建代码INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio)/上面有说明#if OS_CRITICAL_ME
19、THOD = 3 /* Allocate storage for CPU status register */ 为 CPU 状态寄存器分配存储空间OS_CPU_SR cpu_sr; /CPU 状态字是十六位 OS_CPU_SR 为 unsigned int #endifOS_STK *psp;INT8U err; #if OS_ARG_CHK_EN 0/如果 OS_ARG_CHK_EN 设为 1,OSTaskCreate 会检查分配给任务的优先级是否有效。/系统在执行初始化的时候,已经把最低优先级分配给了空闲任务。/所以不能用最低优先级来创建任务。if (prio OS_LOWEST_PRIO
20、) /* Make sure priority is within allowable range */保证优先级在允许范围内return (OS_PRIO_INVALID);#endifOS_ENTER_CRITICAL(); /进入临界状态if (OSTCBPrioTblprio = (OS_TCB *)0) /* Make sure task doesnt already exist at this priority */保证优先级没有被其它任务占用OSTCBPrioTblprio = (OS_TCB *)1; /* Reserve the priority to prevent oth
21、ers from doing . */* . the same thing until task is created. */放置一个非空指针,表示已经占用OS_EXIT_CRITICAL(); /退出临界状态psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the tasks stack */初始化任务堆栈 ,即建立任务堆栈err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0);/初始化任务控制块,从空闲的 OS_TCB 缓冲池/中获得并初始化
22、一个任务控制块if (err = OS_NO_ERR) /如果初始化没有错OS_ENTER_CRITICAL();/进入临界状态OSTaskCtr+; /* Increment the #tasks counter */任务数量加一OS_EXIT_CRITICAL();/退出临界状态if (OSRunning = TRUE) /* Find highest priority task if multitasking has started */如果多任务开始,寻找最高优先级任务OS_Sched(); else /如果初始化任务控制块有错OS_ENTER_CRITICAL();/进入临界状态OS
23、TCBPrioTblprio = (OS_TCB *)0;/* Make this priority available to others */把这一优先级给其它任务OS_EXIT_CRITICAL();/退出临界状态return (err);/返回错误信息OS_EXIT_CRITICAL();/如果优先级占用,退出临界状态return (OS_PRIO_EXIST);/返回优先级存在#endif/*$PAGE*/ /* CREATE A TASK (Extended Version)* Description: This function is used to have uC/OS-II
24、manage the execution of a task. Tasks can either* be created prior to the start of multitasking or by a running task. A task cannot be* created by an ISR. This function is similar to OSTaskCreate() except that it allows* additional information about a task to be specified.* Arguments : task is a poi
25、nter to the tasks code* pdata is a pointer to an optional data area which can be used to pass parameters to* the task when the task first executes. Where the task is concerned it thinks* it was invoked and passed the argument pdata as follows:* void Task (void *pdata)* * for (;) * Task code;* * * pt
26、os is a pointer to the tasks top of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). pstk will thus point to the highest (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, pstk will point
27、to the* lowest memory location of the stack and the stack will grow with increasing* memory locations. pstk MUST point to a valid free data item.* prio is the tasks priority. A unique priority MUST be assigned to each task and the* lower the number, the higher the priority.* id is the tasks ID (0655
28、35)* pbos is a pointer to the tasks bottom of stack. If the configuration constant* OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e. from high* memory to low memory). pbos will thus point to the LOWEST (valid) memory* location of the stack. If OS_STK_GROWTH is set to 0, pbos wi
29、ll point to the* HIGHEST memory location of the stack and the stack will grow with increasing* memory locations. pbos MUST point to a valid free data item.* stk_size is the size of the stack in number of elements. If OS_STK is set to INT8U,* stk_size corresponds to the number of bytes available. If
30、OS_STK is set to* INT16U, stk_size contains the number of 16-bit entries available. Finally, if* OS_STK is set to INT32U, stk_size contains the number of 32-bit entries* available on the stack.* pext is a pointer to a user supplied memory location which is used as a TCB extension.* For example, this
31、 user memory can hold the contents of floating-point registers* during a context switch, the time each task takes to execute, the number of times* the task has been switched-in, etc.* opt contains additional information (or options) about the behavior of the task. The* LOWER 8-bits are reserved by u
32、C/OS-II while the upper 8 bits can be application* specific. See OS_TASK_OPT_? in uCOS-II.H.* Returns : OS_NO_ERR if the function was successful.* OS_PRIO_EXIT if the task priority already exist* (each task MUST have a unique priority).* OS_PRIO_INVALID if the priority you specify is higher that the
33、 maximum allowed* (i.e. OS_LOWEST_PRIO)*/*建立一个任务的扩展版函数描述:这个函数用于 ucosII 处理完成一个任务,它要么在多任务处理之前建立,要么运行任务建立,它不够由中断服务程序建立。它与 OSTaskCreate()功能相似,但它允许一个特殊任务的更多信息。参数:task: 指向任务代码的指针pdata:任务开始执行时,传递给任务参数的指针,用法见上。ptos:分配给任务堆栈的栈顶指针prio:分配给任务的优先级id:为任务创建一个特殊标志符,扩展版本有用。在这里设为和优先级一样即可。pbos:指向任务堆栈栈底指针,用于堆栈检验stk_size
34、:用于指定堆栈容量。例:如果堆栈入口宽度为 4B,那么 stk_size 为 1000,说明堆栈有 4000Bpext:指向用户附加的数据域指针,用来扩展任务的任务控制块 OS_TCBopt:设定 OSTaskCreateExt 的选项,指定是否允许堆栈检验,是否将堆栈清零,是否进行浮点数操作等。具体见 uCOS_II 中每一位定义。只要将相应位与 opt 相或即可返回:OS_NO_ERR :如果函数成功。OS_PRIO_EXIT :如果优先级已经存在。OS_PRIO_INVALID:如果定义优先级的数大于最大值 */*$PAGE*/#if OS_TASK_CREATE_EXT_EN 0 /能
35、使包含创建代码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)/具体含义见上#if OS_CRITICAL_METHOD = 3 /* Allocate storage for CPU status register */为 CPU 状态寄存器分配存储空间OS_CPU_SR cpu_sr;#endifOS_STK *psp;/任务堆栈参数指针INT8U err
36、;/错误参数 #if OS_ARG_CHK_EN 0/允许检验什么东西,没有看懂if (prio OS_LOWEST_PRIO) /* Make sure priority is within allowable range */优先级超出范围return (OS_PRIO_INVALID);/返回优先级不可行#endifOS_ENTER_CRITICAL();/如果可行,进入临界状态if (OSTCBPrioTblprio = (OS_TCB *)0) /* Make sure task doesnt already exist at this priority */保证此优先级不存在OST
37、CBPrioTblprio = (OS_TCB *)1; /* Reserve the priority to prevent others from doing . */* . the same thing until task is created. */保留优先级,说明此优先级已经占用OS_EXIT_CRITICAL();/退出临界状态,这样可以使此函数在定义任务数据结构/其它部分的时候,能够开中断 if (opt /memset 是一个标准的 ANSI 函数,编译器商家会使之最优化#else/这个函数具体是什么不知道。(void)memset(ptos, 0, stk_size * s
38、izeof(OS_STK);#endif psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, opt); /* Initialize the tasks stack */初始化任务堆栈err = OS_TCBInit(prio, psp, pbos, id, stk_size, pext, opt);/任务控制块初始化if (err = OS_NO_ERR) /如果成功则 OS_TCBInit 返回 OS_NO_ERROS_ENTER_CRITICAL();/进入临界状态OSTaskCtr+; /* Increment the #tasks cou
39、nter */创建任务数加一OS_EXIT_CRITICAL();/退出临界状态if (OSRunning = TRUE) /* Find HPT if multitasking has started */如果多任务运行的话,检查高优先级OS_Sched();/任务调度 else /如果任务控制块初始化失败OS_ENTER_CRITICAL();OSTCBPrioTblprio = (OS_TCB *)0; /* Make this priority avail. to others */将这一优先级给其它任务OS_EXIT_CRITICAL();return (err);/如果不允许检验堆栈OS_EXIT_CRITICAL();return (OS_PRIO_EXIST);/如果此优先级存在,返回。#endif/*$PAGE*/ /*