嵌入式Linux下SPI总线驱动程序设计

2017-07-19 11:30李传玺
电子科技 2017年8期
关键词:外设驱动程序内核

孙 帅,李传玺

(航天科工深圳集团有限公司 南京分公司,江苏 南京 211100)



嵌入式Linux下SPI总线驱动程序设计

孙 帅,李传玺

(航天科工深圳集团有限公司 南京分公司,江苏 南京 211100)

给出了一种提高软件使用效率的设计方法,以SPI驱动程序为例,通过外设和处理器相分离的设计思想,在外设模型和处理器模型之间增加一层虚拟总线,达到降低外设驱动与主机控制器驱动耦合的目的。实际测试结果表明,该方法实现了主机和外设任意组合的功能,具备较高的应用价值。

SPI总线;设备驱动; Linux; 嵌入式

Linux操作系统在嵌入式领域得到广泛的应用,不仅是因为良好的内核性能,更是展示了其在开源上的优势[1],使得符合驱动规范的外设器件,均能得到操作系统的有效支持。然而,由于外设器件种类繁多,且外设驱动和处理器结构相关[2-3],若驱动程序移植在不同的处理器上,将导致驱动软件存在多个版本,这给产品开发和系统维护带来了较大的困难。

为提高外设驱动程序的使用效率,降低设备驱动和处理器结构的耦合程度,本文以Linux设备驱动模型为基础,用设备和处理器相分离的思想设计串行外设接口SPI(Serial Peripheral Interface)驱动[4],在外设驱动和处理器驱动之间增加一层SPI虚拟总线,该总线对内对外隐藏了对端的不确定性,使得外设驱动与主机控制器驱动不相关,实现主机和外设任意组合的功能。最后通过嵌入式平台的测试,验证了该虚拟总线的隔离功能。

1 SPI虚拟总线结构

在Linux非总线结构的驱动中,用户应用程序访问SPI物理设备需要经过内核空间的相关调用[5],如图1中不含虚线部分。内核的设备协议驱动层需要了解外设的通信协议和数据结构,并负责SPI功能的具体实现[6]。而总线驱动结构则是以Linux设备驱动模型为基础[7],采用设备和处理器相分离的思想,在硬件设备和内核协议驱动之间增加一层SPI虚拟总线,分离出设备协议驱动层关于硬件的功能,如图1中的虚线部分。SPI总线由SPI核心接口层和SPI控制器驱动层组成。

图1 SPI虚拟总线结构

SPI核心接口层提供核心数据结构的相关定义、SPI控制器驱动和设备驱动的注册、注销管理等API[8]。其与具体的处理器平台无关:向下屏蔽了物理总线控制器的差异,规范统一的访问策略和接口参数;向上提供了统一的协议,以便内核空间的设备协议驱动层通过总线进行数据收发。SPI控制器驱动层负责将上层协议驱动的数据按SPI总线的时序要求发送给设备,并从设备收到的数据返回给上层的协议驱动[9]。SPI控制器驱动为系统中每条SPI总线实现相应的读写方法,同时负责管理具体的硬件资源,诸如DMA、中断向量等。

2 SPI总线驱动设计

2.1 SPI核心接口层

SPI核心接口层主要包含spi_master、spi_device和spi_driver这3个数据结构。spi_master结构用于表示SPI控制器,其规定了总线编号、控制器的片选信号、工作模式、消息链表以及消息队列[10];spi_device结构用于描述SPI设备,包括片选索引、数据单位、中断编号等信息;spi_driver结构则对应spi_device操作方法的实现[11]。当系统加载模块时,内核首先通过spi_register_master( )注册spi_master结构到系统中,然后调用spi_register_board_info( )将每个spi_board_info挂在全局链表变量上,以遍历已经注册到系统中的控制器,匹配相应的控制器并获取同名的spi_master结构指针,随后通过spi_new_device( )向系统增加SPI设备,最终调用spi_register_driver( )完成spi_driver的注册。

2.2 SPI控制器驱动层

SPI控制器驱动层主要包含platform_device和platform_devic[12]两个数据结构。在platform_device中定义了控制器所需的寄存器地址、DMA通道资源、中断编号和设备名称。其中,设备名称用于匹配相应的控制器驱动[13]。platform_device对应platform_device平台驱动的操作方法。以飞思卡尔IMX为例,在系统初始化阶段,SPI控制器以mxs-spi为名称通过mxs_get_device( )向系统注册平台设备[14],同时mxs_spi_init( )以mxs-spi为名称向系统添加平台驱动。平台总线匹配platform_device和platform_device,触发probe( )函数回调以完成SPI控制器的注册过程[15]。至此,连接内核设备协议和硬件外设的SPI虚拟总线创建完成。

2.3 SPI模型的初始化

在初始化阶段,spi_init( )向系统注册一个名为SPI的总线类型,同时为SPI控制器注册名为spi_master的设备类,使文件系统类型创建节点文件sys/bus/spi、sys/class/spi_master,表明SPI总线中spi_bus_type结构的match字段指向了spi_match_device( )函数,该函数用于匹配SPI总线上的设备和驱动。同时,SPI设备和其驱动通过总线互相进行匹配[16],使得设备能够找到正确的驱动程序进行控制和驱动。

static int __init spi_init(void)

