嵌入式Linux系统中实时时钟驱动的设计
冯豪,李瑞
(天地(常州)自动化股份有限公司,江苏常州 213015)
摘要:提出了嵌入式Linux系统下实时时钟驱动的设计方法,介绍了字符设备驱动开发架构和实时时钟芯片X1226,阐述了该芯片驱动的实现过程。实际应用中取得良好的效果。
关键词:Linux; 实时时钟; 驱动程序
中图分类号: 文献标识码:
Design of Real-time Clock Driver under Embedded Linux System
Li Rui
(Tiandi (Changzhou) Automation Co. , Ltd. , Changzhou 213015, China)
Abstract:The paper proposed a design method of real-time clock driver under embedded Linux system, introduced character device driver framework and real-time clock chip X1226, and described the chip driver realization process. The application showed good results.
Key words: Linux, real-time clock, driver
0 引言
嵌入式Linux操作系统为实时时钟开发提供了方便。Linux系统具有开源、稳定、可移植等优点,其驱动程序是一个个独立并且完全隐藏了设备的工作细节,向应用程序提供了一组独立于驱动程序的标准化的调用[1]。
1 驱动程序数据结构
应用程序通过下列数据结构实现系统调用[1][2]:
struct file_operations {
struct module *owner;
ssize_t (*read) (struct file *,char *,size_t, loff_t *);
ssize_t (*write) (struct file *,const char *,size_t, loff_t *);
int (*open) (struct inode *, struct file *);
int (*release) (struct inode *, struct file *);
…}
open()
在Linux或应用程序使用设备前都会调用驱动程序的这个方法。
release()
当Linux或应用程序不再使用设备时会调用驱动程序的这个方法。
read()
Linux或应用程序会调用驱动程序的read()方法从字符设备中读取数据。
write()
Linux或应用程序会调用驱动程序的write()方法写多个字节数据到字符设备中。
2 硬件电路
实时时钟硬件电路如图所示。

图1 实时时钟硬件电路
控制芯片采用PXA270,该芯片基于ARMV5TE架构[3],便于Linux系统的移植。PXA270与X1226两线通信。B1提供后备电源。OSC提供精准的32.768kHz的时钟。
3 实时时钟芯片介绍
实时时钟芯片X1226[4]带有时钟、 日历、两路查询报警、振荡器补偿和后备电池切换。芯片上集成了补偿和调整元件,节省了空间和成本。振荡器采用一个外部、低成本的32.768kHz晶振。时钟控制寄存器(CCR)有SR(状态寄存器)、Y2K(世纪)、DW(周)、YR(年)、MO(月)、DT(日)、HR(时)、MN(分)、SC(秒)等。
X1226支持双向总线协议,采用两线接口:串行时钟(SCL)、串行数据(SDA)。该协议有4种形式的信号:
数据 当SCL为低电平时,SDA上的数据才能改变。
开始 当SCL为高电平时,SDA由高电平变为低电平。
停止 当SCL为高电平时,SDA由低电平变为高电平。
应答 应答用来表示数据传送成功。X1226将SDA拉为低电平。
以这4种信号为基础,可以组成两种功能:写操作和读操作。
写操作 向CCR写入一个字节数据时,先发送开始信号,再发送数据信号0xDE、CCR地址高位、低位、写入的一个字节数据,分别会收到应答信号,然后发送停止信号。
读操作 向CCR读取一个字节数据时,先发送开始信号,再发送数据信号0xDE、CCR地址高位、低位,分别会收到应答信号,再次发送开始信号,发送数据信号0xDF,会收到应答信号,接着读取一个字节数据,然后发送停止信号。
4 驱动程序实现过程
(1)控制芯片的寄存器映射 寄存器GPDR3、GPSR3、GPCR3、GPLR3的物理地址通过函数ioremap()映射到操作系统内核虚拟地址。
(2)实现4种信号的程序:数据信号程序、开始信号程序、停止信号程序、应答信号程序。
(3)写操作功能程序和读操作功能程序。
(4)基于Linux字符驱动程序框架,完成以下程序:
open和release分别调用宏MOD_INC_USE_COUNT和MOD_DEC_USE_COUNT增加和减少驱动程序的使用计数。
read调用读操作功能程序,读取秒、分、时、日、月、年、周、世纪到内核数据区,再传递给用户数据区。
write程序流程图如图2所示。
(5)驱动程序的初始化函数module_init()用来注册主设备号、设备名称、file_operations结构指针。

图2 write程序流程图
(6)module_exit卸载注册的驱动程序。
以上过程中要注意总线时序关系和GPIO118输入输出方向的改变。如SDA上的信号改变之后延时300nS,SCL上的信号再改变。
5 结语
本文介绍了实时时钟X1226在嵌入式Linux系统中驱动程序设计,给出了硬件电路图和驱动程序的实现过程,并成功移植到了嵌入式系统中。该驱动在实际应用中取得了良好的效果。
参考文献:
[1] Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini. Linux Device Drivers[M]. 3rd Edition. O'Reilly,2005.1,49-53.
[2] 周立功,陈明计,陈渝.ARM嵌入式Linux系统构建与驱动开发范例[M].北京:北京航空航天大学出版社,2006.112-122.
[3] Marvell Semiconductor, Inc. Marvell® PXA27x Processor Family Developer’s Manual[EB/OL]. [2010—09—10]. http://www.marvell.com/application-processors/pxa-family/assets/pxa_27x_dev_man.pdf.
[4]Intersil Corporation. X1226 Datasheet[EB/OL]. [2010—09—10]. http://www.intersil.com/data/fn/fn8098.pdf.
作者简介:冯豪(1982-),男,助理工程师,2005年毕业于河南理工大学,现主要从事煤矿电气产品的设计与开发工作。