您的位置:首页 > 其它

VxWorks中POSIX标准定时机制

2013-10-28 10:34 344 查看
VxWorks中主要提供IEEE的POSIX1003.1b标准定时器和WatchDog两种定时机制。

其中,WatchDog定时器主要作为系统时钟中断服务程序(ISR)的一部分维护。定时器超时后,关联的超时函数将会在系统时钟中断上下文中运行,即单独于当前进程之外运行。这个时候,超时函数与中断服务程序具有同等的约束条件,限制很大。比如,不能有可能导致阻塞的函数(malloc...),无参数且返回类型为void,不可重复进入,禁止中断等等。

LZ实习项目为协议栈开发,所以,对于定时器超时处理,首先应当在当前协议进程中进行,并且超时处理是非常有可能需要发送消息,因此需要带回复消息参数等等,基于以上原因,主要就看了下对POSIX定时机制并记录。

POSIX定时器:

POSIX定时器建立在时钟与信号基础之上,任务程序在指定时间间隔后向自身发送信号并进行处理。程序自身可创建、设置以及删除定时器。

POSIX基本标准是只支持秒级分辨率。由于大多数实时操作系统对定时器有更高要求,因此POSIX的两种扩展:XSI扩展和TMR扩展,他们分别定义了微秒级和纳秒级的时间分辨率。比较诡异的是,VxWorks中没有XSI扩展的标准API,但是却又有XSI支持的微妙级的数据结构,我特别纳闷。

数据类型:

time_t:typedef long time_t;                /* seconds */

struct timeval 
{              
	time_t tv_sec;                     /* seconds */          
	long   tv_usec;                    /* microseconds */   
};

struct timespec
{
	time_t  tv_sec;                    /* seconds */
	long    tv_nsec;                   /* nanoseconds */
};

TMR扩展定时器:

TMR扩展定时器使用的数据结构及POSIX API:

timer_create()         // 创建时钟
timer_gettime()        // 获得时钟器给定值的当前剩余值
timer_settime()        // 设定时钟值
timer_connect()        // 联系用户函数和时钟信号(非POSIX标准)
timer_cancel()         // 取消一个时钟
timer_getoverrun()     // 获取超限次数

API详情请参考《UNIX系统编程》

基本流程:



实例:

#include <vxWorks.h>
#include <stdio.h>
#include <taskLib.h>
#include <time.h>

void timeout_handler(timer_t timerid, int arg);

int count = 0;
timer_t mytimer = 0;
struct itimerspec setting_time;

void myTest(void)
{
	int time_count = 0;
	
	setting_time.it_interval.tv_sec = 2;	
	setting_time.it_interval.tv_nsec = 0;	
	setting_time.it_value.tv_sec = 0;	
	setting_time.it_value.tv_nsec = 100000000;	
	
	/* create timer */
	if (ERROR == timer_create(CLOCK_REALTIME, NULL, &mytimer))
	{
		printf("create failed!\n");
		return;
	}

	/* connect to application */
	if (ERROR == timer_connect(mytimer, (VOIDFUNCPTR)timeout_handler, 0))
	{
		printf("connect failed!\n");
		return;
	}

	/* set and start timer */
	if (ERROR == timer_settime(mytimer, 0, &setting_time, NULL))
	{
		printf("settime failed!\n");
		return;
	}	

	for (;;)
	{
		/* delay 1s */
		taskDelay(sysClkRateGet());
		printf("time_%d== ", time_count);
		if (10 == time_count)
		{
			/* cancel timer */
			(void)timer_cancel(mytimer);
			break;
		}
	}

	/* delete timer */
	(void)timer_delete(mytimer);
}

void timeout_handler(timer_t timerid, int arg)
{
	// 接口参考timer_connect形参
	// static int over = 0;
	
	count++;
	printf("Oh, dear~~\n");
	printf("count_%d== ", count);		
	
	/* test time overrun */
	// taskDelay(sysClkRateGet()*5);
	// over = timer_getoverrun(mytiemr);
	// printf("over_%d== ", over);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: