随着嵌入式设备的普及,Linux系统在这一领域的应用也愈发广泛。而在Linux系统中,驱动设备树接口成为了嵌入式设备驱动的重要组成部分,广泛应用于包括嵌入式系统、嵌入式ARM开发板等在内的硬件设备领域。本文将从驱动设备树接口的基础概念入手,深入探究其在Linux系统中的应用与优势。
成都创新互联公司从2013年开始,先为德安等服务建站,德安等地企业,进行企业商务咨询服务。为德安企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。
一、驱动设备树接口的基础概念
在介绍驱动设备树接口之前,我们先来了解一下设备树。设备树是一种基于树形结构的硬件平台描述语言,它可以用来描述硬件平台上各种设备的物理信息,如设备的名称、地址、中断等。设备树的主要作用是解决设备资源配置的问题,可以方便地将设备信息传递给内核,从而完成设备的初始化工作。
而驱动设备树接口(Driver Device Tree,简称DDT)则是Linux内核中实现设备树机制的接口。通过驱动设备树接口,内核可以获取设备信息,并根据设备树的描述来初始化相应的驱动程序。驱动设备树接口是一种通用的接口,应用广泛,包括但不限于嵌入式设备、开发板、服务器等领域。
二、驱动设备树接口的应用
驱动设备树接口的主要作用是为驱动程序提供设备信息,从而完成设备的初始化。而驱动设备树接口的使用方法,可以分为驱动程序对设备树信息的解析和设备树的编写两部分。
1、设备树信息的解析
驱动程序使用驱动设备树接口的之一步,就是解析设备树中的信息。设备树中包含了许多设备的物理信息,如设备名、中断号、地址等,通过解析设备树,驱动程序可以从中获取需要的信息,从而完成相应的初始化工作。
以常见的I2C总线为例,其设备树节点的基本格式如下:
“`
i2c@address {
compatible = “i2c-device-name”;
reg =
;
interrupt-parent = &gpio;
interrupts = ;
};
“`
在此,驱动程序首先需要调用of_match_device()函数,将设备树节点与驱动程序的匹配表进行匹配。如果匹配成功,程序则会进入到of_platform_populate()函数中,开始初始化相应的驱动程序。
2、设备树的编写
设备树的编写,是驱动程序开发的重要组成部分。在编写设备树时,开发人员需要遵循一系列规范,以便内核能够正确地解析设备树。下面我们来介绍一下设备树的编写规范。
(1)设备树节点的名称
在设备树中,每个节点都必须要有一个独一无二的名称。节点名称一般遵循以下规范:
“`
device@physical_address {
…
};
“`
还可以使用以下格式:
“`
device@physical_address {
compatible = “device-model”;
…
};
“`
其中,device为设备名称,physical_address为设备的物理地址,compatible表示设备的模块。
(2)设备树节点的类型
在设备树中,每个节点都必须要有一个类型。节点类型一般遵循以下规范:
“`
device {
compatible = “device-model”;
…
};
“`
其中,device表示设备的类型,compatible表示设备的模块。
(3)设备树节点的属性
在设备树中,还可以为每个节点添加一些属性。这些属性一般遵循以下规范:
“`
device {
compatible = “device-model”;
reg = ;
…
};
“`
其中,reg表示设备的内存地址信息。
三、驱动设备树接口的优势
驱动设备树接口作为嵌入式设备驱动的重要组成部分,具有以下优势:
1、对于嵌入式系统来说,设备树可以直接描述芯片的硬件结构,便于物理硬件的描述和修改。
2、设备树可以提供与硬件平台相关的信息,方便内核驱动程序对硬件进行初始化。
3、对于不同人开发的硬件,设备树可以起到统一的作用,从而方便外围设备的扩展。
4、通过使用设备树,内核不再需要硬编码来实现硬件初始化,因此可以更加方便、快捷、简单地实现驱动程序的开发。
相关问题拓展阅读:
以LinuxKernelSdioMx28 / LinuxKernelSdioMx53项目代码为例:
– module_init(DibBridgeTargetModuleInit)
驱动模块初始化入口
– DibBridgeTargetModuleInit():模块初始化函数。
1.调用sdio_register_driver()注册sdio接口驱动,
2.调用register_chrdev()注册驱动模块为字符设备。
– sdio_register_driver():向系统注册sdio接口驱动,调用以后,系统会触发sdio设备id检测,如果设备id和接口驱动里.id_table里定迅耐义的id一致,则系统调用probe函数。
1. 可以在DibBridgeTargetModuleInit()里调用,这样inod之后,驱动接口即被注册(设备id被注册),有相应设备插入则probe会被调用(此种做法参考LinuxKernelSdioMx28)
2. 也可以在sdio初始化时调用,这样设备插入时,probe不会被调用,只有在sdio初始化,sdio_register_driver()被调用时,系统才会重新检测设备id,并调用probe。(此种做法好处是,模块初始化不涉及何种设备,具有更好的通用性。参考LinuxKernelSdioMx53)
– static struct sdio_driver Dib_sdio_driver
是键游sdio接口驱动的结构体,包括.id_table, .probe()函数等,如下
static struct sdio_driver Dib_sdio_driver = {
.name = “Dib_sdio”,
.id_table = Dib_sdio_ids,
.probe = Dib_sdio_probe,
.remove = __devexit_p(Dib_sdio_remove),
};
其中.id_table很重要,它里面定义了此sdio驱动模块关心的sdio设备id号,只有插入的sdio设备的id号和这里面定义的id对应上,系统才会调用.probe函数。
– register_chrdev()
将驱动模块向系统注册为字符设备,并将操作该设备的接口函数file_operations也一起注册了。
1.可以在DibBridgeTargetModuleInit()里调用。(参考LinuxKernelSdioMx53/LinuxKernelSdioMx28代码)
2.也可以在probe函数里调用,即只有在系统稿昌销检测到硬件设备时才去注册字符设备(参考sdk8remote代码)
– struct file_operations
包含如下最基本的文件操作函数,
struct file_operations fops =
{
.ioctl = DibBridgeTargetModuleIoctl, //控制命令传输或数据传输
.open = DibBridgeTargetModuleOpen,
.read = DibBridgeTargetModuleReadData,//数据传输
.write = DibBridgeTargetModuleWriteData
.release = DibBridgeTargetModuleRelease,
};
– .ioctl/.read 等等
user space和kernel space的传输通道,通过使用copy_from_user和copy_to_user这样的函数来实现数据传递
Linux方面的想相关知识可以百度搜索《Linux就该这么学》进行学习了解
利用Linux中IIC设备子系统移植IIC设备驱动
背景描述
IIC总线在嵌入式系统中应用十分广泛,常见的有eeprom,rtc。一般的处理器会包含IIC的控制器,用来完成IIC时序的控制;另外一方面,由于IIC的时序简单,使用GPIO口来模拟时序也是常见的做法。面对不同的IIC控制器,各种各样的芯片以及linux源码,如何更快做好IIC设备驱动。
问题描述
在我们的方案中,我们会用到eeprom,段友rtc以及tw2865。由于Hi3520的IIC控制器设计有问题,无法正常使用。而IIC控制器的SDA和SCL管脚正好是和两个GPIO管脚复用的。Hisi将控制gpio来实现IIC的时序,从而对IIC设备进行操作。这种设计方乱旁式简单明了,但使用IIC子系统,可以更方便的移植和维护其他的设备驱动。
问题分析
Hisi对于gpio口,rtc芯片以及tw2865的处理方式如下:将gpio口做成一个模块化的驱动,该驱动模拟IIC时序,并向外提供一些函数接口,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。对于具体的rtc芯片,将其注册为一个misc设备,并利用gpio模块导出的函数进行rtc芯片的配置操作。
其实对于linux-2.6.24\drivers\i2c目录下代码,我们可以加以利用。
Linux的IIC字结构分为三个组成部分:
IIC核心
IIC核心提供了IIC总线驱动和设握陪槐备驱动的注册、注销方法,IICalgorithm上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码。
IIC总线驱动
IIC总线驱动是对IIC硬件体系结构中适配器端的实现。
IIC设备驱动
IIC设备驱动是对IIC硬件体系总设备端的实现。
我们查看下该目录下的makefile和kconfig:
obj-$(CONFIG_I2C_BOARDINFO) +=i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_CHARDEV) +=i2c-dev.o
obj-y +=busses/ chips/ algos/
i2c-core.c就是IIC核心,buses中的文件是主流处理器中IIC总线的总线驱动,而chips中的文件就是常用芯片的驱动,algos中的文件实现了一些总线适配器的algorithm,其中就包括我们要用到的i2c-algo-bit.c文件。
我们首先利用i2c-gpio.c和i2c-algo-bit.c做好总线驱动。
在i2c-gpio.c中,module_initi2c_gpio_initplatform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);
将其注册为platform虚拟总线的驱动。
在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,
定义了如下三个结构体:
structi2c_gpio_platform_data *pdata;//平台相关的gpio的设置
structi2c_algo_bit_data *bit_data;//包含algorithm的具体函数,setor
get SDA和SCL
structi2c_adapter *adap;//适配器
i2c_gpio_probe主要做了下面几件事:
填充bit_data结构的各个函数指针,关联到具体的操作SDA和SCl函数。
填充adap结构,adap->algo_data= bit_data;
pdata= pdev->dev.platform_data;
bit_data->data= pdata;
pdev->dev->driver_data= adap;
在i2c-core中注册适配器类型。
inti2c_bit_add_numbered_bus(struct i2c_adapter *adap)
在staticint i2c_bit_prepare_bus(struct i2c_adapter *adap)中
adap->algo= &i2c_bit_algo;
将i2c_bit_algo与adap关联上。
static const structi2c_algorithm i2c_bit_algo = {
.master_xfer = bit_xfer,
.functionality = bit_func,
};
其中,master_xfer函数指针就是IIC传输函数指针。
I2c-algo-bit.c还实现了IIC开始条件,结束条件的模拟,发送字节,接收字节以及应答位的处理。
i2c-gpio.c中的i2c_gpio_setsda_val等函数是与具体平台gpio相关的。
修改对应arch-hi3520v100目录下的gpio.h中的各个函数,这些函数是通过操作寄存器来控制gpio的方向和值。
在对应mach-hi3520v100中的platform-devices.c中添加如下:
static structi2c_gpio_platform_data pdata = {
.sda_pin = 1dev.platform_data=pdata
综合上面的过程,我们完成了adapter的注册,并将用gpio口模拟的algorithm与adapter完成了关联。
这样,在rtc-x1205.c中,x1205_attach函数利用i2c核心完成client和adap的关联。
在x1205_probe函数中填充i2c_client结构体,并调用i2c_attach_client通知iic核心。
接着注册rtc驱动。
最后我们要读取时间,就需要构造i2c_msg结构体,如下所示:
struct i2c_msg msgs = {
{ client->addr, 0, 2,dt_addr }, /* setup read ptr */
{ client->addr, I2C_M_RD,8, buf }, /* read date */
};
/* read date registers */
if((i2c_transfer(client->adapter, &msgs, 2)) != 2) {
dev_err(&client->dev,”%s: read error\n”, __FUNCTION__);
return -EIO;
}
关于linux驱动设备树接口的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
创新互联成都网站建设公司提供专业的建站服务,为您量身定制,欢迎来电(028-86922220)为您打造专属于企业本身的网络品牌形象。
成都创新互联品牌官网提供专业的网站建设、设计、制作等服务,是一家以网站建设为主要业务的公司,在网站建设、设计和制作领域具有丰富的经验。
网页标题:深入探索:Linux下驱动设备树接口(linux驱动设备树接口)
文章网址:http://www.mswzjz.com/qtweb/news46/203746.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联