免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 914 | 回复: 0
打印 上一主题 下一主题

Linux设备驱动简析—Timer(2.6.10) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-22 10:22 |只看该作者 |倒序浏览

/*
*By Neil Chiao (
neilchiao at gmail.com
)
*转载请注明出处:
neilengineer.cublog.cn

*/


    在上次《Linux设备驱动简析--内核中的时间》一文中介绍了jiffies。
Jiffies是Linux内核中的时间单位,也就是内核计数器。每次时钟中断发生时,内核计数器(Jiffies)的值加1,这个值就是系统时钟的滴答数。
时钟中断由定时硬件以周期性的间隔产生,这个间隔由HZ值设定。ARM平台上默认的HZ值是100。


一、时钟驱动初始化调用机制

start_kernelà
asmlinkage void __init start_kernel(void)
{
       ……
       setup_arch(&command_line);
       ……
       time_init();
       ……
}

setup_archà
void __init setup_arch(char **cmdline_p)
{
……
       init_arch_irq = mdesc->init_irq;
       system_timer = mdesc->timer;
       init_machine = mdesc->init_machine;
……
}

       上述代码中mdesc->timer又是什么地方初始化呢?请继续阅读。

mdesc是 struct machine_desc结构体的指针,其初始化在setup_arch函数中:
       mdesc = setup_machine(machine_arch_type);
上述代码在.arch.info段中寻找当前平台,找到后返回其所在位置(指针)。而指针所在地址之后的地址中保存的平台相关信息,如函数指针地址等在MACHINE_START宏中初始化,如xxx平台:
arch/arm/mach-xxx/xxx.c:
MACHINE_START(xxxx, "xxxx")
……
       .timer = &xxx_timer,
……
MACHINE_END

       MACHINE_START宏的定义:
#define MACHINE_START(_type,_name)           \
const struct machine_desc __mach_desc_##_type      \
__attribute__((__section__(".arch.info"))) = {   \
       .nr          = MACH_TYPE_##_type,     \
       .name             = _name,
       简单地说,MACHINE_START宏把相关信息在LD时,放在了.arch.info段中。

而上述的xxx_timer结构定义一般如下:
struct sys_timer xxx_timer = {
       .init         =xxx_timer_init,
       .offset     = xxx_gettimeoffset,
};
       xxx_timer_init函数中初始化并使能硬件时钟,注册中断处理函数等。

       上述代码完成了system_timer的初始化,而实际的调用在time_init函数中:
start_kernelà
asmlinkage void __init start_kernel(void)
{
       ……
       time_init();
       ……
}
      

二、时钟驱动简析

  这里不此具体的驱动为例,说个大概吧。时钟驱动一般都会有如下的结构:

1、arch/arm/mach-xxx/xxx.c:
MACHINE_START(xxxx, "xxxx")
……
       .timer = &xxx_timer,
……
MACHINE_END
     
2、xxx_timer的结构定义:
struct sys_timer xxx_timer = {
       .init         =xxx_timer_init,
       .offset     = xxx_gettimeoffset,
};

3、xxx_timer_init的实现
1)初始化timer的硬件,设置相关寄存器的值(包括时钟中断使能)
2)用类似setup_irq(IRQ_TIMERINT, &xxx_timer_irq);来注册时钟中断,其中xxx_timer_irq就是时钟中断发生时调用的ISR

4、中断处理函数xxx_timer_irq的实现
      一般主要做下面几件事 :
1)write_seqlock(&xtime_lock);
2)清中断
3)timer_tick(regs);
4)write_sequnlock(&xtime_lock);



注意:好像从2.6.22开始,内核中的时钟相关机制有大的改变,有空的时候研究下。









本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/91522/showart_1906446.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP