第3章μC/OS-Ⅱ中的任务
3.1任务的基本概念
☆μC/OS-Ⅱ操作系统内核的主要工作就是对任务进行管理和调度
☆任务
☆μC/OS-Ⅱ就是能对小任务的运行进行管理和调度的多任务操作系统
☆代码上看,μC/OS-Ⅱ的任务是一个函数,从任务的存储结构上看,μC/OS-Ⅱ的任务由三个部分组成:任务程序代码(函数),任务堆栈和任务控制块。
任务代码:任务的执行部分
任务堆栈:保存任务的工作环境
任务控制块(TCB):任务了任务代码的程序控制块,记录了任务的各个属性

☆μC/OS-Ⅱ的任务(最多含有64个任务):用户任务(应用程序设计者编写的任务,为了解决应用问题而编写的)和系统任务(由系统提供的任务,为应用程序提供某种服务或系统本身服务)
☆任务的状态
任务的状态 说明
睡眠状态 任务只是以代码的形式驻留在程序空间(ROM或RAM),还没有交给操作系统管理时的情况叫做睡眠状态。简单地说,任务在没有被配备任务控制块或被剥夺了任务控制块时的状态叫做任务的睡眠状态
就绪状态 如果系统为配备了任务控制块且在任务就绪表中进行了就绪登记,则任务就具备了运行的充分条件,这时任务的状态就叫做就绪状态
运行状态 处于就绪状态的任务如果经调度器判断获得了CPU的使用权,则任务就进入运行状态,任何时刻只能有一个任务处于运行状态,就绪的人任务只有当所有优先级高于本任务的任务都转为等待状态时,才能进入运行状态。
等待状态 正在运行的任务,需要等待一段时间或需要等待一个事件发生再运行时,该任务就会把CPU的使用权让给其他任务而使任务进入等待状态。
中断服务状态 一个正在运行的任务一旦响应中断申请就会中止运行而去执行中断服务,这时任务的状态叫做中断服务状态。

☆任务在不同状态之间的转换图

☆用户任务代码的一般结构
根据嵌入式系统任务的工作特点,任务的执行代码通常是一个无限循环结构,并且在这个循环中可以响应中断,这种结构也叫做超循环结构。
示例:
void Mytask (void * pdata)
{
for(;;)
{
可以被中断的用户代码;
OS_ENTER_CRITICAL(); //进入临界段(关中断)
不可以被中断的用户的代码;
OS_EXIT_CRITICAL(); //退出临界段(开中断)
可以被中断得用户代码;
}
}
从程序设计的角度来看,一个μC/OS-Ⅱ任务的代码就是一个C语言函数。同时为了可以传递各种不同类型德 数据甚至是函数,任务的参数是一个void类型的指针。
μC/OS-Ⅱ里定义的宏OS_ENTER_CRITICAL()和OS_EXIT_CRITICAL()用以有效地对中断进行控制。
而在运行这两个宏之间的代码时是不会响应中断的,这种受保护的代码叫做临界段。在具体应用中可以根据实际需要在一个任务中使用这对宏从而设置多个临界段。
因此,μC/OS-Ⅱ任务的代码结构是一个带有临界段的无限循环。
☆用户应用程序的一般结构
从程序设计来看,用户任务是一个任务(进程)。不会被主函数或其他函数调用,主函数只负责创建和启动它们,而由操作系统负责调度运行它们。
用户应用程序的代码示例:
void MyTask1(void *pdata) //定义用户任务1
{
for(;;)
{
……
}
}
void MyTask2(void *pdata) //定义用户任务2
{
for(;;)
{
……
}
}
void MyTask3(void *pdata) //定义用户任务3
{
for(;;)
{
……
}
}

void main()
{
……
OSInit(); //初始化μC/OS-Ⅱ
……
OSTaskCreate(MyTask1,……); //创建用户任务1
OSTaskCreate(MyTask2,……); //创建用户任务2
OSTaskCreate(MyTask3,……); //创建用户任务3
……
OSSTART(); //启动μC/OS-Ⅱ

……
}
其中,OSTaskCreate()为操作系统μC/OS-Ⅱ提供的用来创建任务的函数;OSStart()为操作系统μC/OS-Ⅱ提供的启动各任务的函数,使用之后,任务就交由操作系统来管理和调度了。
☆系统任务
μC/OS-Ⅱ里所定义的两个应用程序的系统任务:
空闲任务(每个应用程序必须使用的):
在多任务系统运行时,系统经常会在某个时间内无用户任务可运行而处于所谓的空闲态。为使CPU在没有用户任务可执行时有事可做,μC/OS-Ⅱ提供了一种叫做空闲任务OSTaskIdle()的系统任务。
void OSTASKIdle(void * pdata)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif

