临界段 Critical Sections :
1、为了实现资源共享,一个操作系统必须提供临界段操作的功能
2、uc/os-iii 为了处理林阶段代码需要关中断,处理完毕后需要开中断-——避免其他任务或中断服务进入临界段代码
3、uc/os-iii 定义两个宏(macros)开关中断————OS_ENTER_CRITICAL()
OS_EXIT_CRITICAL()——————>>>OS_CPU.H
任务(task) :通常是一个无限循环
void mytask(void * pdara)
{
do init
while(1)
{
do something;
waiting;
do something;
}
}
保留了优先级为:0,1,2,3,4
OS_LOWEST_PRI0-3、OS_LOWEST_PRI0-2、OS_LOWEST_PRI0-1、OS_LOWEST_PRI0
优先级号越低,任务的优先级越高
uC/OS中的中断处理
1、中断服务子程序要用汇编语言编写
2、用户中断子程序框架:
a、保存全部CPU寄存器
b、调用OSIntEnter 或 OSIntNesting直接加1
c、执行用户代码做中断服务
d、调用OSIntExit();
e、恢复所有CPU寄存器
f、执行中断返回指令
// OSIntEnter
void OSIntEnter (void)
{
OS_ENTER_CRITICAL();
OSIntNesting++;
OS_EXIT_CRITICAL();
}
中断与时钟节拍
1、当发生中断时,首先应保护现场,将CPU寄存器入栈,在处理中断函数,然后恢复现场,将CPU寄存器出栈,最后执行中断返回。
2、uC/OS提供了OSIntEnter() 和 OSIntExit()----------->>>告诉内核进入了中断状态
3、时钟节拍是一种特殊的中断,操作系统的心脏。对任务列表进行扫描,判断是否有延时任务应该处于准备就绪状态,最后进行上下文切换。
时钟节拍
1、uC/OS需要用户提供周期信号源,用于实现时间延时和确认超时。节拍率在10-100hz。
节拍率越高,系统的额外负荷就越重
2、时钟节拍的实际频率取决于用户应用程序的精度。时钟节拍源可以是硬件定时器,也可以是50/60Hz交流电源信号
3、用户必须在多任务系统启动以后再启动时钟节拍器,在调用OSStart()之后。
//OSTickISR
void OSTickISR(void)
{
保存处理器寄存器的值;
调用OSIntEnter() 或将OSIntNesting加1
调用OSTimeTick();
调用OSInitExit();
恢复处理寄存器的值;
执行中断返回指令;
}
uC/OS初始化
1、首先调用OSInit();
2、空闲任务idle task,总是处于就绪状态, 优先级总是设成最低——> OS_LOWEST_PRI0
3、初始化了4个空数据结构缓冲区。
uC/OS-II的启动
多任务启动是用户通过调用OSStart()实现的。
OSInit();/* 初始化 uC/OS-III */
......
调用 OSTaskCreate() 或 OSTaskCreateExt();
......
OSStart();/* 开始任务调度!永不返回 */
//OSStart
if ( OSRuning == FALSE )
{
Y =
X =
OSPrioHghRdy =
OSPrioCur =
OSPrioHghRdy =
OSTCBCur =
OSStartHighRdy =
}
任务控制块 (TCB)
1、任务控制块 OS_TCB 是一数据结构,保存该任务的相关参数——任务堆栈指针,状态,优先级,任务表位置,任务链表指针等。
2、一旦任务建立,OS_TCBs 将被赋值。
3、OS_TCB 分两条链表,空闲链表和使用链表
// 任务控制块结构的主要成员
OS_STK *OSTCBStrPtr; //当前任务栈顶指针
struct os_tcb *OSTCBNext; //任务块控制的双重链表指针
struct os_tcb *OSTCBPrev; //任务块控制的双重链表指针
OS_EVENT *OSTCBEventPtr; //事件控制块的指针
void *OSTCBMsg; //消息指针
INT16U OSTCBDly; //任务延时
INT8U OSTCBStat; //任务状态字
INT8U OSTCBPrio; //任务优先级
INT8U OSTCBX; //用于加速进入就绪状态的过程
INT8U OSTCBY; //用于加速进入就绪状态的过程
INT8U OSTCBBitX; //用于加速进入就绪状态的过程
INT8U OSTCBBitY; //用于加速进入就绪状态的过程
任务就绪表 (Ready List)
1、每个任务的就绪标志都放入就绪表中,就绪表中有两个变量OSRdyGrp 和 OSRdyTb1[]。
2、OSRdyGrp 中任务按优先级分组,8个任务为一组。OSRdyGrp 每一位表示每一组中是否有进入就绪状态
就绪表中 OSRdyTb1[] 相应元素的相应位也置位。
任务创建
1、让 uC/OS-II 管理用户的任务,,用户必须要先建立任务
2、用户可以通过传递任务地址和其他参数到以下两个函数之一来创建任务:
OSTaskCreate( ) 、OSTaskCreateExt( )
3、任务不能由中断服务程序(ISR)来建立。
任务调度
1、uC/OS-III是抢占式实时多任务内核,优先级最高的任务一旦准备就绪,则拥有CPU的所有权开始投入运行。
2、任务调度的工作就是:查找准备就绪的最高优先级的任务并进行上下文切换。
3、uC/OS-III 任务调度所花费的时间为常数,与应用程序中建立的任务数无关
4、uC/OS-III 总是运行进入就绪状态任务中优先级最高的哪一个,确定那个任务优先级最高,
下面该那个任务运行了的工作是由调度器(Scheduler)完成的。
5、任务级的调度是由函数OSSched( )完成的。中断级的调度是由另一个函数OSIntExt( )完成的
根据就绪表确定最高优先级
1、OSRdyGrp 值确定高3位,假设OSRdyGrp = 0x08,对应OSRdyTb1[3],高优先级为2;
2、OSRdyTb1[3]值确定低3位,假设OSRdyTb1[3]=0x3a,最高优先级的任务为25
是任务脱离就绪态