转载:http://blog.csdn.net/yasin_lee/article/details/5657143
问题:通过调用linux 中的time.h中定义的库函数(gettimeofday & settimeofday)去获取和设置系统时间后,发现在i850设备重新启动后,我做的时间修改全部作废了。
原因:linux中的时间有两个,RTC时间 和 系统时间
系统时间是每次在系统启动过程中通过读取RTC时钟获得的,此后我们看到的系统显示时间既是这个系统时间,我们通过库函数去读取和修改的也是这个系统时间,这意味着RTC时间根本没有被修改,所以导致系统每次启动读取的时间都不是我们曾经设置的。
解决:直接在kernel中改时间!
- //file path : /home/cpp/r7_new/kernel_imx/drivers/rtc/rtc-mc13892.c
- /*
- * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
- */
- /*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
- #include <linux/rtc.h>
- #include <linux/module.h>
- #include <linux/platform_device.h>
- #include <linux/pmic_status.h>
- #include <linux/pmic_external.h>
- #define RTC_TIME_LSH 0
- #define RTC_DAY_LSH 0
- #define RTCALARM_TIME_LSH 0
- #define RTCALARM_DAY_LSH 0
- #define RTC_TIME_WID 17
- #define RTC_DAY_WID 15
- #define RTCALARM_TIME_WID 17
- #define RTCALARM_DAY_WID 15
- static unsigned long rtc_status;
- static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm);
- static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm);
- static int mxc_rtc_open(struct device *dev)
- {
- if (test_and_set_bit(1, &rtc_status))
- return -EBUSY;
- return 0;
- }
- static void mxc_rtc_release(struct device *dev)
- {
- clear_bit(1, &rtc_status);
- }
- static void print_rtc_status(struct rtc_time *tm)
- {
- printk("rtc_time/t: %02d:%02d:%02d/n",
- tm->tm_hour, tm->tm_min, tm->tm_sec);
- printk("rtc_date/t: %04d-%02d-%02d/n",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
- }
- static int mxc_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
- {
- int ret = -1;
- struct rtc_time tm;
- switch (cmd) {
- case RTC_AIE_OFF:
- pr_debug("alarm off/n");
- CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0x100000, 0x100000));
- return 0;
- case RTC_AIE_ON:
- pr_debug("alarm on/n");
- CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, 0, 0x100000));
- return 0;
- //****************************************************************************************
- //add this code for calling RTC clock setting function
- case 1314:
- rtc_time_to_tm(arg, &tm);
- ret = mxc_rtc_set_time(dev, &tm);
- if(0==ret) {
- printk("RTC setting SUCCESS/n");
- ret = mxc_rtc_read_time(dev, &tm);
- if(0==ret) {
- printk("the current RCT time is :/n");
- print_rtc_status(&tm);
- }
- return 0;
- }
- else
- printk("RTC set time ERROR/n");
- //****************************************************************************************
- }
- return -ENOIOCTLCMD;
- }
- static int mxc_rtc_read_time(struct device *dev, struct rtc_time *tm)
- {
- unsigned int tod_reg_val = 0;
- unsigned int day_reg_val = 0, day_reg_val2;
- unsigned int mask, value;
- unsigned long time;
- do {
- mask = BITFMASK(RTC_DAY);
- CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));
- day_reg_val = BITFEXT(value, RTC_DAY);
- mask = BITFMASK(RTC_TIME);
- CHECK_ERROR(pmic_read_reg(REG_RTC_TIME, &value, mask));
- tod_reg_val = BITFEXT(value, RTC_TIME);
- mask = BITFMASK(RTC_DAY);
- CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));
- day_reg_val2 = BITFEXT(value, RTC_DAY);
- } while (day_reg_val != day_reg_val2);
- time = (unsigned long)((unsigned long)(tod_reg_val &
- 0x0001FFFF) +
- (unsigned long)(day_reg_val * 86400));
- rtc_time_to_tm(time, tm);
- return 0;
- }
- static int mxc_rtc_set_time(struct device *dev, struct rtc_time *tm)
- {
- unsigned int tod_reg_val = 0;
- unsigned int day_reg_val, day_reg_val2 = 0;
- unsigned int mask, value;
- unsigned long time;
- if (rtc_valid_tm(tm))
- return -1;
- rtc_tm_to_time(tm, &time);
- tod_reg_val = time % 86400;
- day_reg_val = time / 86400;
- do {
- mask = BITFMASK(RTC_DAY);
- value = BITFVAL(RTC_DAY, day_reg_val);
- CHECK_ERROR(pmic_write_reg(REG_RTC_DAY, value, mask));
- mask = BITFMASK(RTC_TIME);
- value = BITFVAL(RTC_TIME, tod_reg_val);
- CHECK_ERROR(pmic_write_reg(REG_RTC_TIME, value, mask));
- mask = BITFMASK(RTC_DAY);
- CHECK_ERROR(pmic_read_reg(REG_RTC_DAY, &value, mask));
- day_reg_val2 = BITFEXT(value, RTC_DAY);
- } while (day_reg_val != day_reg_val2);
- return 0;
- }
- static int mxc_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
- {
- unsigned int tod_reg_val = 0;
- unsigned int day_reg_val = 0;
- unsigned int mask, value;
- unsigned long time;
- mask = BITFMASK(RTCALARM_TIME);
- CHECK_ERROR(pmic_read_reg(REG_RTC_ALARM, &value, mask));
- tod_reg_val = BITFEXT(value, RTCALARM_TIME);
- mask = BITFMASK(RTCALARM_DAY);
- CHECK_ERROR(pmic_read_reg(REG_RTC_DAY_ALARM, &value, mask));
- day_reg_val = BITFEXT(value, RTCALARM_DAY);
- time = (unsigned long)((unsigned long)(tod_reg_val &
- 0x0001FFFF) +
- (unsigned long)(day_reg_val * 86400));
- rtc_time_to_tm(time, &(alrm->time));
- return 0;
- }
- static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
- {
- unsigned int tod_reg_val = 0;
- unsigned int day_reg_val = 0;
- unsigned int mask, value;
- unsigned long time;
- if (rtc_valid_tm(&alrm->time))
- return -1;
- rtc_tm_to_time(&alrm->time, &time);
- tod_reg_val = time % 86400;
- day_reg_val = time / 86400;
- mask = BITFMASK(RTCALARM_TIME);
- value = BITFVAL(RTCALARM_TIME, tod_reg_val);
- CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM, value, mask));
- mask = BITFMASK(RTCALARM_DAY);
- value = BITFVAL(RTCALARM_DAY, day_reg_val);
- CHECK_ERROR(pmic_write_reg(REG_RTC_DAY_ALARM, value, mask));
- return 0;
- }
- struct rtc_drv_data {
- struct rtc_device *rtc;
- pmic_event_callback_t event;
- };
- static struct rtc_class_ops mxc_rtc_ops = {
- .open = mxc_rtc_open,
- .release = mxc_rtc_release,
- .ioctl = mxc_rtc_ioctl,
- .read_time = mxc_rtc_read_time,
- .set_time = mxc_rtc_set_time,
- .read_alarm = mxc_rtc_read_alarm,
- .set_alarm = mxc_rtc_set_alarm,
- };
- static void mxc_rtc_alarm_int(void *data)
- {
- struct rtc_drv_data *pdata = data;
- rtc_update_irq(pdata->rtc, 1, RTC_AF | RTC_IRQF);
- }
- static int mxc_rtc_probe(struct platform_device *pdev)
- {
- struct rtc_drv_data *pdata = NULL;
- printk(KERN_INFO "mc13892 rtc probe start/n");
- pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
- if (!pdata)
- return -ENOMEM;
- pdata->event.func = mxc_rtc_alarm_int;
- pdata->event.param = pdata;
- CHECK_ERROR(pmic_event_subscribe(EVENT_TODAI, pdata->event));
- device_init_wakeup(&pdev->dev, 1);
- pdata->rtc = rtc_device_register(pdev->name, &pdev->dev,
- &mxc_rtc_ops, THIS_MODULE);
- platform_set_drvdata(pdev, pdata);
- if (IS_ERR(pdata->rtc))
- return -1;
- printk(KERN_INFO "mc13892 rtc probe succeed/n");
- return 0;
- }
- static int __exit mxc_rtc_remove(struct platform_device *pdev)
- {
- struct rtc_drv_data *pdata = platform_get_drvdata(pdev);
- rtc_device_unregister(pdata->rtc);
- CHECK_ERROR(pmic_event_unsubscribe(EVENT_TODAI, pdata->event));
- return 0;
- }
- static struct platform_driver mxc_rtc_driver = {
- .driver = {
- .name = "pmic_rtc",
- },
- .probe = mxc_rtc_probe,
- .remove = __exit_p(mxc_rtc_remove),
- };
- static int __init mxc_rtc_init(void)
- {
- return platform_driver_register(&mxc_rtc_driver);
- }
- static void __exit mxc_rtc_exit(void)
- {
- platform_driver_unregister(&mxc_rtc_driver);
- }
- module_init(mxc_rtc_init);
- module_exit(mxc_rtc_exit);
- MODULE_AUTHOR("*********");
- MODULE_DESCRIPTION("MC13892 Realtime Clock Driver (RTC)");
- MODULE_LICENSE("GPL");
- //file end
- //-------------------------------------------------------------------------------------
- //file for test setting RTC:
- /*编译:~/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 */
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <unistd.h>
- #include <syslog.h>
- #include <string.h>
- #include <sys/wait.h>
- int main()
- {
- int fd_rtc = -1;
- char rtc_name[20] = "/dev/rtc0";
-
- int ret = -1;
- struct timeval tv;
- struct tm;
-
- fd_rtc = open(rtc_name, O_RDWR);
- if(0 > fd_rtc)
- {
- printf("/nERROR : open file <%s> FAILURE. now exit/n", rtc_name);
- return -1;
- }
- printf("/nopen file <%s> SUCCECC, FD = %d/n", rtc_name, fd_rtc);
- //-----------------------
- ret = gettimeofday(&tv,NULL);
-
- if(ret == -1) {
- printf("gettimeofday ERROR: %s/n",strerror(errno));
- }
-
- printf("we get the time: %llu %d %s/n",tv.tv_sec, tv.tv_sec, ctime((time_t *)(&tv.tv_sec)));
-
- tv.tv_sec+=5000;//改变时间
- printf("NOW we will set time to %llu %s/n", tv.tv_sec, ctime((time_t *)(&tv.tv_sec)));
-
- ioctl(fd_rtc,1314,tv.tv_sec);
- close(fd_rtc);
- return 1;
- }
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。