pdata = pdata; //防止某些编译器报错
for(;;)
{
OS_ENTER_CRITICAL(); //关闭中断
OSdleCtr++; //计数
OS_EXIT_CRITICAL(); //开放中断
}
}
pdata = pdata,因为任务中没有用到参数pdata,防止某些C语言编译器报错。
空闲任务,只是对系统定义的一个空闲任务运行次数计数器OSdleCtr进行加1操作,也可以在空闲任务中编写一些用户的代码。
μC/OS-Ⅱ规定,一个用户应用程序必须使用这个空闲任务,而且这个任务是不能用软件来删除的。
统计任务(应用程序可以根据实际需求来选择使用的):OSTaskStart(),每秒计算一次CPU在单位时间内被使用的时间,并把计算结果以百分比的形式存放在变量OSCPUUsage中,便以应用程序通过访问它来了解CPU的利用率。
用户可以根据应用程序的实际需要来进行选择,如果使用必须定义在系统头文件OS_CFG.H中的系统配置常数OS_TASK_STAN_EN设置为1,必须在创建统计任务前调用函数OSStartInit()对统计任务进行初始化。
☆任务的优先权及优先级别:
μC/OS-Ⅱ中的任务必须具有一个唯一的优先级别,μC/OS-Ⅱ把任务的优先权分为64个优先级别,每一个级别都用一个数字来表示,数字0表示任务的优先级别最高,数字越大表示任务的优先级别越低。
通常,一个应用程序的任务数小于64。为了节省内存,用户可以根据应用程序的需要,在文件OS_CFG.H中通过给表示最低优先级别的常数OS_LOWEST_PRIO赋值的方法,来说明应用程序中任务优先级别的数目。系统中可供使用的优先级别为OS_LOWEST_PRIO + 1个。同时也限制了应用程序中任务的总数最多为OS_LOWEST_PRIO + 1个。系统总是把最低优先级别OS_LOWEST_PRIO自动赋给空闲任务。如果应用程序中还使用了统计任务,则系统会把优先级别OS_LOWEST_PRIO – 1自动赋给统计任务,因此用户任务可以使用的优先级别是OS_LOWEST_PRIO – 1个。
2.2 任务堆栈
☆任务堆栈:在储存器中按数据“后进先出(LIFO)”的原则组织的连续存储空间。为了满足任务切换和响应中断时保存CPU寄存器中的内容及存储任务私有数据的需要,每一个任务都应该配有自己的堆栈,任务堆栈是任务的重要组成部分。
☆任务堆栈的创建
在文件OS_CPU.H中专门定义了一个数据类型OS_STK定义任务堆栈
typedef unsigned int OS_STK; //该类型长度为16位
定义任务堆栈的栈区,即定义一个OS_STK类型的一个数组
#define TASK_STK_SIZE 512; //定义堆栈的长度(1024字节)
OS_STK_TaskStk[TASK_STK_SIZE]; //定义一个数组来作为任务堆栈
当调用函数OSTaskCreate()来创建一个任务时,把数组的指针传递给函数OSTaskCreate()中的堆栈栈顶参数ptos,就可以把该数组与任务关联起来而形成该任务的任务堆栈。
OS_STK * OSTaskStkInit(
void (* task)(void * pd),
void * pdato,
OS_STK * ptos,
INT16U prio
);
☆堆栈的增长方向随系统所使用的处理器不同而不同,有向上,有向下,因此在使用函数OSTaskCreate()创建任务时,要注意所使用的处理器对堆栈增长方向的支持是向上还是向下的。
☆任务堆栈的初始化
当CPU启动运行一个任务时,CPU的各寄存器总是需要预置一些初始数据,例如指向任务的指针,程序状态字PSW等。
系统启动时,让CPU从任务堆栈里获得数据,因此,应用程序在创建一个新的任务时,就必须把在系统启动这个任务时CPU各寄存器所需要的初始数据首先存放在任务的堆栈里。
任务堆栈的初始化工作应该是由操作系统负责的,μC/OS-Ⅱ在创建任务函数OSTaskCreate()中通过调用任务堆栈初始化函数OSTaskStkInit()来完成任务堆栈初始化工作。
原型如下:
OS_STK * OSTaskStkInit(
void (* task)(void *pd),
void *pdato,
OS_STK *ptos,
INT16U opt
);
2.3 任务控制块及任务控制块链表
☆任务控制块(OS_TCB):μC/OS-Ⅱ中用来记录任务的堆栈指针、任务当前状态、任务的优先级别等一些与任务管理有关的属性的表。
☆为了管理系统中的多任务,μC/OS-Ⅱ把系统所有的任务的控制块链接为两条链表,并通过这两条链表管理个任务控制块,进而再通过任务控制块换来对任务进行相关的操作。
☆任务控制块的结构:
任务控制块是一个结构类型数据。当用户应用程序调用OSTaskCreate()函数创建一个用户任务时,这个函数就会对任务控制块中的所有成员赋予与该任务相关的数据,并驻留在RAM中。

