开篇前,注意设置时间命令,开发时有用。
大家注意我们使用“date -s”命令仅仅是将当前系统时间设置了,此时间还没有写入到I.MX6U内部RTC里面或其他的RTC芯片里面,因此系统重启以后时间又会丢失。我们需要将当前的时间写入到RTC里面,这里要用到hwclock命令,输入如下命令将系统时间写入到RTC里面:
hwclock -w //将当前系统时间刷新写入到RTC里面
时间写入到RTC里面以后就不怕系统重启以后时间丢失了,如果I.MX6U-ALPHA开发板底板接了纽扣电池,那么开发板即使断电了时间也不会丢失。大家可以尝试一下不断电重启和断电重启这两种情况下开发板时间会不会丢失。
一、RTC驱动
一、硬件原理,裸机寄存器编程
二、RTC驱动框架及应用编程
60.1 Linux内核RTC驱动简介
RTC设备驱动是一个标准的字符设备驱动,应用程序通过open、release、read、write和ioctl等函数完成对RTC设备的操作,关于RTC硬件原理部分我们已经在裸机篇中的第二十五章进行了详细的讲解。
Linux内核将RTC设备抽象为rtc_device结构体,因此RTC设备驱动就是申请并初始化rtc_device,最后将rtc_device注册到Linux内核里面,这样Linux内核就有一个RTC设备的。至于RTC设备的操作肯定是用一个操作集合(结构体)来表示的,我们先来看一下rtc_device结构体,此结构体定义在include/linux/rtc.h文件中,结构体内容如下(删除条件编译):
示例代码60.1.1 rtc_device结构体
104 struct rtc_device
105 {
106 struct device dev; /* 设备 */
107 struct module *owner;
108
109 int id; /* ID */
110 char name[RTC_DEVICE_NAME_SIZE]; /* 名字 */
111
112 const struct rtc_class_ops *ops; /* RTC设备底层操作函数 */
113 struct mutex ops_lock;
114
115 struct cdev char_dev; /* 字符设备 */
116 unsigned long flags;
117
118 unsigned long irq_data;
119 spinlock_t irq_lock;
120 wait_queue_head_t irq_queue;
121 struct fasync_struct *async_queue;
122
123 struct rtc_task *irq_task;
124 spinlock_t irq_task_lock;
125 int irq_freq;
126 int max_user_freq;
127
128 struct timerqueue_head timerqueue;
129 struct rtc_timer aie_timer;
130 struct rtc_timer uie_rtctimer;
131 struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */
132 int pie_enabled;
133 struct work_struct irqwork;
134 /* Some hardware can't support UIE mode */
135 int uie_unsupported;
......
147 };
我们需要重点关注的是ops成员变量,这是一个rtc_class_ops类型的指针变量,rtc_class_ops为RTC设备的最底层操作函数集合,包括从RTC设备中读取时间、向RTC设备写入新的时间值等。因此,rtc_class_ops是需要用户根据所使用的RTC设备编写的,此结构体定义在include/linux/rtc.h文件中,内容如下:
示例代码60.1.2 rtc_class_ops结构体
71 struct rtc_class_ops {
72 int (*open)(struct device *);
73 void (*release)(struct device *);
74 int (*ioctl)(struct device *, unsigned int, unsigned long);
75 int (*read_time)(struct device *, struct rtc_time *);
76 int (*set_time)(struct device *, struct rtc_time *);
77 int (*read_alarm)(struct device *, struct rtc_wkalrm *);
78 int (*set_alarm)(struct