基于Linux设备模型的单总线接口的设计
2014-09-28王龙奇樊明辉陈丽红
王龙奇,樊明辉,陈丽红
(福州大学物理与信息工程学院,福建福州350000)
基于Linux设备模型的单总线接口的设计
王龙奇,樊明辉*,陈丽红
(福州大学物理与信息工程学院,福建福州350000)
单总线是一些传感器和低速器件与主机通信常用一种总线协议,如智能温度传感器DS18B20,A/D转换芯片等。随着物联网的发展,这些传感器的应用将越来越广泛,而这些接口没有与内核紧密联系,内核无法进行统一管理,稳定性和可靠性无法得到保证。在符合Linux内核设备模型[2]的前提下,实现一个稳定的单总线接口,将整个控制器分为顶层设备接口、核心层、底层硬件接口由上到下3个部分;同时对驱动和设备分离、顶层设备接口和具体硬件操作分离。
单总线;Linux;嵌入式系统;分层;分离
Linux系统以其开放、稳定、功能强大著称,在其内核源码中提供众多接口和协议的实现,其中包括PCI、USB、I2C、SPI等等,各种总线的实现都是基于内核的设备模型,具有稳定、功能丰富、扩展性强的优点。而单总线,由于其应用的特殊性——主要应用于EEPROM存储器控制、数字电位器控制、传感器控制、时钟控制等方面,Linux内核尚未提供总线的支持。而这些应用正渐渐成为许多完整系统不可或缺的一部分、如智能系统中传感器的控制,同步系统中同步时钟的获取等等,课题正是基于这种现状,遵循Linux内核的分层、分离思想,实现了一个符合Linux内核设备模型的单总线控制器。
1 单总线协议简介
单总线协议[3],即1-wire protocol,是 Dallas公司提出一种串行总线协议。与其他的串行总线如I2C、SPI类似,1-wire的命令、数据传输也是通过串行方式,但是1-wire具备了最少资源占用的优势,仅使用一根信号线,同时用于传输时钟、数据、命令,并且是双向传输。除此之外,它还具有成本低廉、可扩展性强、维护方便等特点。
单总线协议只适用于单主机场合,易于实现一主多从的网络连接,如常用的多点温度采集系统[4]。节点之间的识别通过一串64bit专用ID进行识别[5-6]。单总线协议还定义了单主单从的简单通信方式,主机不用发送识别码即可与从机进行通信。
单总线协议包含了3种最基本时序,即复位时序、写时序和读时序[7]。在3种基本时序的基础上,总线协议定义了寻址方式、命令传输方式、数据传输方式,这就是课题要实现的物理层部分。
2 系统结构
在linux内核中,几乎所有的设计都是基于模块化、分层、分离[8]等思想,在这些思想的指导下,以切合实际应用为出发点,课题实现了一种基于Linux设备模型的分层单总线控制器,它的整体原理框图如图1所示。
图1 单线总线协议实现的原理框图
2.1 物理层
在物理层中,本层向上层(核心层)屏蔽了下层通信线路的机械、电气特性等。机械特性主要是指总线连接的接口、外设的拓扑结构、引脚数量及其排列等。而电气特性规定了系统的供电范围、比特与电平的对应关系、比特流的组织方式等。该层最重要的功能是提供了硬件的操作接口,上层通过这些API实现了命令的传送和数据的收发,所以,对上层而言,下层是完全透明的,不需要直接参与底层物理特性的控制。
2.2 核心层
核心层是本系统最重要的一层,起到了承上启下的作用,包括了设备、设备驱动、通用API接口、适配器4个部分。
在完整的内核驱动中,Linux正是通过设备模型实现设备的统一管理——也就是在kobject、kset等底层内核对象的基础上,将设备device、设备驱动devive_driver和总线bus_type[9]以合适的方式组织在一起,它们的关系如图2所示。
总线是连接设备和设备驱动的媒介,当有新的设备接入时,系统自动匹配总线上挂载的所有驱动,一旦匹配成功就将设备和设备驱动进行绑定。这个过程比较繁琐,首先是总线注册后会在/sys文件系统下生成总线目录,相应地也会在该目录下创建devices、drivers两个目录,以及关于自动匹配和热插拔的一些属性文件。当一个设备驱动注册并匹配成功后,会在总线目录下的驱动目录生成关于这个设备驱动的属性文件和链接文件。设备注册会复杂一些,内核会先判断该设备是否指明父设备,是否指明所属类,也就是说至少存在4种组合,这里,设备都没有指定父设备,但指定了所属类,适配器所属的类是oneWire_adapter_class,单总线设备所属的类是oneWire_dev_class,那么设备注册之后,属性文件并不存在于总线目录,而是存在于类目录下,同时会创建总线到设备、设备到总线、设备到类等链接。总线目录如下所示。
图2 Linux的设备模型
设备目录如下所示:.
除了探测功能,总线和设备驱动还要承担设备删除、热插拔事件、电源控制等处理。设备删除完成的是与探测相反的工作,判断设备是否处于忙状态,如果忙则拒绝删除,只有当设备处于空闲状态才会完成删除操作,包括阻止设备的新请求、等待未执行请求、与绑定的驱动脱离、删除sys文件系统下的目录和节点。电源管理主要是指某些硬件设备支持多种工作模式,设备驱动的suspend和resume方法可以实现工作模式的切换,使设备进入休眠,或者恢复到正常工作状态。
2.3 设备层
设备层相对简单,主要是将底层的API封装成统一的文件接口提供给应用层。Linux下的设备一般可分为3类——字符设备、网络设备、块设备[10],每一种设备都有各自的应用场合和特点,差别比较大,这里单总线接口也属于字符设备,所以使用的是字符设备接口。字符设备通过一个核心结构体——file_operations封装所有接口函数原型,最新版的内核已经提供了25种操作接口,而事实上常用的只有不到10种,这里用到的包括:
(1)设备打开——oneWire_open,分配一个新的用户句柄,绑定适配器,同时将用户句柄也作为设备注册进内核由内核统一管理。
(2)设备关闭——oneWire_close,从内核中卸载用户句柄,将用户句柄和适配器分离,注销用户句柄。
(3)设备控制——oneWire_ioctl,用于除读写之外的一些特殊控制,比如复位、设置句柄标志等等。
(4)设备读——oneWire_read,用于从片外设备读取数据到应用层。
(5)设备写——oneWire_write,用于将应用层数据传输到片外设备。
2.4 应用层
应用层已经涉及到了应用程序的编写,并不是课题要讨论的部分,但考虑到系统的完整性,还是将其作为测试,用来验证系统设计的可行性,在最后一节展开介绍。
3 关键问题的解决
3.1 多用户句柄问题
课题设计的最终目标是要求能够在多用户态下正常使用,那就不可避免地会遇到这样的问题——不同用户下多应用程序同时打开设备的问题。课题采用了动态分配用户句柄的方式解决这个问题,每次有新的应用程序打开设备都会创建一个用户句柄,而适配器是共用的,新增加的用户句柄作为一个节点添加到适配器关于用户句柄的链表上,在驱动卸载时遍历所有句柄,处理所有请求。
3.2 多适配器问题
多适配器问题和多用户句柄问题不同,适配器包含具体外设信息,直接对外实现控制,是最接近外设的实际意义上的设备。每一个适配器都要求有一个次设备号,用于标识其对应的外设。这部分内容与平台相关,是驱动移植主要修改的部分。课题采用的解决方案是——用S3C2440的GPB作为单总线接口,GPB共有11个端口,也就是说可以有11个单总线接口,GPB0对应的次设备号为0,GPB1对应的次设备号为1,其他的类似。
3.3 互斥问题
在多用户句柄的情况下,适配器是共用的,这必然会产生互斥问题[11]。在Linux内核中,解决互斥问题的方法有自旋锁、信号量、原子操作、读写锁、顺序锁、RCU、完成事件等。每一种互斥机制根据自身的特点都有对应的应用场合。自旋锁主要应用于多处理器环境下,它不会引起睡眠,当锁已经被其他用户抢占,当前请求者会不断查询锁的保持者是否已经释放锁,这种特性避免了调用进程的挂起。信号量与自旋锁的功能类似,但是实现的办法完全不同,当请求者无法立即获得信号量时将直接进入睡眠,它允许并行访问,并行访问的数量在信号量被创建时初始化,即可以由多个内核同时控制该信号量,所以信号量不仅适用于单处理器,也适用于多处理器系统。原子量是最底层的控制方式,是一系列不可中断操作的集合,它的操作过程是封闭的,不可中断的,一般很少直接使用。读写锁的特性是对访问者进行区分,分为读者和写者,这类锁相对于自旋锁而言,它可以同时有多个读者进行读访问,而写者一个时刻只能有一个,也就是说读写锁同时只能有一个读者或者多个读者,但不能既有读者又有写者。完成事件,是基于资源保护而提出的,是一种简单的同步机制,可以实现简单休眠和唤醒,并且不会引起竞争。其他几种锁也各有优缺点。
基于上述介绍,课题的互斥机制采用的是自旋锁和完成事件。在适配器注册和卸载的时候采用自旋锁,防止有未完成的任务存在时设备被卸载,以及当有新的适配器加入时,访问设备链表发生冲突。用户句柄的添加删除到适配器关于用户句柄的链表,也需要自旋锁实现串行访问,因为任何时刻对于新添加的句柄,仅有一个可以访问到该链表,否则可能造成链表的添加和删除操作紊乱。设备卸载使用的互斥机制是完成事件,等待设备注销完成、删除sys文件系统下的属性文件以后,才允许退出设备卸载处理程序。
3.4 设备驱动、设备、总线的组织方式
设备驱动、设备、总线的组织方式最初只有一种方式,由设计者自行设计,也就是定义一种专用总线,而新的内核提供另一种组织方式,即平台设备。对应的总线称为平台总线,由设计者提供一些私有参数,通过平台设备结构体传入探测函数实现设备的注册和初始化。
3.4.1 专用总线
将相关的设备和驱动都挂载在专用总线上,这是传统方式。像I2C、SPI等总线都提供了这种方式,它的一个特点就是专用性,可以做到高效简洁,因为它负责专门的设备注册、驱动注册。多数设备都提供这种方式,课题的设计也提供了这种方式。
3.4.2 平台总线
平台总线是一种虚拟总线,相比于USB、PCI等专用总线,它主要用于描述片上资源,如LCD、看门狗等等,平台设备所描述的资源有一个共同点——允许总线直接寻址。它需要分配一些特殊的资源,如中断号、物理地址映射范围等等。当有新的设备或驱动注册时,内核会调用虚拟总线的探测函数,对分配到的资源进行初始化,注册到内核,从本质上说,平台设备只是标准设备一种扩展。课题在验证设计的正确与否采用就是这种组织方式。
4 验证
图3是基于ARM920T平台的外设连接方式,这里的验证仅取两条总线,每一条总线上挂载一个DS18B20[12]作为测试设备,在一个循环里每次轮流读取温度传感器传回的数据,并将其从二进制转为十进制显示(仅考虑正温度的情况)。二进制小数的提取采用的是比较原始的办法——查表法,因为DS18B20的小数只用4bit表示,也就是说只有16种取值,所以不会占用很大内存。
图3 外设拓扑图
得益于字符设备的统一接口,应用层的调用非常简单,只需要打开设备,就可以读写数据。而在退出程序时,关闭设备是必须的,这样才能释放不用的资源。测试程序比较简短,其主程序片段如下所示(注:未写出出错处理代码):
下面是程序运行结果,总共有4个模块需要加载,分别是核心模块、底层接口模块、设备接口模块、外设注册模块。当运行test程序时,就启动温度转换和采集,然后将采集的数据进行处理后打印到终端,温度的单位为开尔文,如23.2500+273.15K,表示当前环境温度为23.2500摄氏度。Sensor1、sensor2分别标识传感器1和传感器2,通过对比可以发现它们的采样还是有零点几度的偏差的。
[root@EmbedSkywlq1988]#insmod oneWire_core.ko.
[root@EmbedSkywlq1988]#insmod oneWire_s3c2440.ko.
[root@EmbedSkywlq1988]#insmod oneWire_dev.ko.
[root@EmbedSkywlq1988]#insmod oneWire_device.ko.
[root@EmbedSkywlq1988]#./test
ds18b20 test.
open success.
cureent temperature:sensor1:23.2500+273.15 K
cureent temperature:sensor1:23.3125+273.15 K
cureent temperature:sensor1:23.2500+273.15 K
cureent temperature:sensor2:23.3125+273.15 K
…
测试程序简单地验证了设计的正确性,这是两条总线一对一的情况。通过简单配置还可以实现挂载更多的设备,也就一对多,多对多的情况。
5 结语
课题实现了linux框架下的单总线控制器,整个设计利用linux内核的一些同步措施保障了系统运行的稳定性。同时,由于整个设计过程采用了分离、分层思想,所以,使用者只需对底层接口稍加修改即可实现移植,并将其嵌入到更多的嵌入式系统中,具有一定的实用意义。
[1]李正平,徐超,陈军宁.Linux 2.6内核设备模型分析[J].计算机技术与发展,2007,17(3):141-143.
[2]刘军卫,李曦,陈香兰.用户态驱动框架的研究与实现[J].计算机系统与应用,2011,20(11):67-71.
[3]冯国进.嵌入式Linux驱动程序设计从入门到精通[M].北京:清华大学出版社,2008:10-35.
[4]秦芹.一种基于DS18B2O的温度采集新方案[J].电子技术设计与运用,2010,37(37):62-64.
[5]张会新,龚进,樊姣荣.分布式数字无线测温系统[J].化工自动化及仪表,2011,38(12):1493-1495.
[6]任兵,任小洪,李国志.基于ARM-Linux的多路温度采集系统的设计[J].工业控制计算,2011,24(11):44-45.
[7]陈聪慧,苏伟达,蔡声镇.一种单总线接口时序分析仪的研制木[J].微计算机应用,2008,29(6):50-53.
[8]陈曦,吕湘晔,刘艳防.基于嵌入式Linux新型模块化工业控制器设计[J].仪表技术与传感器,2010(11):27-29.
[9]陈生翰,刘其洪,丁注.单总线数字温度传感器DS18B20自动识别的设计与实现[J].仪表技术与传感器,2010(5):16-18.
[10]舒克毅,胡荣强.嵌人式Linux字符设备驱动程序设计[J].仪表技术,2010(2):4-8.
[11]张祖昌,曾夏夏.互斥技术在嵌人式系统中的应用[J].闽江学院学报,2007,28(5):68-71.
[12]陈志英,李光辉.单总线(1-Wire Bus)技术及其应用[J].国外电子元器件,2003(8):4-7.
Imp lementation of 1-W ire Interface Based on Linux Devicemodel
WANG Longqi,FAN Minghui*,CHEN Lihong
(Department of Physics and Information Engineering,Fuzhou University,Fuzhou Fujian 350000,China)
1-Wire Bus is a bus protocol which connects some sensors and low-speed devices with the host,such as the smart temperature sensor DS18B20,A/D chip,and so on.With the developmentof the internetof things,the application of these sensorswill becomemore widespread,but their interfaces are not closely linked with the kernel,the kernel can not unify themanagement,so stability and reliabilitymay not be guaranteed.In linewith the premise of the Linux kernel devicemodel,a stable 1-Wire interface is given.the controller will be divided into three parts,top-level device interface,the core layer and the underlying hardware interface;menuwhile the driver and the device,the top-level device interface and the specific hardware are seperated in operations.
the 1-Wwire bus;Linux;embedded system;stratification;separation
10.3969/j.issn.1005-9490.2014.01.025
TP316.2 文献标识码:A 文章编号:1005-9490(2014)01-0103-05
2013-04-11修改日期:2013-05-20
EEACC:6150M
王龙奇(1988-)男,硕士研究生,主要研究方向为嵌入式系统设计,393146277@ qq.com;
樊明辉(1974-),男,副研究员,博士,主要研究方向为计算机应用和地理信息系统,fanmh@fzu.edu.cn。