UCOS学习笔记(七)时间管理与软件定时器

时间管理

 在裸机编程中,为了实现延时效果我们会使用delay_ms()和delay_us()函数,但是在带操作系统的编程中这俩个延时函数可以使用吗?当然数可以的,但是在延时的同时会停止UCOS的任务调度,在延时完成后才会恢复调度器,如果延时时间长的话对于RTOS来说是毁灭性的,关闭调度器会使任务难以被及时的响应,所以我们需要一种不关闭调度器的延时方法。
 UCOS III提供了与时间管理相关的服务,在前俩章的中断管理中,UCOSIII设置了能提供时基中断的中断源。该中断源提供10HZ到1000HZ之间的中断(通过设置OS_CFG_TICK_RATE_HZ),延时函数的分辨率便是由时基中断来确定的,若设置为1000HZ,最小就可以设置1ms的延时。注意,频率越高,CPU额外的消耗就越多。

API函数

相关代码在OS_TIME.中

函数名功能
OSTImeDly()延时执行函数n个时基
OSTimeDlyHMSM()延时执行任务HH:MM:SS.mmm
OSTimeDlyResume()恢复处于延时状态的任务
OSTimeGet()获得当前的时基计数值
OSTimeTick()用于标记,表示发生了一个时基中断

 其中使用频繁的就是第一个和第二个的,俩个虽然都是延时函数,但是功能是有所区别的。

 OSTImeDly()函数原型

void  OSTimeDly (OS_TICK   dly,
                 OS_OPT    opt,
                 OS_ERR   *p_err)

 第一个参数为任务的延时时基,第二个参数为延时模式,第三个参数为错误码。任务调用这个函数后会被挂起直到期满,这个函数可以有三种模式:相对延时模式、周期性延时模式、绝对定时模式。
 周期性延时和周期性延时都是精确地延时,会被中断打断,进入中断后花费的时间可就不可预计了,但是绝对定时模式是可以提供精确延时的,如果是对延时有很高的要求最好还是使用绝对定时模式。

 OSTimeDlyHMSM()函数原型

void OSTimeDlyHMSM (CPU_INT16U   hours,
                     CPU_INT16U   minutes,
                     CPU_INT16U   seconds,
                     CPU_INT32U   milli,
                     OS_OPT       opt,
                     OS_ERR      *p_err)

 这个函数就比 OSTImeDly()友好多了,看参数就可以看出来,前四个参数分别是小时、分钟、秒和毫秒的延时值,第五个参数为选择计数模式和取值范围,最后为错误码。
 关于opt参数,模式选择与OSTImeDly()是完全相同的,选择取值范围时如果选择OS_OPT_TIME_HMSM_STRICT是与我们习惯的取值范围是相同的,即毫秒取值0-999,秒的取值0-59,分钟的取值0-59,小时的取值为0-99;若选择OS_OPT_TIME_HMSM_NON_STRICT取值范围为数据类型的最大取值范围。推荐使用我们的习惯计法,这样设置的时候可读性更好,而且OS_OPT_TIME_HMSM_STRICT是默认的,如果要用这个格式是可以不写这个参数的。
比如要设置2小时30分钟30秒300毫秒的相对延时,程序可以写为:

OSTimeDlyHMSM(2,30,30,300,OS_OPT_TIME_DLY,p_err);

软件定时器

 32给我们提供了多达8个的硬件定时器,但是在使用操作系统时我们经常会有那种需要定时执行的任务,全吧使用硬件定时器是不现实的,所以UCOSIII给我们提供了软件定时器服务,当设置OS_CFG_TMR_EN为1时软件定时器服务被使能。软件定时器与硬件定时器类似,递减其计数值,当计数值为0时,就是定时器期满时通过回调函数来执行相应的操作。回调函数由我们自己定义,但是在回调函数中不能调用上面的延时函数以及OSxxxPend()函数(请求信号量、mutex、消息队列等)或者其他能导致定时器任务被阻塞或者删除的函数。
应用中能够设置任意多的软件定时器(限制于RAM)
 定时器的分辨率决定于时基频率也就是变量)OS_CFG_TMR_TASK_RATE_HZ的值,它是以HZ为单位的,推荐值为10HZ,也就是十分之一秒,定时器用于不精确时间尺度的任务。

API函数

相关代码在OS_TMR.中

函数名功能
OSTmrCreate()创建和设置定时器
OSTmrDel()删除一个定时器
OSTmrRemainGet()获得定时器的剩余期限值
OSTmrStart()开始定时器运行
OSTmrStateGet()获得定时器当前的状态
OSTmrStop()暂停定时器

 一般使用的多的就是加标记的三个函数

 OSTmrCreate()函数原型

void  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)			//错误码

 别的参数就不说了,opt参数若设置为OS_OPT_TMR_ONE_SHOT表示该定时器只运行一次,而设置为OS_OPT_TMR_PERIODIC的话运行完一次后会将定时器重新加载。
 写回调函数时要按照以下的格式

void tmr1_callback(void *p_tmr, void *p_arg)
{
	功能代码;
}

函数名就是函数的指针所以只用将函数的名字传入即可。

 OSTmrStart()函数原型

CPU_BOOLEAN  OSTmrStart (OS_TMR  *p_tmr,			//一个定时器变量的指针
                         OS_ERR  *p_err)			//错误码

 这个函数就很简单了,就不赘述了;

 OSTmrCreate()函数原型

CPU_BOOLEAN  OSTmrStop (OS_TMR  *p_tmr,				//一个定时器变量的指针
                        OS_OPT   opt,				//选项
                        void    *p_callback_arg,	//回调函数的参数
                        OS_ERR  *p_err)				//错误码

 opt如果选择OS_OPT_TMR_NONE为直接关闭定时器,如果选择OS_OPT_TMR_CALLBACK则会在关闭定时器的时候调用回调函数同时将参数在创建定时器时传给定时器,OS_OPT_TMR_CALLBACK_ARG则会在关闭定时器的时候调用回调函数并且把这个参数传给这个函数使用。

总结

 以上就是关于时间管理和软件定时器的一些知识点以及API函数,当然,完全没有涉及到底层的实现,只是表层的一些应用,关于底层实现的知识可能以后才会在博客中记录,我以后会试着自己去实现一个微缩版的UCOS。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值