`
yesjavame
  • 浏览: 702610 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Marvell-linux研究-pxa-rtc.c源代码分析

阅读更多

Marvell-linux研究-pxa-rtc.c源代码分析

转载时请注明出处和作者联系方式

作者联系方式:李先静<xianjimli at hotmail dot com>

我对RTC感兴趣的原因有两个,一是如何把修改后的时间保存下来,下次开机后,修改后的时间仍然有效,这要把修改后的时间写入RTC的寄存器中去。二是如何实现关机响闹和定时开机,这也要设置RTCALARM寄存器。

这里我们分析一下pxa-rtc.c的源代码

67staticirqreturn_t pxa_rtc_interrupt(intirq,void*dev_id,structpt_regs *regs)
68{
69unsignedintrtsr;
70unsignedlongnum =0, events = RTC_IRQF;
71
72rtsr = RTSR;
73
74/*clear interrupt sources */
75RTSR =0;
76RTSR = (RTSR_AL | RTSR_HZ | RTSR_RDAL1 | RTSR_RDAL2 | RTSR_SWAL1 |
77RTSR_SWAL2 | RTSR_PIAL);
78
79/*clear alarm interrupt if it has occurred */
80#ifdefCONFIG_PXA_RTC_WRISTWATCH
81if(rtsr & (RTSR_RDAL1)) {
82rtsr &= ~(RTSR_RDALE1 | RTSR_RDALE2);
83num++;
84events |= RTC_AF;
85}
86#else
87if(rtsr & RTSR_AL) {
88rtsr &= ~RTSR_ALE;
89num++;
90events |= RTC_AF;
91}
92#endif
93if(rtsr & RTSR_HZ) {
94/*rtsr &= ~RTSR_HZE; */
95num++;
96events |= RTC_UF;
97}
98if(rtsr & RTSR_SWAL1) {
99rtsr &= ~RTSR_SWALE1;
100num++;
101events |= RTC_SWF;
102}
103if(rtsr & RTSR_SWAL2) {
104rtsr &= ~RTSR_SWALE2;
105num++;
106events |= RTC_SWF;
107}
108if(rtsr & RTSR_PIAL) {
109/*rtsr &= ~RTSR_PIALE; */
110num++;
111events |= RTC_PF;
112}
113RTSR = rtsr & (RTSR_ALE | RTSR_HZE | RTSR_RDALE1 |
114RTSR_SWALE1 | RTSR_SWALE2 | RTSR_PIALE |RTSR_PICE |
115RTSR_SWCE);
116
117/*
118printk(KERN_INFO "IRQ num:%d IRQ Events:0x%x\n", (int)num,
119(unsigned int)events);
120*/
121/*update irq data & counter */
122rtc_update(num, events);
123returnIRQ_HANDLED;
124}

72读取RTSR中的值到rtsr变量。

75禁止所有RTC中断。

76清除所有RTC中断的状态。

81-112这段代码检测是否发现了某种中断,若发生了则把计数加1,并设置相应事件位域。

113恢复中断设置。

122调用rtc_update更新rtc_irq_data,并唤醒相应的等待者。

127staticirqreturn_t pxa_rtc_tickirq(intirq,void*dev_id,structpt_regs *regs)
128{
129unsignedlongnum =0, events = RTC_IRQF;
130/*
131 * If we match for the first time, the periodic interrupt flag won't
132 * be set.If it is, then we did wrap around (very unlikely but
133 * still possible) and compute the amount of missed periods.
134 * The match reg is updated only when the data is actually retrieved
135 * to avoid unnecessary interrupts.
136 */
137OSSR = OSSR_M1;/*clear match on timer1 */
138OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
139num++;
140events |= RTC_PF;
141
142/*update irq data & counter */
143rtc_update(num, events);
144returnIRQ_HANDLED;
145}

137清除标志。

138设置下一次的中断时间,间隔时间长度主要用rtc_freq决定,该参数由用户设置。

139增加事件计数。

140-143调用rtc_update更新rtc_irq_data,并唤醒相应的等待者。

148staticvoidtm_to_wwtime(structrtc_time *tm,unsignedint*dreg,
149unsignedint*yreg)

165staticintwwtime_to_tm(unsignedintdreg,unsignedintyreg,
166structrtc_time *tm)

184staticunsignedinttm_to_swtime(structsw_time *tm)

195staticvoidswtime_to_tm(unsignedintswreg,structsw_time *tm)

206staticintpxa_sw_get(structsw_time *tm,unsignedlongcmd,unsignedlongarg)

227staticintpxa_sw_set(structsw_time *tm,unsignedlongcmd,unsignedlongarg)

267staticintpxa_rtc_getalarm(structrtc_wkalrm *alrm)

279staticintpxa_rtc_settime(structrtc_time *tm)

297staticintpxa_rtc_setalarm(structrtc_wkalrm *alrm)

以上函数都非常简单,主要是时间格式的转换,这里不再多说。

315staticintpxa_rtc_ioctl(unsignedintcmd,unsignedlongarg)

提供了RTC比较完整的控制,直接操作寄存器,没有什么复杂的逻辑,这也就不列出代码了。

490staticstructrtc_ops pxa_rtc_ops = {
491.owner= THIS_MODULE,
492.ioctl= pxa_rtc_ioctl,
493.proc = pxa_rtc_read_proc,
494.read_time= pxa_rtc_gettime,
495.set_time = pxa_rtc_settime,
496.read_alarm = pxa_rtc_getalarm,
497.set_alarm= pxa_rtc_setalarm,
498};

该结构定义了RTC的基本操作,其中pxa_rtc_settime就是用来更新时间到RTC中,而pxa_rtc_setalarm就是用来设置硬件ALARM事件的。

500staticintpxa_rtc_probe(structdevice *dev)
501{
502intret;
503
504/*find the IRQs */
505ret = request_irq(IRQ_RTC1Hz, pxa_rtc_interrupt,
506SA_INTERRUPT,"RTC 1Hz",NULL);
507if(ret) {
508printk(KERN_ERR"RTC:IRQ%dalready in use.\n", IRQ_RTC1Hz);
509gotoIRQ_RTC1Hz_failed;
510}
511ret = request_irq(IRQ_RTCAlrm, pxa_rtc_interrupt,
512SA_INTERRUPT,"RTC Alrm",NULL);
513if(ret) {
514printk(KERN_ERR"RTC:IRQ%dalready in use.\n", IRQ_RTCAlrm);
515gotoIRQ_RTCAlrm_failed;
516}
517#ifdef SOFT_IRQP
518ret = request_irq (IRQ_OST1, pxa_rtc_tickirq, SA_INTERRUPT,"rtc timer",NULL);
519if(ret) {
520printk(KERN_ERR"rtc: IRQ%dalready in use.\n", IRQ_OST1);
521gotoIRQ_OST1_failed;
522}
523#endif
524
525/*initialization */
526RTSR =0;
527
528/*register RTC */
529register_rtc(&pxa_rtc_ops);
530return0;
531
532#ifdef SOFT_IRQP
533IRQ_OST1_failed:
534free_irq (IRQ_RTCAlrm,NULL);
535#endif
536IRQ_RTCAlrm_failed:
537free_irq(IRQ_RTC1Hz,NULL);
538IRQ_RTC1Hz_failed:
539return-EBUSY;
540}

先注册中断处理函数,初始化RTC,然后注册RTC设备。Pxa-rtcRTC的一个种实现,它并不直接暴露给用户空间,而是在rtc.c中以标准的接口/dev/rtc提供给应用程序使用。

542staticintpxa_rtc_remove(structdevice *dev)
543{
544unregister_rtc(&pxa_rtc_ops);
545
546#ifdef SOFT_IRQP
547free_irq (IRQ_OST1,NULL);
548#endif
549free_irq(IRQ_RTCAlrm,NULL);
550free_irq(IRQ_RTC1Hz,NULL);
551return0;
552}

注销RTC,注销中断处理函数。

568staticintpxa_rtc_suspend(structdevice *dev, pm_message_t state, u32 level)
569{
570structrtc_time tm;
571structtimespec time;
572
573if(level == SUSPEND_POWER_DOWN) {
574memset(&time,0,sizeof(structtimespec));
575
576pxa_rtc_gettime(&tm);
577rtc_tm_to_time(&tm, &time.tv_sec);
578save_time_delta(&pxa_rtc_delta, &time);
579}
580
581return0;
582}
583
584staticintpxa_rtc_resume(structdevice *dev, u32 level)
585{
586structrtc_time tm;
587structtimespec time;
588
589if(level == RESUME_POWER_ON) {
590memset(&time,0,sizeof(structtimespec));
591
592pxa_rtc_gettime(&tm);
593rtc_tm_to_time(&tm, &time.tv_sec);
594restore_time_delta(&pxa_rtc_delta, &time);
595}
596
597return0;
598}

电源管理函数,这里要注意的是,这里的saverestore并非两个相反的动作,save是保存当前系统时间与RTC时间的差值,而restore是用上次保存的时间差值和RTC的时间来恢复当前系统时间。

604staticstructdevice_driver pxa_rtc_drv = {
605name:"pxa-rtc",
606.bus= &platform_bus_type,
607.probe= pxa_rtc_probe,
608.remove = pxa_rtc_remove,
609.suspend= pxa_rtc_suspend,
610.resume = pxa_rtc_resume,
611};
612
613staticint__init pxa_rtc_init(void)
614{
615intret;
616ret = driver_register(&pxa_rtc_drv);
617if(ret) {
618printk(KERN_ERR"rtc: register error.\n");
619}
620printk(KERN_INFO"PXA Real Time Clock driver v"DRIVER_VERSION"\n");
621return0;
622}
623
624staticvoid__exit pxa_rtc_exit(void)
625{
626driver_unregister(&pxa_rtc_drv);
627}

注册/注销设备驱动程序。

~~end~~

分享到:
评论

相关推荐

    pxa270-rtc.rar_270_RTC_pxa27_pxa270_pxa270 sd

    《PXA270 RTC驱动源代码解析》 在嵌入式系统开发中,RTC(Real-Time Clock)是至关...通过对pxa270-rtc.c源代码的深入分析和实践,开发者可以掌握如何为PXA270处理器定制和优化RTC驱动,确保系统的时钟功能稳定可靠。

    pxa270-rtc.rar_pxa270 rtc

    《PXA270 RTC:嵌入式系统中的实时时钟..."pxa270-rtc.c"文件的代码为我们提供了实现这一过程的具体示例,通过深入学习和理解,开发者可以更好地掌控PXA270平台的RTC功能,为各种嵌入式应用提供精确可靠的时钟服务。

    LCD.rar_PXA270-s linux_pxa_pxa270 LCD linux _pxa270 lcd_visual c

    这个主题涉及的“LCD.rar_PXA270-s_linux_pxa_pxa270_LCD_linux_pxa270_lcd_visual_c”压缩包,明显是关于基于PXA270处理器的Linux系统下LCD(液晶显示器)驱动程序的资源集合。现在,我们将深入探讨其中涉及的关键...

    RTC.rar_RTC_pxa270

    深入研究这个驱动代码,开发者可以学习如何与PXA270的RTC硬件接口交互,了解如何编写兼容Linux内核的RTC驱动,以及如何优化嵌入式系统的电源管理。这对于那些需要在PXA270平台上开发需要精确时间同步的应用,如...

    kernel-headers-sa-2.4.19-rmk6-pxa1-hh5.tar.gz

    标题中的"kernel-headers-sa-2.4.19-rmk6-pxa1-hh5.tar.gz"是一个Linux内核头文件包,主要用于开发和编译针对特定硬件平台的Linux应用程序或驱动程序。这个包是基于2.4.19版本的Linux内核,这是一个比较旧但仍然在...

    pxa27x.rar_aka

    通过对压缩包内的pxa27x.c和pxa27x.h两个文件的解析,我们将揭示PXA27x处理器与Linux内核之间的交互机制。 PXA27x处理器,由Marvell公司生产,是XScale微架构系列的一部分,广泛应用于嵌入式系统,如移动设备、工业...

    基于SPI接口wifi8686无线网卡的Linux驱动

    综合以上信息,我们可以了解到这是一个为Linux 2.6内核的PXA270平台开发的SPI接口8686无线网卡驱动程序,涉及到驱动的编译、安装、测试和性能分析等方面。开发人员或系统集成者需要阅读提供的PDF文档来获取详细信息...

    rtc.rar_pxa255_visual c

    标题中的"rtc.rar_pxa255_visual c"暗示了这是一个与RTC(实时时钟)相关的项目,使用了PXA255处理器,并且开发环境是Visual C++。描述进一步指出,这是CODEWARRIOR(一种集成开发环境,IDE)的源代码,用于实现RTC...

    2.4.18-rmk7-pxa1-XSBase.tar.gz

    总结起来,“2.4.18-rmk7-pxa1-XSBase.tar.gz”是一个针对老款Marvell PXA1处理器的Linux内核版本,它体现了Linux内核的可定制性和灵活性。尽管如今的Linux内核已经发展到5.x系列,但回顾这些历史版本,我们可以更好...

    嵌入式处理器------PXA255开发平台----09浙江大学.ppt

    3. **集成性强**:PXA255包含内置的MMU(内存管理单元),支持复杂的操作系统如Windows CE和Linux,并且集成了多种外围接口,如USB、以太网、串行口等,方便系统集成。 4. **多媒体支持**:XScale架构增强了对多媒体...

    EELIOD-LINUX.rar_EELIOD_eeliod.tar.gz_linux wifi_pxa270

    《EELIOD-LINUX:Linux下PXA270 WiFi驱动与测试程序详解》 EELIOD-LINUX.rar是一款专为EELIOD PXA270开发板设计的软件资源包,其中包含了针对Linux操作系统的WiFi驱动程序以及相关的测试程序。PXA270是Marvell公司...

    基于Marvell ARM ? XScale ? PXA270M处理器的PXA270M.zip

    Marvell ARM ? XScale ? PXA270M是一款高性能、低功耗的微处理器,广泛应用于嵌入式系统和移动设备中。...通过仔细研究这些材料,开发者可以充分利用PXA270M的潜力,构建出高效、可靠的嵌入式解决方案。

    linux-2.6.26下开发marvell-88w8686-wifi驱动.docx

    Linux 2.6.26 下开发 Marvell 88W8686 WiFi 驱动 本文档详细介绍了在 Linux 2.6.26 平台下开发 Marvell 88W8686 WiFi 驱动的过程。该驱动程序基于 PXA270 平台的 SPI 接口驱动程序,并移植到 2440 平台上。整个移植...

    嵌入式Linux系统--003pxa270开发板的使用.ppt

    嵌入式Linux系统--003pxa270开发板的使用.ppt

    clock-pxa2xx.rar_The Common

    可能包含了对PXA2xx处理器特有的时钟源、时钟门控和频率切换的代码。 通过分析这两个源文件,我们可以深入了解ChipIdea驱动如何与PXA2xx处理器的时钟硬件交互,以及如何利用通用的结构和函数来实现高效且灵活的时钟...

    rtc.rar_RTC_RTC wince_ds1672_wince rtc

    在"rtc"这个压缩包内的文件可能是RTC驱动的源代码、编译后的驱动程序、配置文件或者是用于测试RTC功能的工具。通过分析这些文件,开发者可以了解如何实现DS1672与PXA270处理器的接口,以及如何在WinCE系统上部署和...

    AIK-Linux工具

    signed boot.img files, Samsung/Spreadtrum DHTB header signed boot.img files, the Samsung/Marvell PXA1088/1908 board boot.img variant (AOSP-PXA), Loki patched boot.img files, Sony SIN signed/packaged ...

    基于PXA270-Linux的智能家居系统研究.pdf

    《基于PXA270-Linux的智能家居系统研究》这篇文章探讨了利用PXA270处理器和Linux操作系统设计智能家居网络系统的方法。PXA270是Marvell公司的一款高性能、低功耗的微处理器,常用于嵌入式系统,而Linux则因其开源、...

    PXA270-EP_Linux.rar_pxa270_pxa270-

    《PXA270-EP_Linux.rar_pxa270_pxa270-》这个压缩包文件主要聚焦于嵌入式系统中Linux的使用和实践,其中包含的两个关键元素是“PXA270”处理器和与之相关的Linux系统。下面将详细解析这两个核心概念,并结合压缩包内...

Global site tag (gtag.js) - Google Analytics