在创建实时任务的过程中,主要通过3个函数对定时器进行设置,它们分别是:rt_set_oneshot_mode,rt_set_periodic_mode和start_rt_timer,下面分别对这3个函数进行分析。
1. rt_set_oneshot_mode
用于将定时器设置为单触发模式,所谓单触发模式,就是说,每当定时器产生一次中断后,系统都要根据目前系统任务对时间精度的要求情况对定时器重新进行编程,设定下一次触发的时间。rt_set_oneshot_mode完成的功能如下:
1.调用stop_rt_timer停止定时器的运行;
2.设置全局变量oneshot_timer的值为1;在时钟中断函数中,系统会检查oneshot_timer的值,判断定时器的工作模式,然后根据定时器的模式对定时器进行相应的操作。
2. rt_set_periodic_mode
rt_set_periodic_mode的操作与rt_set_oneshot_mode的类似,只不过它将oneshot_timer的值设为0,表示定时器应工作在周期模式;当定时器工作在周期模式下时,系统只要对定时器进行一次初始化,指定定时器产生中断的周期,以后就不再需要对定时器进行编程了。
3. start_rt_timer
根据设定的定时器运行模式对定时器进行初始化,它完成的主要功能如下:
1.调用函数rt_request_timer注册时钟中断服务程序rt_timer_handler;
2.初始化系统用于保存时间信息的结构rt_smp_times(就是前面所说的rt_times);
3.调用rt_request_linux_irq注册一个Linux下的中断服务程序recover_jiffies,这个中断程序和Linux的时钟中断服务程序共享时钟中断,recover_jiffies用于补偿Linux所丢失的时钟中断(因为可能由于实时任务的运行,使Linux很长一段时间得不到运行的机会,无法响应时钟中断)。
4. 注意
- 请注意,如果你不设置模式,默认是周期性的。
- 使用stop_rt_timer停止定时器,会设置定时器返回默认的状态(即周期性的)。如果没有删除在使用的RTAI调度程序,你想确定在多模块上是单触发模式,在每一个start_rt_timer前总要调用rt_set_oneshot_mode。
- 使用start_rt_timer(0),自动强制进入单触发模式。
- rt_is_hard_timer_running API可以知道是否已经有个计时器在运行了,该函数应该小心使用,因为它会形成一个“race”情况。
- 在使用任何与时间处理相关的函数前调用start_rt_timer API很重要,否则所有的值都被认为是错误的。
- 实时任务(本文所指的实时任务,如果没有特别说明都是硬实时的)都是以Linux内核模块方式实现的,要实现一个实时任务,在模块初始化的时候要调用RTAI的任务创建函数初始化实时任务相关的数据和环境,指定定时器的运行模式(单触发模式或周期模式),初始化定时器,然后开始执行任务;需要注意的是,当没有加载任何RTAI的实时任务模块的时候,RTAI的任务调度和时钟中断都没有启动。
5. 示例代码
#define TICK_TIME 1000000
if ((hard_timer_running = rt_is_hard_timer_running()))
{
printf("Skip hard real_timer setting...\n");
sampling_interval = nano2count(TICK_TIME);
}
else
{
printf("Starting real time timer...\n");
rt_set_oneshot_mode();
start_rt_timer(0);
}
sampling_interval = nano2count(TICK_TIME);

本文介绍了RTAI中定时器的三种设置模式:单触发模式、周期模式及启动过程。重点解析了三个关键函数:rt_set_oneshot_mode、rt_set_periodic_mode和start_rt_timer的作用及使用场景,并给出了一个简单的示例代码。
784

被折叠的 条评论
为什么被折叠?