其中成员OSTCBStat用来存放任务的当前的状态,该成员变量可能的值
值 说明
OS_STAT_RDY 表示任务处于就绪状态
OS_STAT_SEM 表示任务处于等待信号量状态
OS_STAT_MBOX 表示任务处于等待消息邮箱状态
OS_STAT_Q 表示任务处于等待消息队列状态
OS_STAT_SUSPEND 表示任务处于等待被挂起状态
OS_STAT_MUTEX 表示任务处于等待互斥型信号量状态

☆任务控制块链表:
μC/OS-Ⅱ用两个链表来管理任务控制块
空任务块链表(其中所有的任务控制块还没有分配任务),在应用程序调用函数OSInit()对μC/OS-Ⅱ系统进行初始化时创建的
任务块链表(其中所有的任务控制块已经分配任务)在调用函数OSTaskCreate()创建任务时建立的。
建立任务控制块链表的具体做法:从空任务控制块链表摘取一个空任务控制块,然后填充上任务属性后,再形成新的链表。
系统在调用函数OSInit()对μC/OS-Ⅱ系统进行初始化时,先在RAM中建立一个OS_TCB结构类型的数组OSTCBTbl[],这样每个数组元素就是一个任务快,然后把这些控制块链接成如下的链表:

由于链表中的这些控制块还没与具体任务相关联,则称为空任务块链表。
μC/OS-Ⅱ初始化时建立的空任务链表的元素一共是OS_MAX_TASKS + OS_N_SYS_TASKS个,其中定义在文件OS_CFG.H中的常数OS_MAX_TASKS指明了用户任务的最大数目,而定义在文件UCOS_II.H中的常数OS_N_SYS_TASKS指明了系统任务的数目。
每当应用程序调用系统函数OSTaskCreate()或OSTaskCreateExit()创建一个任务时,系统就会将空任务控制块链表头指针OSTCBFreeList指向的任务控制块分配给该任务。在给任务控制块中的各成员赋值后,就按任务控制块链表的头指针OSTCBList将其加入到任务控制块链表中。
为了加快对任务控制块的访问速度,除了任务控制块被创建为双链表之外,μC/OS-Ⅱ在μC/OS-Ⅱ.H文件中还定义了一个数据类型为OS_TCB *的数组OSTCBTbl[],专门用来以任务的优先级别为顺序在各个数组元素里存放指向各个任务控制块的指针,同时为了μC/OS-Ⅱ能随时访问正在运行任务的任务控制块,定义了一个OS_TCB*类型的变量OSTCBCur,专门存放当前正在运行的任务的任务控制块指针。
μC/OS-Ⅱ允许使用函数OSTaskDel()删除一个任务,删除一个任务,实质就是把该任务的任务从任务控制块链表中删掉,并把它归还给空任务控制块链表。

2.4 任务就绪表及任务调度
☆多任务操作系统的核心工作:工作调度
调度:通过一个算法在多个任务中确定哪个任务来运行
调度器:完成调度的函数
μC/OS-Ⅱ进行调度的思想:每时每刻总是让优先级别最高的就绪任务处于运行状态。因此,在系统或用户任务调用系统函数及执行中断服务程序结束时,总是调用调度器来确定应该运行的任务并运行它。
☆任务就绪表的结构:
μC/OS-Ⅱ进行任务调度的依据就是任务调度表。
系统总是从处于就绪状态的任务中选择一个任务运行。
任务就绪表:μC/OS-Ⅱ在RAM里设立的,用以记录系统中任务就绪情况,系统中的每一个任务都在这个表中占据一个位置,并用这个位置的状态(1或0)来表示任务是否处于就绪状态。μC/OS-Ⅱ用一个类型为INT8U的数组OSRdyTbl[]来充当任务就绪表。

图2-6表示是一个最多可以记录32个任务就绪状态的任务就绪表,以任务的优先级别高低为顺序,为每一个任务安排一个二进制位,并规定该位的值为1的数表示对应的任务处于就绪状态,0表示对应的任务处于非就绪状态。
每个任务的就绪状态只占一位,则OSRdyTbl[]数组的一个元素可以表达8个任务的就绪状态。8个任务成为一个任务组。
☆对任务就绪表的操作:
将优先级别为prio的任务设置为就绪状态
OSRdyGrp |= OSMapTbl[prio >> 3];
OSRdyTbl[prio >> 3] |= OSMapTbl[prio & 0x07];
其中OSMapTbl[]是μC/OS-Ⅱ为加快运算速度定义的一个数组,其元素值为:
OSMapTbl[0] = 00000001B;
OSMapTbl[1] = 00000010B;
OSMapTbl[2] = 00000100B;
OSMapTbl[3] = 00001000B;
OSMapTbl[4] = 00010000B;
OSMapTbl[5] = 00100000B;
OSMapTbl[6] = 01000000B;
OSMapTbl[7] = 10000000B;

使优先级别为prio的任务脱离就绪状态。
if(OSRdyTbl[prio >> 3] &= -OSMapTbl[prio & 0x07] == 0)
OSRdyGrp &= -OSMapTbl[prio >> 3];
从任务就绪表中获取优先级别最高的就绪任务:
y = OSUnMapTal[OSRdyGrp];
//获得优先级别的D5、D4、D3位
x = OSUnMapTal[OSRdyTbl[y]];
//获得优先级别的D2、D1、D0位
prio = (y << 3) + x;
//获得就绪任务的优先级别


y = OSUnMapTal[OSRdyGrp];
prio = (INT8U)((y << 3) + OSUnMapTal[OSRdyTbl[y]]);

OSUnMapTal[]也是μC/OS-Ⅱ为提高查找速度定义的一个数组:

