您的位置:首页 > 运维架构 > Linux

基于S3C2440的Linux-3.6.6移植——定时器的应用

2013-05-04 21:02 495 查看
定时器是很重要的一个资源,在linux中使用的是TIMER4作为常规的定时器,我们可以通过查看中断资源来找到定时器中断:

[root@zhaocj/]#cat /proc/interrupts
……
30: 20118 s3c S3C2410 Timer Tick
……
如上所示,系统内部的定时器的中断号为30。通过阅读arch/arm/mach-s3c24xx/include/mach目录下的irqs.h文件,很容易得到中断号为30所对应的中断就是TIMER4。

下面就简单分析一下linux定时器的运行机理。
在Mach-zhaocj2440.c文件的最后,会看到:
MACHINE_START(ZHAOCJ2440, "ZHAOCJ2440")
/*Maintainer: Michel Pollet <buserror@gmail.com> */
.atag_offset =0x100,
.map_io =zhaocj2440_map_io,
.init_machine = zhaocj2440_init,
.init_irq = s3c24xx_init_irq,
.timer = &s3c24xx_timer,
.restart = s3c244x_restart,
MACHINE_END
其中的.timer就是定义的定时器,它指向的内核定时器结构s3c24xx_timer是在arch/arm/plat-samsung目录下的Time.c文件内:
struct sys_timer s3c24xx_timer = {
.init = s3c2410_timer_init,
.offset = s3c2410_gettimeoffset,
.resume = s3c2410_timer_setup
};
.init表示初始化定时器资源,.offset表示返回至上一次定时器中断以来的定时器偏移量(单位是毫秒),,resume表示如果想要连续的中断,则要重新建立定时器中断。

我们先来看看定时器初始化函数s3c2410_timer_init:
static void __init s3c2410_timer_init(void)
{
s3c2410_timer_resources();
s3c2410_timer_setup();
setup_irq(IRQ_TIMER4, &s3c2410_timer_irq);
}
s3c2410_timer_resources函数是从平台设备中获取定时器资源;s3c2410_timer_setup函数是建立定时器中断,也就是配置相关的timer4寄存器,我们注意到,在s3c24xx_timer结构中的.resume元素指向的也是这个函数;第三行代码表示创建一个定时器中断。我们重点介绍一下s3c2410_timer_irq结构:
staticstruct irqaction s3c2410_timer_irq= {
.name ="S3C2410 TimerTick",
.flags =IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.handler =s3c2410_timer_interrupt,
};
其中的.name就是我们在前面介绍过的,执行“cat /proc/interrupts”命令时看到的timer4中断的名称;s3c2410_timer_interrupt就是timer4的中断函数,它主要完成的任务是修改jiffies_64变量,以便更新时间。

下面写一段应用程序,演示一下定时器的功能:
#include<stdio.h>
#include<unistd.h>
#include<signal.h>

void sigalrm_fn(int sig)
{
printf("alarm!\n");
alarm(2);
return;
}

int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(2);
while(1) pause();
return 1;
}


该程序的作用是每隔2秒打印“alarm!”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: