打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
HOW TO: 修改RTC时钟

转载:http://blog.csdn.net/yasin_lee/article/details/5657143

问题:通过调用linux 中的time.h中定义的库函数(gettimeofday & settimeofday)去获取和设置系统时间后,发现在i850设备重新启动后,我做的时间修改全部作废了。

 

原因:linux中的时间有两个,RTC时间 和 系统时间

 

系统时间是每次在系统启动过程中通过读取RTC时钟获得的,此后我们看到的系统显示时间既是这个系统时间,我们通过库函数去读取和修改的也是这个系统时间,这意味着RTC时间根本没有被修改,所以导致系统每次启动读取的时间都不是我们曾经设置的。

 

解决:直接在kernel中改时间!

  1. //file path : /home/cpp/r7_new/kernel_imx/drivers/rtc/rtc-mc13892.c  
  2. /* 
  3.  * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved. 
  4.  */  
  5. /* 
  6.  * The code contained herein is licensed under the GNU General Public 
  7.  * License. You may obtain a copy of the GNU General Public License 
  8.  * Version 2 or later at the following locations: 
  9.  * 
  10.  * http://www.opensource.org/licenses/gpl-license.html 
  11.  * http://www.gnu.org/copyleft/gpl.html 
  12.  */  
  13. #include <linux/rtc.h>  
  14. #include <linux/module.h>  
  15. #include <linux/platform_device.h>  
  16. #include <linux/pmic_status.h>  
  17. #include <linux/pmic_external.h>  
  18. #define RTC_TIME_LSH        0  
  19. #define RTC_DAY_LSH     0  
  20. #define RTCALARM_TIME_LSH   0  
  21. #define RTCALARM_DAY_LSH    0  
  22. #define RTC_TIME_WID        17  
  23. #define RTC_DAY_WID     15  
  24. #define RTCALARM_TIME_WID   17  
  25. #define RTCALARM_DAY_WID    15  
  26. static unsigned long rtc_status;  
  27. static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm);  
  28. static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm);  
  29. static int mxc_rtc_open(struct device *dev)  
  30. {  
  31.     if (test_and_set_bit(1, &rtc_status))  
  32.         return -EBUSY;  
  33.     return 0;  
  34. }  
  35. static void mxc_rtc_release(struct device *dev)  
  36. {  
  37.     clear_bit(1, &rtc_status);  
  38. }  
  39. static void print_rtc_status(struct rtc_time *tm)  
  40. {  
  41.     printk("rtc_time/t: %02d:%02d:%02d/n",  
  42.            tm->tm_hour, tm->tm_min, tm->tm_sec);  
  43.     printk("rtc_date/t: %04d-%02d-%02d/n",  
  44.            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);  
  45. }  
  46. static int mxc_rtc_ioctl(struct device *dev, unsigned int cmd,  
  47.              unsigned long arg)  
  48. {  
  49.     int ret = -1;  
  50.     struct rtc_time tm;  
  51.     switch (cmd) {  
  52.     case RTC_AIE_OFF:  
  53.         pr_debug("alarm off/n");  
  54.         CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0x100000, 0x100000));  
  55.         return 0;  
  56.     case RTC_AIE_ON:  
  57.         pr_debug("alarm on/n");  
  58.         CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0, 0x100000));  
  59.         return 0;  
  60. //****************************************************************************************  
  61. //add this code for calling RTC clock setting function  
  62.     case 1314:  
  63.         rtc_time_to_tm(arg, &tm);  
  64.         ret = mxc_rtc_set_time(dev, &tm);  
  65.         if(0==ret) {  
  66.             printk("RTC setting SUCCESS/n");  
  67.             ret = mxc_rtc_read_time(dev, &tm);  
  68.             if(0==ret) {  
  69.                 printk("the current RCT time is :/n");  
  70.                 print_rtc_status(&tm);  
  71.             }  
  72.             return 0;  
  73.         }  
  74.         else  
  75.             printk("RTC set time ERROR/n");  
  76. //****************************************************************************************  
  77.     }  
  78.     return -ENOIOCTLCMD;  
  79. }  
  80. static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)  
  81. {  
  82.     unsigned int tod_reg_val = 0;  
  83.     unsigned int day_reg_val = 0, day_reg_val2;  
  84.     unsigned int mask, value;  
  85.     unsigned long time;  
  86.     do {  
  87.         mask = BITFMASK(RTC_DAY);  
  88.         CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));  
  89.         day_reg_val = BITFEXT(value, RTC_DAY);  
  90.         mask = BITFMASK(RTC_TIME);  
  91.         CHECK_ERROR(pmic_read_reg(REG_RTC_TIME, &value, mask));  
  92.         tod_reg_val = BITFEXT(value, RTC_TIME);  
  93.         mask = BITFMASK(RTC_DAY);  
  94.         CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));  
  95.         day_reg_val2 = BITFEXT(value, RTC_DAY);  
  96.     } while (day_reg_val != day_reg_val2);  
  97.     time = (unsigned long)((unsigned long)(tod_reg_val &  
  98.                            0x0001FFFF) +  
  99.                    (unsigned long)(day_reg_val * 86400));  
  100.     rtc_time_to_tm(time, tm);  
  101.     return 0;  
  102. }  
  103. static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)  
  104. {  
  105.     unsigned int tod_reg_val = 0;  
  106.     unsigned int day_reg_val, day_reg_val2 = 0;  
  107.     unsigned int mask, value;  
  108.     unsigned long time;  
  109.     if (rtc_valid_tm(tm))  
  110.         return -1;  
  111.     rtc_tm_to_time(tm, &time);  
  112.     tod_reg_val = time % 86400;  
  113.     day_reg_val = time / 86400;  
  114.     do {  
  115.         mask = BITFMASK(RTC_DAY);  
  116.         value = BITFVAL(RTC_DAY, day_reg_val);  
  117.         CHECK_ERROR(pmic_write_reg(REG_RTC_DAY, value, mask));  
  118.         mask = BITFMASK(RTC_TIME);  
  119.         value = BITFVAL(RTC_TIME, tod_reg_val);  
  120.         CHECK_ERROR(pmic_write_reg(REG_RTC_TIME, value, mask));  
  121.         mask = BITFMASK(RTC_DAY);  
  122.         CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));  
  123.         day_reg_val2 = BITFEXT(value, RTC_DAY);  
  124.     } while (day_reg_val != day_reg_val2);  
  125.     return 0;  
  126. }  
  127. static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)  
  128. {  
  129.     unsigned int tod_reg_val = 0;  
  130.     unsigned int day_reg_val = 0;  
  131.     unsigned int mask, value;  
  132.     unsigned long time;  
  133.     mask = BITFMASK(RTCALARM_TIME);  
  134.     CHECK_ERROR(pmic_read_reg(REG_RTC_ALARM, &value, mask));  
  135.     tod_reg_val = BITFEXT(value, RTCALARM_TIME);  
  136.     mask = BITFMASK(RTCALARM_DAY);  
  137.     CHECK_ERROR(pmic_read_reg(REG_RTC_DAY_ALARM, &value, mask));  
  138.     day_reg_val = BITFEXT(value, RTCALARM_DAY);  
  139.     time = (unsigned long)((unsigned long)(tod_reg_val &  
  140.                            0x0001FFFF) +  
  141.                    (unsigned long)(day_reg_val * 86400));  
  142.     rtc_time_to_tm(time, &(alrm->time));  
  143.     return 0;  
  144. }  
  145. static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)  
  146. {  
  147.     unsigned int tod_reg_val = 0;  
  148.     unsigned int day_reg_val = 0;  
  149.     unsigned int mask, value;  
  150.     unsigned long time;  
  151.     if (rtc_valid_tm(&alrm->time))  
  152.         return -1;  
  153.     rtc_tm_to_time(&alrm->time, &time);  
  154.     tod_reg_val = time % 86400;  
  155.     day_reg_val = time / 86400;  
  156.     mask = BITFMASK(RTCALARM_TIME);  
  157.     value = BITFVAL(RTCALARM_TIME, tod_reg_val);  
  158.     CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, value, mask));  
  159.     mask = BITFMASK(RTCALARM_DAY);  
  160.     value = BITFVAL(RTCALARM_DAY, day_reg_val);  
  161.     CHECK_ERROR(pmic_write_reg(REG_RTC_DAY_ALARM, value, mask));  
  162.     return 0;  
  163. }  
  164. struct rtc_drv_data {  
  165.     struct rtc_device *rtc;  
  166.     pmic_event_callback_t event;  
  167. };  
  168. static struct rtc_class_ops mxc_rtc_ops = {  
  169.     .open = mxc_rtc_open,  
  170.     .release = mxc_rtc_release,  
  171.     .ioctl = mxc_rtc_ioctl,  
  172.     .read_time = mxc_rtc_read_time,  
  173.     .set_time = mxc_rtc_set_time,  
  174.     .read_alarm = mxc_rtc_read_alarm,  
  175.     .set_alarm = mxc_rtc_set_alarm,  
  176. };  
  177. static void mxc_rtc_alarm_int(void *data)  
  178. {  
  179.     struct rtc_drv_data *pdata = data;  
  180.     rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);  
  181. }  
  182. static int mxc_rtc_probe(struct platform_device *pdev)  
  183. {  
  184.     struct rtc_drv_data *pdata = NULL;  
  185.     printk(KERN_INFO "mc13892 rtc probe start/n");  
  186.     pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);  
  187.     if (!pdata)  
  188.         return -ENOMEM;  
  189.     pdata->event.func = mxc_rtc_alarm_int;  
  190.     pdata->event.param = pdata;  
  191.     CHECK_ERROR(pmic_event_subscribe(EVENT_TODAI, pdata->event));  
  192.     device_init_wakeup(&pdev->dev, 1);  
  193.     pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,  
  194.                      &mxc_rtc_ops, THIS_MODULE);  
  195.     platform_set_drvdata(pdev, pdata);  
  196.     if (IS_ERR(pdata->rtc))  
  197.         return -1;  
  198.     printk(KERN_INFO "mc13892 rtc probe succeed/n");  
  199.     return 0;  
  200. }  
  201. static int __exit mxc_rtc_remove(struct platform_device *pdev)  
  202. {  
  203.     struct rtc_drv_data *pdata = platform_get_drvdata(pdev);  
  204.     rtc_device_unregister(pdata->rtc);  
  205.     CHECK_ERROR(pmic_event_unsubscribe(EVENT_TODAI, pdata->event));  
  206.     return 0;  
  207. }  
  208. static struct platform_driver mxc_rtc_driver = {  
  209.     .driver = {  
  210.            .name = "pmic_rtc",  
  211.            },  
  212.     .probe = mxc_rtc_probe,  
  213.     .remove = __exit_p(mxc_rtc_remove),  
  214. };  
  215. static int __init mxc_rtc_init(void)  
  216. {  
  217.     return platform_driver_register(&mxc_rtc_driver);  
  218. }  
  219. static void __exit mxc_rtc_exit(void)  
  220. {  
  221.     platform_driver_unregister(&mxc_rtc_driver);  
  222. }  
  223. module_init(mxc_rtc_init);  
  224. module_exit(mxc_rtc_exit);  
  225. MODULE_AUTHOR("*********");  
  226. MODULE_DESCRIPTION("MC13892 Realtime Clock Driver (RTC)");  
  227. MODULE_LICENSE("GPL");  
  228. //file end  
  229. //-------------------------------------------------------------------------------------  
  230. //file for test setting RTC:  
  231. /*编译:~/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc -Wall test_pty_static.c -o test_pty_static.exe -static -I /home/cpp/new_andriod/kernel_imx/include  */  
  232. #include <sys/types.h>  
  233. #include <sys/stat.h>  
  234. #include <stdio.h>  
  235. #include <stdlib.h>  
  236. #include <fcntl.h>  
  237. #include <errno.h>  
  238. #include <unistd.h>  
  239. #include <syslog.h>  
  240. #include <string.h>  
  241. #include <sys/wait.h>  
  242. int main()  
  243. {  
  244.     int     fd_rtc = -1;  
  245.     char    rtc_name[20] = "/dev/rtc0";  
  246.       
  247.     int ret = -1;  
  248.     struct timeval tv;  
  249.     struct tm;  
  250.       
  251.     fd_rtc = open(rtc_name, O_RDWR);  
  252.     if(0 > fd_rtc)  
  253.     {  
  254.         printf("/nERROR : open file  <%s>  FAILURE. now exit/n", rtc_name);  
  255.         return -1;  
  256.     }  
  257.     printf("/nopen file  <%s>  SUCCECC, FD = %d/n", rtc_name, fd_rtc);  
  258. //-----------------------     
  259.     ret = gettimeofday(&tv,NULL);  
  260.       
  261.     if(ret == -1) {  
  262.         printf("gettimeofday ERROR:  %s/n",strerror(errno));  
  263.     }  
  264.       
  265.     printf("we get the time:  %llu     %d   %s/n",tv.tv_sec, tv.tv_sec, ctime((time_t *)(&tv.tv_sec)));   
  266.       
  267.     tv.tv_sec+=5000;//改变时间  
  268.     printf("NOW we will set time to   %llu         %s/n", tv.tv_sec, ctime((time_t *)(&tv.tv_sec)));  
  269.       
  270.     ioctl(fd_rtc,1314,tv.tv_sec);  
  271.     close(fd_rtc);  
  272.     return 1;  
  273. }  

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
keypad driver
[z]pmic芯片lp3925驱动
__attribute__((packed))的作用
Linux RTC驱动分析(一)
linux内核中串口驱动注册过程(tty驱动)[转]
Linux设备驱动编程之中断处理
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服