一、软件定时器
1、什么是软件定时器
UCOS中软件定时器本质是递减计数器,当计数器减到零时可以触发某种动作的执行,这个动作通过回调函数来实现。UCOSIII中定时器的时间分辨率由一个宏OS_CFG_TMR_TASK_RATE_HZ,单位为HZ,默认为100Hz(定时单位为5ms),可以通过修改宏定义的值来修改定时单位长度,定时时间=定时数*定时单位长度。
2、UCOS中软件定时器的API函数
这里主要要讲的是定时器创建函数,在使用创建函数前要先定义一个定时器结构体变量作为函数的参数。
OSTmrCreate (OS_TMR *p_tmr, //软件定时器结构体变量地址指针
CPU_CHAR *p_name, //输入一个字符串作为该创建定时器的名字
OS_TICK dly, //初始延迟数
OS_TICK period, //周期定时数
OS_OPT opt, //工作模式选项
OS_TMR_CALLBACK_PTR p_callback, //回调函数指针
void *p_callback_arg, //传入回调函数的参数
OS_ERR *p_err) //返回报错信息
还有一个参数比较复杂的就是定时器删除函数
OSTmrStop (OS_TMR *p_tmr, //被删除的定时器结构体指针
OS_OPT opt, //删除选项1直接删除2删除前在调用一次回调函数3删除前调用回调函数并传入新的参数
void *p_callback_arg, //模式3删除时传入的新参数的指针
OS_ERR *p_err) //函数报错信息
其余的API函数都比较简单,只需要传入目标定时器结构体和返回报错信息即可。
三、定时器的工作模式
UCOS III中软件定时器的工作模式有单次定时、有初试延迟的周期模式和无初始延迟的周期模式。
1、单次模式
故名思义,即定时器启动后只会按照创建时的初始延迟数(dly)定时一次,时间到后执行回调函数后定时结束。值得注意的是若在计时过程中出现重新开启定时器定时计数将会被重新设定初始值,如下图所示。
2、有初试延迟的周期模式
定时器第一次定时时间由创建该延迟的延迟函数中的dly决定,之后进行的延迟按照创建函数中的period参数进行,如下图所示
3、无初始延迟的周期模式
定时器的定时时间由创建函数中period决定,定时间到调用回调函数后自动重新开始定时,如下图所示
二、信号量与互斥信号量
1、信号量(其实就是个标志位)
主要作用:1保证某些资源被任务占用时不会被其他要调用改资源的任务打断,2进行任务的同步
公共资源保护
举例:A任务要占用打印机资源,若B任务也要占用打印机资源,则在A打印过程中打印机的信号量被A占用,此时即使任务调度器让B运行,B也要等待打印机的信号量被释放(等待过程会将B加入等待列表然后任务调度器在调用A任务),当A完成打印工作信号量重新被释放,释放函数可以选择1将信号量发布给等待列表中最高优先级任务2将信号量发布给所有等待该信号信号任务,3将信号量发布,但不启动任务调度器,B得到信号量才能继续完成任务。
任务同步
举例:任务A为检测按键按下任务B表示若按键按下则LED翻转,A任务若检测到按键按下则释放一次信号量(信号量加1 )当任务B运行且请求到信号量(信号量不为哦0减一)时,B可以翻转LED然后
2、互斥信号量
主要作用:防止因为等待低优先级信号量释放产生的优先级翻转
优先级翻转:
高优先级任务A在等待低优先级任务B释放信号量的过程中,任务B被优先级在AB之间的任务C打断,导致A需要额外让比自己优先级低的任务C执行完,才能得到任务B释放的信号量。如下图所示:
采用互斥信号量优点
当高优先级高的任务A等待低优先级任务B释放信号量时,互斥信号量会将任务B的优先级临时拉高到与等待该信号量的最高优先级任务的优先级一致,如图所示,不会出现高优先级任务等待信号量释放而等待低优先级任务的情况(没有中优先级任务M插入)