ucos(八)软件定时器

摘要:
1.创建软件计时器void OSTmrCreate(OS_TMR*p_TMR,软件计时器对象p_name:由软件计时器执行的回调函数void MyCallback(OS_TMR*p_tmpr,向软件计时器传递参数的回调函数p_err:如果没有错误,则返回OS_err_NONE),调用OSTMRCCreate创建软件计时器的单个触发器

一、概述

  内核提供了一个模拟定时器的机制,类似于任务,但是占用资源少,只能做一些简单的定时控制,如可以定时的喂狗、控灯。在软件定时器,不能添加时间管理函数、阻塞等待函数(等待互斥锁/信号量/事件标志组/消息队列)。

1.创建软件定时器

 
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)
 
参数:
  • p_tmr:软件定时器对象
  • p_name:软件定时器的名字
  • dly:启动定时器后,延迟多长时间执行,默认隐含dly*10ms
  • period:定时周期,默认隐含period*10ms
  • opt:
    OS_OPT_TMR_ONE_SHOT,软件定时器执行一遍
    OS_OPT_TMR_PERIODIC,软件定时器周期性执行
 
  • p_callback:软件定时器执行的回调函数    void MyCallback (OS_TMR *p_tmr, void *p_arg);
  • p_callback_arg:传递参数给软件定时器的回调函数
  • p_err:返回错误码,没有错误的就返回OS_ERR_NONE
 
  • 单次触发
0
  调用OSTmrCreate创建软件定时器,经过dly个节拍后,才真正启动软件定时器,即调用 OSTmrSrart()。定时器会递减被设置初始的定时值,当该值为 0 时就会调用回调函数并停止定时器,直到 OSTmrStart()被重新开启。通过调用 OSTmrStop()停止定时器。
 
  • 重复单次触发
0
  在定时值为 0 之前调用 OSTmrStart()后一次性定时器被再次触发。这个特性可以被用来模拟看门狗的功能。即OSTmrStart()为刷新计数值即喂狗,一旦计数值减到0,则触发调用软件定时器的回调函数,就可以知道负责刷新计数值的任务即定时调用OSTmrStart()的任务是否可靠执行。
 
  • 周期性执行
0
 
定时器可以被设置为有初始定延周期模式。第一周期的递减值由 OSTmrCreate()中的参数"dly"设置,以后的重载值由"period"值确定。调用 OSTmrStart()重新开始。
 

2.启动软件定时器

 
CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr, OS_ERR *p_err)
 
参数:
  • p_tmr:软件定时器对象
  • p_err:返回错误码,没有错误的就返回OS_ERR_NONE
 
返回值:
  • DEF_TRUE is the timer was started
  • DEF_FALSE if not or upon an error
 

3.停止软件定时器

CPU_BOOLEAN OSTmrStop (OS_TMR *p_tmr, OS_OPT opt, void *p_callback_arg, OS_ERR *p_err)
参数:
  • p_tmr:软件定时器对象
  • os_opt:默认参数,OS_OPT_TMR_NONE
  • p_callback_arg:填写OSTmrCreate创建时传递给软件定时器arg的参数
  • p_err:返回错误码,没有错误的就返回OS_ERR_NONE
 
返回值:
  • DEF_TRUE is the timer was started
  • DEF_FALSE if not or upon an error

4.删除软件定时器

CPU_BOOLEAN OSTmrDel (OS_TMR *p_tmr, OS_ERR *p_err)
参数:
  • p_tmr:软件定时器对象
  • p_err:返回错误码,没有错误的就返回OS_ERR_NONE
 
返回值:
  • DEF_TRUE is the timer was started
  • DEF_FALSE if not or upon an error

二、示例

1、创建1个软件定时器。