☆任务的调度:
在多任务系统中,令CPU中止当前正在运行的任务转而去运行另一个任务的工作叫做任务的切换,而按照某种规则进行任务切换的工作叫做任务的调度。
☆任务调度器(在μC/OS-Ⅱ中实现任务调度):在任务就绪表中查找具有最高优先级别的就绪任务;实现任务的切换。
任务级的调度器:由函数OSSched()来实现
中断级的调度器:由函数OSIntExt()来实现。
☆调度器任务切换的两个步骤:获得待运行任务的TCB指针;进行断点数据的切换。
获取待运行就绪任务控制块的指针:
被中止任务的任务控制块指针存放在全局变量OSTCBCur中
OSSched()的源代码:
void OSSched(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR_ cpu_sr;
#endif

INT8U y;

OS_ENTER_CRITICAL();
if((OSLockNesting | OSIntNesting) == 0)
{
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy //得到最高级优先任务
= (INT8U)((y << 3) + UnMapTbl[OSRdyTbl[y]]);
if(OSPrioHighRdy != OSPrioCur)
{
OSTCBHighRdy //得到任务块指针
= OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; //统计任务切换次数的计数器加1
OS_TASK_SW();
}
OS_EXIT_CRITICAL();
}
☆函数OSSchedLock()和OSSchedUnlock()给调度器上锁和解锁。
变量OSLockNesting记录调度器被锁和解锁的情况,上锁一次加1,反之减1,可以通过访问变量OSLockNesting了解调度器上锁的嵌套次数。
☆调度器OSSched()来确认未被上锁且不是中断服务程序调用调度器的情况下,首先从任务就绪表中查得的最高优先级别就绪任务的优先级别OSPrioHighRdy;然后在确认这个就绪任务不是当前正在运行的任务(OSPrioCur存放正在运行任务的优先级别)的条件下,用OSPrioHighRdy作为下标去访问数组OSTCBPrioTbl[],把数组元素OSTCBPrioTbl[OSPrioHighRdy]的值赋给指针变量OSTCBHighRdy。
☆任务切换宏OS_TASK_SW()
靠OSCtxSw()来实现任务的切换。
断点:任务被中止运行时的位置
断点数据:任务被中止时存放在CPU的PC、PSW和通用寄存器等各寄存器中的数据

“无缝”的接续运行:在任务被中止时把该任务的断点数据保存到堆栈中,被重新运行时,把堆栈中的断点数据再恢复到CPU的各寄存器中。
一个被中止的任务能否正确地在断点处恢复运行,关键在于是否能正确地在CPU各寄存器中恢复断点数据,而能正确恢复断点数据的关键是CPU的堆栈指针SP是否有正确的指向。
防止被中止任务堆栈指针的丢失,被中止任务在保存断点时,要把当时的CPU的SP值保存到该任务控制块的成员OSTCBStkPtr中。
即,任务的切换就是断点数据的切换,断点数据的切换就是CPU堆栈指针的切换,被中止运行任务的任务堆栈指针要保存到该任务的任务控制块中,而待运行任务的任务堆栈指针由该任务控制块转存到CPU的SP中。
☆调度器在任务切换时的工作过程:

OSCtxSw()要依次做下述7项工作:
(1)把被中止任务的断点指针保存到任务堆栈中;
(2)把CPU通用寄存器的内容保存到任务堆栈中;
(3)把被中止任务的任务堆栈指针当前值保存到该任务的任务控制块的OSTCBStkPtr中;
(4)获得待运行任务的任务控制块;
(5)使CPU通过任务控制块获得待运行任务的任务堆栈指针;
(6)把待运行任务堆栈中通用寄存器的内容恢复到CPU的通用寄存器中;
(7)使CPU获得待运行任务的断点指针(该指针是待运行任务在上次被调度器中止运行时保留在任务堆栈中的)
代码为:
void OSCtxSw(void)
{
用压栈指令把CPU通用寄存器R1、R2、…压入堆栈;
OSTCBCur -> OSTCBStkPtr = SP; //在中止任务控制块中保存SP
OSTCBCur = OSTCBHighRdy; //任务控制块的切换
OSPrioCur = OSPrioHighRdy;
SP = OSTCBHighRdy -> OSTCBStkPtr; //使SP指向待运行任务堆栈
用出栈指令把R1、R2、…弹入CPU的通用寄存器;
IRET; //中断返回,使PC指向待运行任务
}
☆引发中断:
(1)微处理器中有软中断指令,在OS_TASK_SW()中封装一个软中断指令
(2)没有软中断指令,使用OS_TASK_SW()中封装其他可使PC等相关寄存器压栈的指令。
2.5 任务的创建
☆创建任务:创建任务控制块,并通过任务控制块把任务代码和任务堆栈关联起来形成一个完整的任务,且使刚创建的任务进入就绪状态,接着引发一次任务调度。
☆函数OSTaskCreate()创建任务:

函数对待创建任务的优先级别进行一系列判断,确认该优先级别合法且未被使用后,然后用OSTaskStkInit()和OSTCBInit()对任务堆栈和任务控制块进行初始化,初始化成功后,把任务计数器加1,判断μC/OS-Ⅱ的核是否在运行状态(即OSRunning的值是否为1),值为1调用OSSched()进行任务调度。
OSTaskCreate()调用成功后,返回OS_NO_ERR;否则,根据具体情况返回OS_PRIO_INVALID、OS_PRIO_EXIST及在函数内部调用任务控制块初始化函数失败时返回的信息。
☆OSTaskCreateExt()创建任务:

更灵活,增加了额外开销。
☆创建任务的一般方法:
在调用启动函数之前先创建一个任务,并赋予它最高的优先级别,从而使它成为起始任务,然后在这个起始任务中,再创建其他任务。
☆PC功能函数
PC功能函数 说明
PC_DOSSaveReturn() 保存DOS环境
PC_VccctSet() 设置中断向量,即把中断向量添入中断向量码对应的中断向量表项中
PC_SetTickRate() 设置μC/OS-Ⅱ时钟频率
PC_DispChar() 在PC的显示器上的指定位置显示一个字符
PC_GetKey() 获得键盘按键的键值
PC_DOSReturn() 恢复DOS环境
2.6 任务的挂起和恢复

挂起任务(停止任务):
INT8U OSTaskSuspend (INT8U prio);

恢复任务:
INT8U OSTaskResume(INT8U prio);

2.7 其他任务管理函数
☆任务优先级别的修改:
OSTaskChangePrio()函数
INT8U OSTaskChangePrio(
INT8U oldprio; //任务现在的优先级别
INT8U newprio;//要修改的优先级别
);
若调用成功,则返回OS_NO_ERR.
☆任务的删除(把任务置于睡眠状态):
把被删除任务的任务控制块从任务控制块链表中删除,并归还给空任务控制块链表,然后在任务就绪表中把该任务的就绪状态位置0。
OSTaskDel():
#if OS_TASK_DEL_EN
INT8U OSTaskDel(
INT8U prio;\\要删除任务的优先级别
);
调用删除任务自己时,则用参数prio为OS_PRIO_SELF。
OSTaskDelReq():
INT8U OSTaskDelReq(
INT8U prio;//待删除任务的优先级别
);
查询任务的信息(了解任务的指针、堆栈的信息):
OSTaskQuery():
INT8U OSTaskQuery(
INT8U prio;//待查询任务的优先级别
OS_TCB *pdata;//存储任务信息的结构
);
2.8 μC/OS-Ⅱ的初始化和任务的启动
☆μC/OS-Ⅱ的初始化(对μC/OS-Ⅱ自身的运行环境进行初始化)
OSInit():对μC/OS-Ⅱ的所有全局变量和数据结构进行初始化(即创建包括空任务控制块链表在内的5个空数据缓冲区),同时创建空闲任务OSTaskIdle,并赋予最低的优先级别和永远的就绪状态。创建一个数组OSTCBPrioTbl[OS_LOWEST_PRIO + 1],方便快速查询任务控制块链表中的各元素。
☆初始化后各全局变量的情况
变量 值 说明
OSPrioCur 0 类型为INT8U,正在运行的任务的优先级
OSPrioHighRdy 0 类型为INT8U,具有最高优先级别的就绪任务的优先级
OSTCBCur NULL 类型为OS_TCB *,指向正在运行多任务控制块的指针
OSTCBHighRdy NULL 类型为OS_TCB *,指向最高优先级别就绪任务控制块的指针
OSTime 0L 类型为INT32U,表示系统当前任务时间(节拍数)
OSIntNesting 0 类型为INT8U,存放中断嵌套的层数(0~255)
OSLockNesting 0 类型为INT8U,调用了OSSchedcdLock的嵌套层数
OSCtxSwCtr 0 类型为INT32U,上下文切换的次数
OSTaskCtr 2 类型为INT8U,已结建立了的任务数
OSRunning FALSE 类型为BOOLEAN,μC/OS-Ⅱ核是否正在运行的标志
OSCPUUsage 0 类型为INT8S,存放CPU的利用率的变量
OSIdleCtrMax 0L 类型为INT32U,表示每秒空闲任务计数的最大值
OSIdleCtrRun 0L 类型为INT32U,表示空闲任务计数器每秒的计数值
OSIdleCtr 0L 类型为INT32U,表示空闲任务的计数器
OSStatRdy FALSE 类型为BOOLEAN,统计任务是否就绪的标志
OSIntExity 0 类型为INT8U,用于函数OSInitExt()

☆μC/OS-Ⅱ的启动:
启动函数OSStart()

2.10 小结
(1)任务由任务控制块、任务堆栈和任务代码组成;
(2)系统按任务就绪表和任务的优先级别来调度任务的;
(3)任务切换的核心工作是任务堆栈指针的切换;
(4)任务调度器代码的设计,使得它的运行时间与系统中的任务数无关,从而使它满足了实时系统的要求;
(5)任务的优先级别也是任务的标识;
(6)应用程序首先应该调用OSInit()函数对全局变量和数据结构进行初始化,以建立uC/OS-II的运行环境;
(7)应用程序是通过调用函数OSStart()开始进入多任务管理的,但在调用函数OSStart()之前必须至少创建一个任务。

操作系统μC/OS-Ⅱ读书笔记(2)相关推荐

  1. [操作系统] 操作系统真相还原读书笔记三:MBR加载loader到内存并跳转到loader执行

    为什么要有loader程序? 通过操作系统真相还原读书笔记二:编写MBR主引导记录我们已经能够正常运行MBR主引导记录(有些书籍也叫做boot)程序了,但该程序什么也没做.我们的MBR 受限于 512 ...

  2. 操作系统 真象还原 读书笔记

    文章目录 环境配置 1.虚拟机virtualBox和centos 2.最小化虚拟机安装后需要配置的基本软件 2.1虚拟机连网 2.2 虚拟机软件安装 3.共享文件设置 3.1安装virtualBox增 ...

  3. 【OS修炼指南目录】----《X86汇编语言-从实模式到保护模式》读书笔记目录表

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 本文是将个人 ...

  4. 《MAC OS X 技术内幕》读书笔记第一章:MAC OS X的起源

    <MAC OS X 技术内幕>读书笔记第一章:MAC OS X的起源 前言 1 System x.x系列 1.1System 1.0(1984年1月24日) 1.2System 2.x(1 ...

  5. 《自己动手写操作系统》读书笔记——初识保护模式

    <自己动手写操作系统>读书笔记--初识保护模式 http://www.cnblogs.com/pang123hui/archive/2010/11/27/2309930.html 书本第三 ...

  6. 《Objective-C高级编程 iOS与OS X多线程和内存管理》读书笔记

    <Objective-C高级编程 iOS与OS X多线程和内存管理>读书笔记 第一章:自动引用计数 自己生成的对象,自己所持有. 非自己生成的对象,自己也能持有 不再需要自己持有的对象时释 ...

  7. 操作系统OS学习笔记(1):操作系统的发展

    操作系统(OS)的目标 实现:方便性/有效性/可扩充性/开放性 方便性 如果在计算机硬件上配置了OS=可以使用编译命令将用户采用高级语言编写的程序翻译成机器代码,或者直接通过OS所提供的各种命令来操纵 ...

  8. 安全——《微服务设计》读书笔记

    身份认证和授权       1.单点登录(SSO) 当主体试图访问一个资源,他会被定向到一个身份提供者那里进行身份验证,身份提供者验明正向后会发消息给服务提供者,让服务提供者来决定是否允许它访问资源. ...

  9. 《Apache Kafka 实战》读书笔记-认识Apache Kafka

    <Apache Kafka 实战>读书笔记-认识Apache Kafka 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.kafka概要设计 kafka在设计初衷就是 ...

  10. 测试思路系列:《谷歌的软件测试之道》读书笔记

    一  谷歌的测试理念 谷歌专职测试人员很少. 把开发过程和测试融合在一起--开发和测试必须同时开展. 写一段代码就立刻测试这段代码,开发人员要对自己写的代码负责,比专职的测试人员更适合做测试工作. 质 ...

最新文章

  1. 盘点类别级物体6D位姿估计
  2. java 项目加载dll文件,在eclipse java项目中加载dll文件
  3. 人脸质量评估网络推荐
  4. 读书笔记——《迁移到云原生架构》
  5. LeetCode 1697. 检查边长度限制的路径是否存在(排序+并查集)
  6. mysql 使用场景_MySQLMHA典型使用场景
  7. android radiogroup 获取点击位置_屏幕连点器,解放双手[Android]
  8. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 网格系统实例:响应式的列重置
  9. jq监听页面的滚动事件,
  10. Data-mediator入门系列2
  11. Android 控件 之 菜单(Menu)
  12. ES6语法实现数据的双向绑定
  13. 简单的Tomcat中配置访问本地资源(含idea配置)
  14. java中ascii码值_java中的ASCII码值
  15. fscan扫描工具安装
  16. 堆排序算法实现(最小堆)
  17. 21克c1语言,C1人称代词
  18. 通用oa系统_点晴:免费OA系统V20,让协同办公无处不在
  19. 照着这本“书”,3年量产自动驾驶卡车
  20. 给女朋友写一个微信小程序

热门文章

  1. 脑电信号处理(EEG/SEEG)工具介绍
  2. 医疗行业CRM客户管理解决方案
  3. ggplot作图(条形图 误差线点图 折线图 箱线图 密度图 岭图 小提琴图 云雨图 直方图 PCA图 PcoA图 NDMS图 和弦图 维恩图 时间序列图 系统发育树 饼图 生物区系图 地图 )
  4. 【德勤报告:区块链变革媒体业有五种可能】
  5. 检测空间中实心圆与平面是否相交
  6. JAVA:实现简单的人员管理系统
  7. 【译】关于 Go 代码结构的思考
  8. 迷你气象站(雨量计,风速,风向)
  9. 计算机wps二级知识选择题,2020年计算机等级WPS考试经典练习题及答案
  10. 基于springboot+vue的幼儿园管理系统 elementui