android修改rtc时间,RTC 时间设置

MMI

|

|

alarm.c----alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)--case ANDROID_ALARM_SET_RTC:

|

|

interface.c----rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);

|

|

V

rtc-m41t94.c---- m41t94_set_time(struct device *dev, struct rtc_time *tm)

static long alarm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

;

;

case ANDROID_ALARM_SET_RTC:

if (copy_from_user(&new_rtc_time, (void __user *)arg,

sizeof(new_rtc_time))) {

rv = -EFAULT;

goto err1;

}

rtc_time_to_tm(new_rtc_time.tv_sec, &rtc_new_rtc_time);

ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_IO,

"set rtc %ld %ld - rtc %02d:%02d:%02d %02d/%02d/%04d/n",

new_rtc_time.tv_sec, new_rtc_time.tv_nsec,

rtc_new_rtc_time.tm_hour, rtc_new_rtc_time.tm_min,

rtc_new_rtc_time.tm_sec, rtc_new_rtc_time.tm_mon + 1,

rtc_new_rtc_time.tm_mday,

rtc_new_rtc_time.tm_year + 1900);

mutex_lock(&alarm_setrtc_mutex);

spin_lock_irqsave(&alarm_slock, flags);

for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)

hrtimer_try_to_cancel(&alarm_timer[i]);

getnstimeofday(&tmp_time);

elapsed_rtc_delta = timespec_sub(elapsed_rtc_delta,

timespec_sub(tmp_time, new_rtc_time));

spin_unlock_irqrestore(&alarm_slock, flags);

rv = do_settimeofday(&new_rtc_time);

spin_lock_irqsave(&alarm_slock, flags);

for (i = 0; i < ANDROID_ALARM_SYSTEMTIME; i++)

alarm_start_hrtimer(i);

spin_unlock_irqrestore(&alarm_slock, flags);

if (rv < 0) {

ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS,

"Failed to set time/n");

mutex_unlock(&alarm_setrtc_mutex);

goto err1;

}

rv = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);

spin_lock_irqsave(&alarm_slock, flags);

alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;

wake_up(&alarm_wait_queue);

spin_unlock_irqrestore(&alarm_slock, flags);

mutex_unlock(&alarm_setrtc_mutex);

if (rv < 0) {

ANDROID_ALARM_DPRINTF(ANDROID_ALARM_PRINT_ERRORS,

"Failed to set RTC, time will be lost on reboot/n");

goto err1;

}

break;

}

android RTC 时间设置,

1,用户设置时间,MMI通过ioctrl命令调用,

2,内核执行alarm_ioctl的

case ANDROID_ALARM_SET_RTC:

3,

将用户空间的时间参数通过copy_from_user取出。为绝对的秒保持在new_rtc_time.tv_sec

4,通过rtc_time_to_tm(new_rtc_time.tv_sec, &rtc_new_rtc_time);将绝对的秒转换为年月日时分秒格式放到rtc_new_rtc_time

struct rtc_time {

int tm_sec;

int tm_min;

int tm_hour;

int tm_mday;

int tm_mon;

int tm_year;

int tm_wday;

int tm_yday;

int tm_isdst;

};

5,  因为要对RTC操作,要用mutex_lock(&alarm_setrtc_mutex);加锁

要清除alarm,要用 spin_lock_irqsave(&alarm_slock, flags);加锁

getnstimeofday(&tmp_time);获得ns级的时间

然后可调用do_settimeofday同步系统时钟:

通过函数

rv = rtc_set_time(alarm_rtc_dev, &rtc_new_rtc_time);

调用interface.c 的

err = mutex_lock_interruptible(&rtc->ops_lock);

err = rtc->ops->set_time(rtc->dev.parent, tm);

mutex_unlock(&rtc->ops_lock);

调用硬件RTC的驱动

static const struct rtc_class_ops m41t94_rtc_ops = {

.read_time = m41t94_read_time,

.set_time = m41t94_set_time,

};

的m41t94_set_time设置到硬件RTC芯片

spin_lock_irqsave(&alarm_slock, flags);

alarm_pending |= ANDROID_ALARM_TIME_CHANGE_MASK;

wake_up(&alarm_wait_queue);

spin_unlock_irqrestore(&alarm_slock, flags);  释放原来申请的锁

mutex_unlock(&alarm_setrtc_mutex);   释放原来申请的锁

因为时间改了。唤醒alarm队列,释放原来申请的锁alarm_slock和alarm_setrtc_mutex