OS_TMR g_tmr; void mytimer_Callback (OS_TMR *p_tmr, void *p_arg) { printf("mytimer_Callback
"); } OSTmrCreate(&g_tmr,"g_tmr",0,100,OS_OPT_TMR_PERIODIC,(OS_TMR_CALLBACK_PTR)mytimer_Callback,NULL,&err);

2、创建2个软件定时器。

OS_TMR g_tmr1; OS_TMR g_tmr2; 
void mytimer_Callback (OS_TMR *p_tmr1, void *p_arg)
 { 
  if(p_tmr1 == &g_tmr1) 
    printf("gtmr1 mytimer_Callback
"); 
  if(p_tmr2 == &g_tmr2) 
    printf("gtmr2 mytimer_Callback
"); 
}

OSTmrCreate(&g_tmr1,"g_tmr1",0,100,OS_OPT_TMR_PERIODIC,(OS_TMR_CALLBACK_PTR)mytimer_Callback,NULL,&err); 
OSTmrCreate(&g_tmr2,"g_tmr2",0,100,OS_OPT_TMR_PERIODIC,(OS_TMR_CALLBACK_PTR)mytimer_Callback,NULL,&err); 
OSTmrStart (&g_tmr1,&err); 
OSTmrStart (&g_tmr2,&err);
 
注意:
void timer_callback (OS_TMR *p_tmr, void *p_arg)
 {
   OS_ERR err; 
  OS_FLAGS flags; 
  printf("timer_callback ...
"); 
  OSFlagPend(&g_flag_grp, 0x03, 0, OS_OPT_PEND_FLAG_SET_ANY +OS_OPT_PEND_FLAG_CONSUME +OS_OPT_PEND_BLOCKING,NULL, &err); 
  delay_ms(2000); 
}

  

当前timer_callback会1秒执行一遍,当调用睡眠2秒和等待事件标志组,该函数还是1秒被调用一次。

 

三、定时器状态

0
  任务调用 OSTmrStateGet()获得定时器的状态。当然,也可以调用OSTmrRemainGet()获得剩余定时时间。定时值是以时基为单位的。如果时基定时器的频率率为 10Hz,那么定时值设置为 50 意味着延时 5 秒。如果定时器被停止,那其定时值也将被停止,直到定时器被恢复时,定时器值继续被定时器任务递减。
(1)"Unused"状态意味着定时器尚未被创建或已经被删除。换句话说,系统不知道该定时器的相关状态。
(2)当创建了定时器或调用了 OSTmrStop(),定时器会处于停止模式。
(3)当调用 OSTmrStart()后定时器处于运行状态。
(4)一次性定时模式的定时器延时期满后处于完成状态"Completed"。
注:
  回调函数被执行时会锁调度器,所以必须让回调函数尽可能地短。

四、实例

设置定时器 2秒执行一次回调函数。
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "includes.h"

//任务1控制块
OS_TCB Task1_TCB;

void task1(void *parg);

CPU_STK task1_stk[128];			//任务1的任务堆栈,大小为128字,也就是512字节

OS_TMR g_tmr;   //软件定时器的对象

void  MyCallback (OS_TMR *p_tmr, void *p_arg);
//主函数
int main(void)
{
	OS_ERR err;

	systick_init();  													//时钟初始化
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);						//中断分组配置
	
	usart_init(9600);  				 									//串口初始化
	
	LED_Init();         												//LED初始化	


	//OS初始化,它是第一个运行的函数,初始化各种的全局变量,例如中断嵌套计数器、优先级、存储器
	OSInit(&err);


	//创建任务1
	OSTaskCreate(	(OS_TCB *)&Task1_TCB,									//任务控制块,等同于线程id
					(CPU_CHAR *)"Task1",									//任务的名字,名字可以自定义的
					(OS_TASK_PTR)task1,										//任务函数,等同于线程函数
					(void *)0,												//传递参数,等同于线程的传递参数
					(OS_PRIO)6,											 	//任务的优先级6		
					(CPU_STK *)task1_stk,									//任务堆栈基地址
					(CPU_STK_SIZE)128/10,									//任务堆栈深度限位,用到这个位置,任务不能再继续使用
					(CPU_STK_SIZE)128,										//任务堆栈大小			
					(OS_MSG_QTY)0,											//禁止任务消息队列
					(OS_TICK)0,												//默认时间片长度																
					(void  *)0,												//不需要补充用户存储区
					(OS_OPT)OS_OPT_TASK_NONE,								//没有任何选项
					&err													//返回的错误码
				);				
	if(err!=OS_ERR_NONE)
	{
		printf("task 1 create fail
");
		
		while(1);
	
	}

	//创建软件定时器
	//启动软件定时器再延时 10*10ms才真正开始运行
	//定时触发周期时间 200*10ms=2S
	//OS_OPT_TMR_PERIODIC:周期执行  OS_OPT_TMR_ONE_SHOT:只执行一次回调函数
	//MyCallback  回调函数
	//NULL  ,不传递参数给MyCallback
	OSTmrCreate(&g_tmr,"g_tmr",10,200,OS_OPT_TMR_PERIODIC,(OS_TMR_CALLBACK_PTR)MyCallback,NULL,&err);
	OSTmrStart(&g_tmr,&err);
	//启动OS,进行任务调度
	OSStart(&err);
								
	printf(".......
");
					
	while(1);
	
}



void task1(void *parg)
{
	uint32_t t=0;
	printf("task1 is create ok
");

	while(1)
	{
		printf("task1 is running......
");
		delay_ms(1000);
	}
}

void  MyCallback (OS_TMR *p_tmr, void *p_arg)//回调函数  相当于你之前的定时器中断服务函数
{
	printf("MyCallback OK
");
	delay_ms(6000);  //在回调函数中延时是没有作用的,和没延时一样。
}

  

免责声明:文章转载自《ucos(八)软件定时器》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mybatis 遇到空串无法判断Jmeter之JDBC Request使用方法(oracle)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

02_iOS 沙盒及各个目录详解

处于安全考虑,一个iosAPP对系统文件的交互权限被限制在app的沙盒目录下。 在安装一个新的app的时候,安装程序会在沙盒目录下创建许多的容器,每个容器目录都有特定的角色。 bundle容器目录:保存应用程序的包(主bundle的资源等) 数据容器目录:就是我们平时开发中用到的Documents,library temp。运行的时候app可以额外的申请容...

定时器中断---那些年我们一起玩mini2440(arm9)裸机

(时钟体系)http://blog.sina.com.cn/s/blog_815420370101ni84.html 时钟概念: ★时钟脉冲:一个按一定电压幅度,一定时间间隔连续发出的脉冲信号;   ★时钟频率:在单位时间(如:1秒)内产生的时钟秒冲数; 时钟的作用: 时钟信号是时序逻辑的基础,它用于决定逻辑单元中的状态何时更新。数字芯片中众多的晶体管都工...

分享一个单机软件试用期计时思路

1.首次启动软件时,先获取自己软件写入的注册表项,如果已经存在了,再获取记录的时钟周期数,如果不存在的话,获取主机自cpu上电以来的时钟周期数,已纳秒为单位,然后把这个数保存到电脑自己的注册项里。 2.以后每次启动软件,都获取自cpu上电以来的时钟周期数,然后再去读取首次写入的那个数值。 3.两两相减,计算出的时间差就是软件再这台主机上存在的天数的纳秒值。...

gnuplot运行方式

gnuplot运行方式 terminal terminal下输入gnuplot,进入command line interact 单行命令模式 gnuplot -p -e ‘command1;command2; plot function’ 脚本模式 gnuplot -p /path_to_script/script.p,扩展名为.p,opt...

Java 定时器

Java 定时器 1. 概述 Timer 可以按计划执行重复的任务或者定时执行指定任务,这是因为 Timer 内部利用了一个后台线程 TimerThread 有计划地执行指定任务。 Timer:是一个实用工具类,该类用来调度一个线程(schedule a thread) ,使它可以在将来某一时刻执行。Java 的 Timer 类可以调度一个任务运行一次...

IDEA设置代理

设置代理 Appearance & Beahvior -> System Settings -> HTTP Proxy,选择手动配置代理,输入IP和端口即可。 测试GitHub或者Google是否连接成功 查看代理软件端口号 查看代理软件端口...