时间:2024-05-04
朱海蕊
(中国矿业大学(北京) 机电与信息工程学院,北京 100083)
基于Linux的加速度传感器mma8653驱动程序的设计
朱海蕊
(中国矿业大学(北京) 机电与信息工程学院,北京 100083)
文章首先阐述了mma8653加速度传感器以及在应用中的优势,介绍了嵌入式Linux系统驱动程序的框架结构并分别介绍各层的作用,然后分析了IIC总线数据传输的时序、嵌入式Linux系统IIC设备驱动程序的设计,最后介绍了基于Linux的加速度传感器mma8653设备驱动程序的具体实现。
Linux;IIC总线;驱动程序;mma8653
加速度传感器是一类能够感知物体的加速度变化,并将其转变为可用输出信号的传感器。随着制造工艺的日益成熟和加速度测量技术的迅速发展,加速度传感器测量精度不断提高,广泛应用于智能手机、平板电脑、数码相机、便携式导航解决方案和医疗应用中。然而现有的采集平台大多考虑了高效稳定的数据采集传输,而忽略了应用中对芯片的尺寸和功耗的要求。
mma8653是飞思卡尔生产的加速度传感器,具有体积小、低功率、噪音低、运动精度高的特点。引脚兼容型Xtrinsic mma8652FC 12位和mma8653FC 10位加速计。适用于对功率和空间具有限制的移动器件。mma8653的工作电压1.95V-3.6V,支持IIC总线接口。
准确的加速度数据测量是嵌入式系统中重要的一点,在Linux操作系统下使用加速度传感器mma8653,不仅可以采集到高精度的数据,而且硬件简单可靠。
IIC(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,在嵌入式设备中得到广泛的应用[1]。IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。
Linux的IIC体系结构主要由3个部分构成,分别是IIC核心、IIC总线驱动和IIC设备驱动[2],其体系结构如图1所示。
IIC核心层作为IIC总线的驱动和设备驱动之间的纽带,提供了一组接口函数,这些接口函数不依赖于具体的硬件平台,其中包括IIC总线驱动和设备驱动的注册函数和注销函数等,IIC核心层提供的传输、发送和接受函数,可用来完成消息的读写。
IIC总线驱动是对IIC硬件体系结构中IIC控制器的实现,IIC控制器与CPU链接,受CPU的控制,IIC控制器可以直接集成在CPU的内部[3]。由IIC总线驱动控制的代码,可以控制IIC控制器以主动的方式产生IIC在通信过程中所必须开始位、停止位、读写周期,以及以从设备方式被读写,产生的应答信号(ACK)等。
图1 Linux中IIC体系结构
IIC设备驱动是对IIC体系结构中的设备端的实现,设备一般挂在受CPU控制的IIC控制器上[4],设备通过IIC控制器与CPU进行数据的传输,IIC设备层由IIC设备和对应的设备驱动组成。
mma8653采用设备-总线-驱动编程模型,内核定义一个虚拟总线i2c_bus_type,虚拟总线上维护着设备相关的硬件信息链表和设备相关的驱动的链表,其中设备相关的硬件信息链表描述的IIC外设的纯硬件信息,每一个节点的数据结构为struct i2c_client,设备相关的驱动的链表描述IIC外设的纯软件信息,每一个节点的数据结构为struct i2c_driver,驱动开发者只需用这两个数据结构定义初始化一个对象,然后向对应的链表添加,内核会调用match函数来比较硬件节点的name和软件节点的name进行匹配,如果匹配成功,内核会调用软件节点的probe函数,并把硬件节点的首地址传递给probe函数。
在ARM嵌入式系统IIC总线中,一般微处理器(如:S5P6818)是总线上的主机,其他是从机,IIC总线上可同时接多个从机,每个从机都有一个唯一的地址,主机负责IIC总线的初始化、数据传输、产生时钟信号等工作。IIC总线传输的时序如图2所示:在I2C总线传输过程中,将两种特定的情况定义为开始和停止条件:当SCL保持“高”时,SDA由“高”变为“低”为开始(START)条件;当SCL保持“高”且SDA由“低”变为“高”时为停止(STOP)条件。开始和停止条件均由主控制器产生。
SDA线上的数据在时钟“高”期间必须是稳定的,只有当SCL线上的时钟信号为低时,数据线上的“高”或“低”状态才可以改变。输出到SDA线上的每个字节必须是8位,每次传输的字节不受限制,但每个字节必须要有一个应答ACK。如果接收器件在完成其他功能(如内部中断)前不能接收另一数据的完整字节时,它可以保持时钟线SCL为低,以促使发送器进入等待状态;当接收器准备好接收数据的其他字节并释放时钟SCL后,数据传输继续进行。
2.1 IIC总线写操作时序
IIC总线写操作有二种方式:字节写和页面写。字节写是指:每次在指定位置写入一个字节数据,时序如图3(a)所示。首先CPU向总线发送START信号,然后CPU向总线上发送mma8653的设备地址和写位,表明CPU要将访问的片内寄存器地址告诉mma8653,如果外设存在于总线上,外设会在第九个时钟周期给CPU一个ACK应答信号;当应答信号来到之后再发一个器件内部地址,外设接收到要访问的片内寄存器以后,给CPU一个应答信号ACK;当应答信号来到之后立即发送数据,当下一个应答信号来到之后发送停止(STOP)信号。页面写和字节写操作很类似,只是主机在完成第一轮数据传送之后不发送停止信号,而继续发送数据,时序如图3(b)所示:IIC字节写和页面写所对应的函数分别是i2c_smbus_write_byte_data()和i2c_smbus_write_block_ data()。
2.2 IIC总线读操作时序
IIC总线读操作主要有2种方式:指定位置读和连续读。指定位置读时序如图4(a)所示,CPU首先向总线发送START信号,然后向总线上发送mma8653的设备地址和写位,如果设备存在于总线上,设备在第九个时钟周期给CPU发送一个ACK信号,CPU然后向外设发送要访问的片内寄存器的地址,外设给CPU发送一个ACK信号,CPU重发START信号,CPU继续重发外设的设备地址和读位,表明CPU要开始读取数据,外设继续给CPU一个ACK信号,外设最终将数据发送给CPU,CPU接收到数据,没有给外设一个有效的ACK信号,CPU数据读取操作完毕,最后发送STOP信号。连续读时序如图4(b)所示;IIC指定位置读和连续读所对应的函数分别是i2c_smbus_ read_byte_data()和i2c_smbus_read_block_data()。
Linux的内核是一个整体的内核,即所有的内核功能链接在一起,在同一个地址空间执行,如果新增加或去除一个硬件驱动,需要把原有的内核重新编译一遍,这样会带来很多不便和浪费。Linux操作系统提供内核模块机制来解决此问题。
模块是设备驱动程序,在编译内核时并没有以静态地方式链接进内核,而是被分别编译并链接成一组目标文件,以模块加载的方式加载进内核,或从正在运行的内核中被卸载[5]。这样保证了内核能达到最小,并且在使用的过程中非常灵活。
内核在运行insmod命令后由系统调用mma8653_init()函数,完成驱动模块的加载工作,在内核中完成各种函数的注册,在注册之后,应用程序调用函数时,内核将查表获得相应函数的位置并调用;运行rmmod命令后有系统调用mma8653_exit()函数,此时完成驱动模块卸载时的各种清理工作,把注册到内核中的函数卸载,mma8653_exit()函数必须把注册到内核的功能函数完全卸载,否则,再次调用此模块时,会因为有相同的函数名而导致调用失败。
图2 IIC总线数据传输时序
图3 IIC总线写数据时序
图4 IIC总线读数据时序
mma8653是由飞思卡尔公司开发的高性能、低功耗的三轴加速计,适用于对功率和空间具有限制的移动器件。mma8653采用IIC接口,体积小使用方便,mma8653的2、10脚分别和S5P6818的IIC控制的时钟(SCL)和数据管脚(SDA)连接,然后通过对S5P6818的控制器进行编程,以IIC的方式控制和访问mma8653,从而获得mma8653的三个轴向的加速度值。mma8653电路如图5所示。
mma8653驱动最终能否得以正常运行,获得实时温度值,关键在于能否正确地编写初始化硬件程序、读写操作的程序。
4.1 设备的初始化、退出处理模块
设备初始化模块的主要功能是:向内核注册设备节点,mma8653_init()函数执行的时候,函数i2c_add_ driver(&mma8653_drv)执行,如果i2c_ driver的id_ table中的name和client中的name匹配后,内核调用i2c_ driver_probe()函数,调用 mma8653_exit(void)会进行设备的卸载,具体函数实现如下。
图5 mma8653电路
4.2 初始化mma8653硬件程序
对mma8653进行操作之前要对采集数据的模式、采集数据的范围进行设置。IIC设备驱动调用SMBUS接口函数来操作IIC控制器,从而发起硬件的操作时序。
下面是初始化硬件程序代码:
4.3 读数据模块
Mma8653需要连续的读取加速度的数据值,具体实现的函数如下:
4.4 应用层接口函数
4.5 硬件信息
要向内核中添加mma8653的硬件相关的信息,内核根据硬件信息定义初始化硬件节点,具体代码如下:
本文采用设备—总线—驱动模型来编写mma8653驱动程序,采用模块化加载的方式来调试mma8653的驱动程序,mma8653采集数据的结果如图6所示。
图6 mma8653采集数据结果
[1]朱华生,叶军.嵌入式系统IIC设备驱动程序设计与实现[J].微计算机信息,2006(10):170-172.
[2]怯肇乾,吴志亮. ARM-Linux-IIC设备的添加与驱动[J].电脑编程技巧与维护,2012(15):14-18.
[3]李植,李哲,牟云飞.IIC总线在Linux下驱动程序的设计与实现[J].工业控制计算机,2015(5):16-18.
[4]何亚军,邓飞其.嵌入式Linux中I2C总线驱动程序设计[J].计算机工程与设计,2008(10):2517-2519,2522.
[5]董志国,李式巨.嵌入式Linux设备驱动程序开发[J].计算机工程与设计,2006(20):3737-3740.
Design of acceleration sensor mma8653 driver based on Linux
Zhu Hairui
(Mechatronics and Information Engineering College of China University of Mining and Technology(Beijing), Beijing 100083, China)
Firstly, this paper expounded the mma8653 acceleration sensor and its advantages in application.,and introduced the frame structure of the embedded Linux system driver and respectively introduced the role of each layer., and then analyzed the IIC bus data transmission sequence and the design of the embedded Linux system IIC device driver, fnally introduced the concrete implementation of the device driver of acceleration sensor mma8653 based on Linux.
Linux; IIC bus; drivers; mma8653
朱海蕊(1988— ),女,河南安阳,硕士;研究方向:计算机应用技术。
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!