一、
1、任务优先级:
ucos操作系统它是根据就绪表中任务的优先级来决定任务的运行顺序的。每个任务都是具有优先级的,它是任务的唯一标识。数值越小,优先级越高。
2、任务堆栈:
每个任务都有自己的堆栈,主要用于保存该任务中变量及寄存器的值。在创建任务时,任务堆栈大小即是其中一个入口参数
3、任务控制块(OS_TCB):
记录任务堆栈指针,任务优先级、任务状态、任务函数指针
任务就绪表:记录系统中所有处于就绪状态的任务。
任务调度器:
作用一:在任务就绪表中查找优先级最高的就绪任务(当一个任务释放CPU控制权后,进行一次任务调度)
作用二:实现任务的切换(将任务从就绪态切换至运行态)
二、
任务状态:
睡眠态:任务在没有配备任务控制块或被剥夺任务控制块时的状态。 (OSTaskDel())
就绪态:任务分配了任务控制块且在就绪表中进行了就绪登记。(OSTaskCreate())
运行态:任务获得了CPU的使用权,并正在运行中
等待态:正在运行的任务,需要等待一段时间或等待一个事件发生在运行时,该任务会让出CPU使用权给别的任务,从而使该任务进入等待态。(OSSemPend()、OSMutexPend()、OSQPend()、OSTimeDlyHMSM())
中断服务状态:正在运行的任务,突然响应中断去执行中断服务程序,此时该任务进入中断等待态。
建立任务函数:
请求任务删除函数:
先发送删除请求,来实现任务释放自身占用资源后在删除
任务删除函数:(删除任务控制块,将任务置于睡眠状态)
prio:任务的优先级,通过任务的优先级实现任务删除
注意:必须在确保被删除任务的资源被释放的前提下才能删除。
改变任务优先级的函数:
任务挂起函数:(等待态)
将即将被挂起的任务的就绪态删除,并做任务挂起记录,不删除任务控制块。
解挂后可以继续运行
三、Ucos 共享资源的锁机制:
关中断/开中断:
关、开中断是独占共享资源最简单也是最快捷的方法。这种方法也是任务和中断服务程序共享变量或数据结构的唯一方法。特点:任务执行过程中不会被中断程序打断。缺点:造成中断延迟。
调度器上锁/解锁:
特点:任务执行过程中可以被中断打断,但不会被就绪表中高优先级的任务打断。
缺点:违背了ucos高优先级任务优先执行的原则
上锁函数:OSSchedlock() 解锁函数:OSSchedUnlock();
信号量:
常用于任务的同步和资源管理。允许多个任务获取信号量访问共享资源,但会限制任务的最大数目。访问的任务数达到可支持的最大数目时,会阻塞获取该信号量的任务,直到有任务释放了信号量。
缺点:会导致任务优先级反转
/*01创建信号量*/
void OSSemCreate (OS_SEM *p_sem,
CPU_CHAR *p_name,
OS_SEM_CTR cnt,
OS_ERR *p_err)
/*参数:
p_sem,信号量对象
p_name,信号量名字
cnt,信号量的初值
p_err,返回错误码,没有错误的就返回OS_ERR_NONE*/
/*等待信号量*/
OS_SEM_CTR OSSemPend (OS_SEM *p_sem,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
/*参数:
p_sem,信号量对象
timeout,超时时间,默认写0,一直等待
opt,设置当前等待互斥锁的阻塞方式,默认写OS_OPT_PEND_BLOCKING,阻塞等待
p_ts,用于记录等待信号量花了多长时间,默认写NULL,不记录。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE
*/
/*释放信号量*/
OS_SEM_CTR OSSemPost (OS_SEM *p_sem,
OS_OPT opt,
OS_ERR *p_err)
/*参数:
p_sem,信号量对象
opt,信号量接收方
.OS_OPT_POST_1,只释放信号量给最高优先级且就绪的任务
.OS_OPT_POST_ALL,释放给所有等待信号量的任务,
p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:
当前信号量计数值。*/
互斥锁:
一种特殊的二进制信号量,区别在于:一旦一个高优先级的任务依赖一个低优先级任务释放信号量,则将低优先级任务的优先级暂时提高到与高优先级任务相同的优先级。待互斥锁释放后,在恢复成原来的优先级。解决任务优先级反转问题(即中途不会跳转到高优先级且使用同一互斥锁的任务中执行)。
/*创建互斥锁*/
void OSMutexCreate (OS_MUTEX *p_mutex,
CPU_CHAR *p_name,
OS_ERR *p_err)
/*参数:
p_mutex,互斥锁对象
p_name,互斥锁名字
p_err,返回错误码,没有错误的就返回OS_ERR_NONE
返回值:无*/
/*等待互斥锁*/
void OSMutexPend (OS_MUTEX *p_mutex,
OS_TICK timeout,
OS_OPT opt,
CPU_TS *p_ts,
OS_ERR *p_err)
/*
参数:
p_mutex,互斥锁对象
timeout,超时时间,默认写0,一直等待
opt,设置当前等待互斥锁的阻塞方式,默认写OS_OPT_PEND_BLOCKING,阻塞等待。如果互斥锁此时被另外一个任务占用,且指定的阻塞类型为OS_OPT_PEND_NON_BLOCKING,则OSMutexPend就会直接返回而不再等待互斥锁被释放。
p_ts,用于记录等待互斥锁花了多长时间,默认写NULL,不记录。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE
说明:
如果占有互斥锁是一个较低优先级多任务,那么UCOSIII就会临时提升它的优先级,使得其等于此时想要获取互斥锁的任务优先级。*/
/*释放互斥锁*/
void OSMutexPost (OS_MUTEX *p_mutex,
OS_OPT opt,
OS_ERR *p_err)
/*
参数:
p_mutex,互斥锁对象
opt,释放互斥锁后希望其他等待锁的任务(最高优先级且就绪)得到立即执行,填写参数OS_OPT_POST_NONE,也是默认值。若使用了OS_OPT_POST_NO_SCHED这个参数,得到互斥锁的任务不会立即执行。
p_err,返回错误码,没有错误的就返回OS_ERR_NONE。*/
死锁:
指两个任务无限制地相互等待对方控制着的资源。 假设某一时刻,任务A获取资源X,任务B获取资源Y,运行一段时间后,任务A和任务B均未释放资源,此时任务A试图获取资源Y,任务B试图获取资源X,则发生死锁。
避免死锁的方法:
1、先得到全部需要的资源,再做下一步工作;
2、用相同的顺序申请多个资源;
临界区:
进入临界段代码之前要关中断,临界段代码执行完后要立即开中断;中途不允许任何中断打入;
进入临界区前调用函数:OS_CRITICAL_ENABLE();
退出临界区前调用函数:OS_CRITICAL_EXIT();