HOW TO: 修改RTC时钟 rtc实时时钟

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

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

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

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

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

[cpp] view plaincopy

//filepath:/home/cpp/r7_new/kernel_imx/drivers/rtc/rtc-mc13892.c

/*

*Copyright2008-2009FreescaleSemiconductor,Inc.AllRightsReserved.

*/

/*

*ThecodecontainedhereinislicensedundertheGNUGeneralPublic

*License.YoumayobtainacopyoftheGNUGeneralPublicLicense

*Version2orlateratthefollowinglocations:

*

*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>

#defineRTC_TIME_LSH0

#defineRTC_DAY_LSH0

#defineRTCALARM_TIME_LSH0

#defineRTCALARM_DAY_LSH0

#defineRTC_TIME_WID17

#defineRTC_DAY_WID15

#defineRTCALARM_TIME_WID17

#defineRTCALARM_DAY_WID15

staticunsignedlongrtc_status;

staticintmxc_rtc_read_time(structdevice*dev,structrtc_time*tm);

staticintmxc_rtc_set_time(structdevice*dev,structrtc_time*tm);

staticintmxc_rtc_open(structdevice*dev)

{

if(test_and_set_bit(1,&rtc_status))

return-EBUSY;

return0;

}

staticvoidmxc_rtc_release(structdevice*dev)

{

clear_bit(1,&rtc_status);

}

staticvoidprint_rtc_status(structrtc_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);

}

staticintmxc_rtc_ioctl(structdevice*dev,unsignedintcmd,

unsignedlongarg)

{

intret=-1;

structrtc_timetm;

switch(cmd){

caseRTC_AIE_OFF:

pr_debug("alarmoff/n");

CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM,0x100000,0x100000));

return0;

caseRTC_AIE_ON:

pr_debug("alarmon/n");

CHECK_ERROR(pmic_write_reg(REG_RTC_ALARM,0,0x100000));

return0;

//****************************************************************************************

//addthiscodeforcallingRTCclocksettingfunction

case1314:

rtc_time_to_tm(arg,&tm);

ret=mxc_rtc_set_time(dev,&tm);

if(0==ret){

HOW TO: 修改RTC时钟 rtc实时时钟
printk("RTCsettingSUCCESS/n");

ret=mxc_rtc_read_time(dev,&tm);

if(0==ret){

printk("thecurrentRCTtimeis:/n");

print_rtc_status(&tm);

}

return0;

}

else

printk("RTCsettimeERROR/n");

//****************************************************************************************

}

return-ENOIOCTLCMD;

}

staticintmxc_rtc_read_time(structdevice*dev,structrtc_time*tm)

{

unsignedinttod_reg_val=0;

unsignedintday_reg_val=0,day_reg_val2;

unsignedintmask,value;

unsignedlongtime;

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=(unsignedlong)((unsignedlong)(tod_reg_val&

0x0001FFFF)+

(unsignedlong)(day_reg_val*86400));

rtc_time_to_tm(time,tm);

return0;

}

staticintmxc_rtc_set_time(structdevice*dev,structrtc_time*tm)

{

unsignedinttod_reg_val=0;

unsignedintday_reg_val,day_reg_val2=0;

unsignedintmask,value;

unsignedlongtime;

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);

return0;

}

staticintmxc_rtc_read_alarm(structdevice*dev,structrtc_wkalrm*alrm)

{

unsignedinttod_reg_val=0;

unsignedintday_reg_val=0;

unsignedintmask,value;

unsignedlongtime;

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=(unsignedlong)((unsignedlong)(tod_reg_val&

0x0001FFFF)+

(unsignedlong)(day_reg_val*86400));

rtc_time_to_tm(time,&(alrm->time));

return0;

}

staticintmxc_rtc_set_alarm(structdevice*dev,structrtc_wkalrm*alrm)

{

unsignedinttod_reg_val=0;

unsignedintday_reg_val=0;

unsignedintmask,value;

unsignedlongtime;

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));

return0;

}

structrtc_drv_data{

structrtc_device*rtc;

pmic_event_callback_tevent;

};

staticstructrtc_class_opsmxc_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,

};

staticvoidmxc_rtc_alarm_int(void*data)

{

structrtc_drv_data*pdata=data;

rtc_update_irq(pdata->rtc,1,RTC_AF|RTC_IRQF);

}

staticintmxc_rtc_probe(structplatform_device*pdev)

{

structrtc_drv_data*pdata=NULL;

printk(KERN_INFO"mc13892rtcprobestart/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"mc13892rtcprobesucceed/n");

return0;

}

staticint__exitmxc_rtc_remove(structplatform_device*pdev)

{

structrtc_drv_data*pdata=platform_get_drvdata(pdev);

rtc_device_unregister(pdata->rtc);

CHECK_ERROR(pmic_event_unsubscribe(EVENT_TODAI,pdata->event));

return0;

}

staticstructplatform_drivermxc_rtc_driver={

.driver={

.name="pmic_rtc",

},

.probe=mxc_rtc_probe,

.remove=__exit_p(mxc_rtc_remove),

};

staticint__initmxc_rtc_init(void)

{

returnplatform_driver_register(&mxc_rtc_driver);

}

staticvoid__exitmxc_rtc_exit(void)

{

platform_driver_unregister(&mxc_rtc_driver);

}

module_init(mxc_rtc_init);

module_exit(mxc_rtc_exit);

MODULE_AUTHOR("*********");

MODULE_DESCRIPTION("MC13892RealtimeClockDriver(RTC)");

MODULE_LICENSE("GPL");

//fileend

//-------------------------------------------------------------------------------------

//filefortestsettingRTC:

/*编译:~/gcc-4.1.2-glibc-2.5-nptl-3/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc-Walltest_pty_static.c-otest_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>

intmain()

{

intfd_rtc=-1;

charrtc_name[20]="/dev/rtc0";

intret=-1;

structtimevaltv;

structtm;

fd_rtc=open(rtc_name,O_RDWR);

if(0>fd_rtc)

{

printf("/nERROR:openfile<%s>FAILURE.nowexit/n",rtc_name);

return-1;

}

printf("/nopenfile<%s>SUCCECC,FD=%d/n",rtc_name,fd_rtc);

//-----------------------

ret=gettimeofday(&tv,NULL);

if(ret==-1){

printf("gettimeofdayERROR:%s/n",strerror(errno));

}

printf("wegetthetime:%llu%d%s/n",tv.tv_sec,tv.tv_sec,ctime((time_t*)(&tv.tv_sec)));

tv.tv_sec+=5000;//改变时间

printf("NOWwewillsettimeto%llu%s/n",tv.tv_sec,ctime((time_t*)(&tv.tv_sec)));

ioctl(fd_rtc,1314,tv.tv_sec);

close(fd_rtc);

return1;

}

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/83160.html

更多阅读

HowtobeagoodEnglishteacher? the english teacher

How to be a good Englishteacher?Abstract: In this paper, first, we havedescribed some of the qualities which good teachers possess;Second, we have investigated the kind of language teacher use withstudents; Third,

Howtopromotesales? howtopriest

How to promotesales?1. Launch a Web site. Web sites provide your company withworldwide exposure and give your customers convenient access toyour services and products. 2. Host a grand opening or hold a reception.

怎么申请国外博士后位置(资料杂记)-1 如何申请国外博士后

How to apply for postdoc positions.1.准备好基本的申请材料,主要有三样(1-3)(1)Cover Letter,也就是你申请时给老板时的email,或者是自荐信。自荐信非常的重要,它决定了老板会不会去看你的CV.会不会考虑你的申请。(2)一份CV,CV 是专门用来

丽莎·布鲁姆:如何与小女孩聊天译文及原文

如何与小女孩聊天作者:丽莎·布鲁姆原载:赫芬顿邮报·读书(链接:http://www.huffingtonpost.com/lisa-bloom/how-to-talk-to-little-gir_b_882510.html?ref=fb&amp;src=sp)翻译:Elysia(http://blog.sina.com.cn/elysiahaiyan)转载请著名

声明:《HOW TO: 修改RTC时钟 rtc实时时钟》为网友公子泺尘分享!如侵犯到您的合法权益请联系我们删除