{

buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL);

status = bus_register(&spi_bus_type); //注册SPI的总线类型

status = class_register(&spi_master_class); //注册spi_master的设备类

}

3 SPI总线验证

通过上述对SPI虚拟总线的分析和创建,本章节以飞思卡尔的IMX平台为例,测试SPI总线及其外设的连接状态。其中,外设为74HC595,定义命名为spidev的设备平台,设备驱动的数据结构如下

static struct spi_driver spidev_spi_driver = {

.driver = {

.name ="spidev",

.owner =THIS_MODULE,

},

.probe =spidev_probe,//探测并匹配相应的外设

};

IMX正常启动后,登入系统并切换到总线级的目录下进行观测,如图2所示。Linux在总线视图的目录中自动创建SPI目录,该目录下注册名为SPI1.0的总线,这层总线使用名为spidev的驱动,而驱动最终又指向名为SPI1.0的总线,表明SPI1.0总线创建成功并具备挂载外设的功能。

图2 使用终端观测到的SPI虚拟总线

进入设备级的目录后,如图3所示。外设已映射到名为SPI1.0的总线,并使用序号1的控制器以及控制器的第1个片选信号。该外设已绑定名为spidev的驱动,挂载到 /bus/spi的子系统中,这与在总线级目录下观测的结果一致。

图3 使用终端观测SPI总线连接的外设信息

4 结束语

提出了一种提高SPI驱动使用效率的设计方法,以Linux设备驱动模型为基础,在外设驱动和处理器驱动之间增加SPI虚拟总线,实现主机和外设任意组合的功能。经过测试,使用本方法设计的SPI驱动,降低设备驱动和处理器结构的耦合程度,且工作性能稳定,具备一定的工程实用性。

[1] Jonatban Corbet.Linux设备驱动程序[M].3版.魏永明,耿岳,钟书毅,译.北京:中国电力出版社,2012.

[2] 杨俊成.嵌入式Linux设备驱动程序框架的研究[J].核电子学与探测技术,2011,31(2):243-244.

[3] 胥霜霞.嵌入式Linux下Z85C30芯片设备驱动程序设计[J].电子科技,2014,27(5):116-117.

[4] 朱恩亮.Linux环境下USB设备驱动程序设计[J].电子

科技,2016,29(1):108-109.

[5] 宋宝华.Linux设备驱动开发详解[M].北京:人民邮电出版社,2008.

[6] 孟浩依然.Linux内核SPI总线驱动分析[EB/OL].(2012-12-11) [2015-09-06]http://www.cnblogs.com/liugf05/archive/2012/12/03/2800457.html.

[7] Marcus E,Stern H.高可用性系统设计[M].汪青青,卢祖英,译.北京:清华大学出版社,2005.

[8] Droid Phone.Linux SPI总线和设备驱动架构[EB/OL].(2014-04-12)[2015-02-16]http://blog.csdn.net/droidphone.

[9] Gene S.Getting Linux for your board[M].New York:Willy Press,2010.

[10] 刘刚.Linux系统移植[M].北京:清华大学出版社,2011.

[11] 孙天泽.嵌入式设计及Linux驱动开发指南[M].2版.北京:电子工业出版社,2007.

[12] Matthew N,Stone R.Linux程序设计[M].2版.杨晓芸,译.北京:机械工业出版社,2002.

[13] Daniel P Bovet.Understanding the Linux kernel[M].北京:中国电力出版社,2007.

[14] 王镇道,胡赞民,陈迪平.基于ARM&Linux平台IIC驱动程序的设计[J].微计算机信息,2011(5):1-3.

[15] 广州致远.嵌入式Linux开发教程[EB/OL].(2014-06-04)[2016-03-12]http://www.zlg.cn/ipc/down/down/id/92.html.

[16] 徐莹彗.ARM9嵌入式系统设计-基于S3C2410与Linux[M].北京:北京航空航天大学出版社,2007.

SPI Bus Driver Under Embedded Linux Programming

SUN Shuai, LI Chuanxi

(Nanjing Company,Aerospace Science and Industry Group (Shenzhen) Co. LTD.,Nanjing 211100,China)

Presents a design method of increasing the service efficiency of the software, the SPI driver, for example, through the design idea of separating peripherals and processor, add a layer between peripherals model and processor model virtual bus, to reduce the coupling of the peripheral drive and the host controller driver. The actual test results show that this method can realize the function of the host and peripherals in any combination has higher application value.

SPI bus; device drivers; Linux; the embedded

2016- 10- 26

孙帅(1984-),男,硕士,工程师。研究方向:航天飞行控制计算机。李传玺(1980-),男,硕士,工程师。研究方向:航天电力仪器。

10.16180/j.cnki.issn1007-7820.2017.08.027

TN919.71;TP316.2

A

1007-7820(2017)08-099-03

猜你喜欢
外设驱动程序内核
强化『高新』内核 打造农业『硅谷』
基于嵌入式Linux内核的自恢复设计
Linux内核mmap保护机制研究
计算机硬件设备驱动程序分析
微生物内核 生态型农资
基于MPC8280的CPU单元与内部总线驱动程序设计
Microchip推出具备双ADC外设的全新器件,扩展其低成本8位PIC®单片机产品线
外设天地行情
外设天地行情
外设天地行情