新聞中心
隨著嵌入式設(shè)備的普及,Linux系統(tǒng)在這一領(lǐng)域的應(yīng)用也愈發(fā)廣泛。而在Linux系統(tǒng)中,驅(qū)動(dòng)設(shè)備樹接口成為了嵌入式設(shè)備驅(qū)動(dòng)的重要組成部分,廣泛應(yīng)用于包括嵌入式系統(tǒng)、嵌入式ARM開發(fā)板等在內(nèi)的硬件設(shè)備領(lǐng)域。本文將從驅(qū)動(dòng)設(shè)備樹接口的基礎(chǔ)概念入手,深入探究其在Linux系統(tǒng)中的應(yīng)用與優(yōu)勢(shì)。

成都創(chuàng)新互聯(lián)公司從2013年開始,先為德安等服務(wù)建站,德安等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為德安企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
一、驅(qū)動(dòng)設(shè)備樹接口的基礎(chǔ)概念
在介紹驅(qū)動(dòng)設(shè)備樹接口之前,我們先來了解一下設(shè)備樹。設(shè)備樹是一種基于樹形結(jié)構(gòu)的硬件平臺(tái)描述語言,它可以用來描述硬件平臺(tái)上各種設(shè)備的物理信息,如設(shè)備的名稱、地址、中斷等。設(shè)備樹的主要作用是解決設(shè)備資源配置的問題,可以方便地將設(shè)備信息傳遞給內(nèi)核,從而完成設(shè)備的初始化工作。
而驅(qū)動(dòng)設(shè)備樹接口(Driver Device Tree,簡稱DDT)則是Linux內(nèi)核中實(shí)現(xiàn)設(shè)備樹機(jī)制的接口。通過驅(qū)動(dòng)設(shè)備樹接口,內(nèi)核可以獲取設(shè)備信息,并根據(jù)設(shè)備樹的描述來初始化相應(yīng)的驅(qū)動(dòng)程序。驅(qū)動(dòng)設(shè)備樹接口是一種通用的接口,應(yīng)用廣泛,包括但不限于嵌入式設(shè)備、開發(fā)板、服務(wù)器等領(lǐng)域。
二、驅(qū)動(dòng)設(shè)備樹接口的應(yīng)用
驅(qū)動(dòng)設(shè)備樹接口的主要作用是為驅(qū)動(dòng)程序提供設(shè)備信息,從而完成設(shè)備的初始化。而驅(qū)動(dòng)設(shè)備樹接口的使用方法,可以分為驅(qū)動(dòng)程序?qū)υO(shè)備樹信息的解析和設(shè)備樹的編寫兩部分。
1、設(shè)備樹信息的解析
驅(qū)動(dòng)程序使用驅(qū)動(dòng)設(shè)備樹接口的之一步,就是解析設(shè)備樹中的信息。設(shè)備樹中包含了許多設(shè)備的物理信息,如設(shè)備名、中斷號(hào)、地址等,通過解析設(shè)備樹,驅(qū)動(dòng)程序可以從中獲取需要的信息,從而完成相應(yīng)的初始化工作。
以常見的I2C總線為例,其設(shè)備樹節(jié)點(diǎn)的基本格式如下:
“`
i2c@address {
compatible = “i2c-device-name”;
reg =
;
interrupt-parent = &gpio;
interrupts = ;
};
“`
在此,驅(qū)動(dòng)程序首先需要調(diào)用of_match_device()函數(shù),將設(shè)備樹節(jié)點(diǎn)與驅(qū)動(dòng)程序的匹配表進(jìn)行匹配。如果匹配成功,程序則會(huì)進(jìn)入到of_platform_populate()函數(shù)中,開始初始化相應(yīng)的驅(qū)動(dòng)程序。
2、設(shè)備樹的編寫
設(shè)備樹的編寫,是驅(qū)動(dòng)程序開發(fā)的重要組成部分。在編寫設(shè)備樹時(shí),開發(fā)人員需要遵循一系列規(guī)范,以便內(nèi)核能夠正確地解析設(shè)備樹。下面我們來介紹一下設(shè)備樹的編寫規(guī)范。
(1)設(shè)備樹節(jié)點(diǎn)的名稱
在設(shè)備樹中,每個(gè)節(jié)點(diǎn)都必須要有一個(gè)獨(dú)一無二的名稱。節(jié)點(diǎn)名稱一般遵循以下規(guī)范:
“`
device@physical_address {
…
};
“`
還可以使用以下格式:
“`
device@physical_address {
compatible = “device-model”;
…
};
“`
其中,device為設(shè)備名稱,physical_address為設(shè)備的物理地址,compatible表示設(shè)備的模塊。
(2)設(shè)備樹節(jié)點(diǎn)的類型
在設(shè)備樹中,每個(gè)節(jié)點(diǎn)都必須要有一個(gè)類型。節(jié)點(diǎn)類型一般遵循以下規(guī)范:
“`
device {
compatible = “device-model”;
…
};
“`
其中,device表示設(shè)備的類型,compatible表示設(shè)備的模塊。
(3)設(shè)備樹節(jié)點(diǎn)的屬性
在設(shè)備樹中,還可以為每個(gè)節(jié)點(diǎn)添加一些屬性。這些屬性一般遵循以下規(guī)范:
“`
device {
compatible = “device-model”;
reg = ;
…
};
“`
其中,reg表示設(shè)備的內(nèi)存地址信息。
三、驅(qū)動(dòng)設(shè)備樹接口的優(yōu)勢(shì)
驅(qū)動(dòng)設(shè)備樹接口作為嵌入式設(shè)備驅(qū)動(dòng)的重要組成部分,具有以下優(yōu)勢(shì):
1、對(duì)于嵌入式系統(tǒng)來說,設(shè)備樹可以直接描述芯片的硬件結(jié)構(gòu),便于物理硬件的描述和修改。
2、設(shè)備樹可以提供與硬件平臺(tái)相關(guān)的信息,方便內(nèi)核驅(qū)動(dòng)程序?qū)τ布M(jìn)行初始化。
3、對(duì)于不同人開發(fā)的硬件,設(shè)備樹可以起到統(tǒng)一的作用,從而方便外圍設(shè)備的擴(kuò)展。
4、通過使用設(shè)備樹,內(nèi)核不再需要硬編碼來實(shí)現(xiàn)硬件初始化,因此可以更加方便、快捷、簡單地實(shí)現(xiàn)驅(qū)動(dòng)程序的開發(fā)。
相關(guān)問題拓展閱讀:
- linux下如何開發(fā)sdio設(shè)備驅(qū)動(dòng)?
- linux下怎么直接使用iic接口
linux下如何開發(fā)sdio設(shè)備驅(qū)動(dòng)?
以LinuxKernelSdioMx28 / LinuxKernelSdioMx53項(xiàng)目代碼為例:
– module_init(DibBridgeTargetModuleInit)
驅(qū)動(dòng)模塊初始化入口
– DibBridgeTargetModuleInit():模塊初始化函數(shù)。
1.調(diào)用sdio_register_driver()注冊(cè)sdio接口驅(qū)動(dòng),
2.調(diào)用register_chrdev()注冊(cè)驅(qū)動(dòng)模塊為字符設(shè)備。
– sdio_register_driver():向系統(tǒng)注冊(cè)sdio接口驅(qū)動(dòng),調(diào)用以后,系統(tǒng)會(huì)觸發(fā)sdio設(shè)備id檢測(cè),如果設(shè)備id和接口驅(qū)動(dòng)里.id_table里定迅耐義的id一致,則系統(tǒng)調(diào)用probe函數(shù)。
1. 可以在DibBridgeTargetModuleInit()里調(diào)用,這樣inod之后,驅(qū)動(dòng)接口即被注冊(cè)(設(shè)備id被注冊(cè)),有相應(yīng)設(shè)備插入則probe會(huì)被調(diào)用(此種做法參考LinuxKernelSdioMx28)
2. 也可以在sdio初始化時(shí)調(diào)用,這樣設(shè)備插入時(shí),probe不會(huì)被調(diào)用,只有在sdio初始化,sdio_register_driver()被調(diào)用時(shí),系統(tǒng)才會(huì)重新檢測(cè)設(shè)備id,并調(diào)用probe。(此種做法好處是,模塊初始化不涉及何種設(shè)備,具有更好的通用性。參考LinuxKernelSdioMx53)
– static struct sdio_driver Dib_sdio_driver
是鍵游sdio接口驅(qū)動(dòng)的結(jié)構(gòu)體,包括.id_table, .probe()函數(shù)等,如下
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驅(qū)動(dòng)模塊關(guān)心的sdio設(shè)備id號(hào),只有插入的sdio設(shè)備的id號(hào)和這里面定義的id對(duì)應(yīng)上,系統(tǒng)才會(huì)調(diào)用.probe函數(shù)。
– register_chrdev()
將驅(qū)動(dòng)模塊向系統(tǒng)注冊(cè)為字符設(shè)備,并將操作該設(shè)備的接口函數(shù)file_operations也一起注冊(cè)了。
1.可以在DibBridgeTargetModuleInit()里調(diào)用。(參考LinuxKernelSdioMx53/LinuxKernelSdioMx28代碼)
2.也可以在probe函數(shù)里調(diào)用,即只有在系統(tǒng)稿昌銷檢測(cè)到硬件設(shè)備時(shí)才去注冊(cè)字符設(shè)備(參考sdk8remote代碼)
– struct file_operations
包含如下最基本的文件操作函數(shù),
struct file_operations fops =
{
.ioctl = DibBridgeTargetModuleIoctl, //控制命令傳輸或數(shù)據(jù)傳輸
.open = DibBridgeTargetModuleOpen,
.read = DibBridgeTargetModuleReadData,//數(shù)據(jù)傳輸
.write = DibBridgeTargetModuleWriteData
.release = DibBridgeTargetModuleRelease,
};
– .ioctl/.read 等等
user space和kernel space的傳輸通道,通過使用copy_from_user和copy_to_user這樣的函數(shù)來實(shí)現(xiàn)數(shù)據(jù)傳遞
Linux方面的想相關(guān)知識(shí)可以百度搜索《Linux就該這么學(xué)》進(jìn)行學(xué)習(xí)了解
linux下怎么直接使用iic接口
利用Linux中IIC設(shè)備子系統(tǒng)移植IIC設(shè)備驅(qū)動(dòng)
背景描述
IIC總線在嵌入式系統(tǒng)中應(yīng)用十分廣泛,常見的有eeprom,rtc。一般的處理器會(huì)包含IIC的控制器,用來完成IIC時(shí)序的控制;另外一方面,由于IIC的時(shí)序簡單,使用GPIO口來模擬時(shí)序也是常見的做法。面對(duì)不同的IIC控制器,各種各樣的芯片以及l(fā)inux源碼,如何更快做好IIC設(shè)備驅(qū)動(dòng)。
問題描述
在我們的方案中,我們會(huì)用到eeprom,段友rtc以及tw2865。由于Hi3520的IIC控制器設(shè)計(jì)有問題,無法正常使用。而IIC控制器的SDA和SCL管腳正好是和兩個(gè)GPIO管腳復(fù)用的。Hisi將控制gpio來實(shí)現(xiàn)IIC的時(shí)序,從而對(duì)IIC設(shè)備進(jìn)行操作。這種設(shè)計(jì)方亂旁式簡單明了,但使用IIC子系統(tǒng),可以更方便的移植和維護(hù)其他的設(shè)備驅(qū)動(dòng)。
問題分析
Hisi對(duì)于gpio口,rtc芯片以及tw2865的處理方式如下:將gpio口做成一個(gè)模塊化的驅(qū)動(dòng),該驅(qū)動(dòng)模擬IIC時(shí)序,并向外提供一些函數(shù)接口,比如:EXPORT_SYMBOL(gpio_i2c_read_tw2815);等。對(duì)于具體的rtc芯片,將其注冊(cè)為一個(gè)misc設(shè)備,并利用gpio模塊導(dǎo)出的函數(shù)進(jìn)行rtc芯片的配置操作。
其實(shí)對(duì)于linux-2.6.24\drivers\i2c目錄下代碼,我們可以加以利用。
Linux的IIC字結(jié)構(gòu)分為三個(gè)組成部分:
IIC核心
IIC核心提供了IIC總線驅(qū)動(dòng)和設(shè)握陪槐備驅(qū)動(dòng)的注冊(cè)、注銷方法,IICalgorithm上層的、與具體適配器無關(guān)的代碼以及探測(cè)設(shè)備、檢測(cè)設(shè)備地址的上層代碼。
IIC總線驅(qū)動(dòng)
IIC總線驅(qū)動(dòng)是對(duì)IIC硬件體系結(jié)構(gòu)中適配器端的實(shí)現(xiàn)。
IIC設(shè)備驅(qū)動(dòng)
IIC設(shè)備驅(qū)動(dòng)是對(duì)IIC硬件體系總設(shè)備端的實(shí)現(xiàn)。
我們查看下該目錄下的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總線的總線驅(qū)動(dòng),而chips中的文件就是常用芯片的驅(qū)動(dòng),algos中的文件實(shí)現(xiàn)了一些總線適配器的algorithm,其中就包括我們要用到的i2c-algo-bit.c文件。
我們首先利用i2c-gpio.c和i2c-algo-bit.c做好總線驅(qū)動(dòng)。
在i2c-gpio.c中,module_init?i2c_gpio_init?platform_driver_probe(&i2c_gpio_driver,i2c_gpio_probe);
將其注冊(cè)為platform虛擬總線的驅(qū)動(dòng)。
在staticint __init i2c_gpio_probe(struct platform_device *pdev)中,
定義了如下三個(gè)結(jié)構(gòu)體:
structi2c_gpio_platform_data *pdata;//平臺(tái)相關(guān)的gpio的設(shè)置
structi2c_algo_bit_data *bit_data;//包含algorithm的具體函數(shù),setor
get SDA和SCL
structi2c_adapter *adap;//適配器
i2c_gpio_probe主要做了下面幾件事:
填充bit_data結(jié)構(gòu)的各個(gè)函數(shù)指針,關(guān)聯(lián)到具體的操作SDA和SCl函數(shù)。
填充adap結(jié)構(gòu),adap->algo_data= bit_data;
pdata= pdev->dev.platform_data;
bit_data->data= pdata;
pdev->dev->driver_data= adap;
在i2c-core中注冊(cè)適配器類型。
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關(guān)聯(lián)上。
static const structi2c_algorithm i2c_bit_algo = {
.master_xfer = bit_xfer,
.functionality = bit_func,
};
其中,master_xfer函數(shù)指針就是IIC傳輸函數(shù)指針。
I2c-algo-bit.c還實(shí)現(xiàn)了IIC開始條件,結(jié)束條件的模擬,發(fā)送字節(jié),接收字節(jié)以及應(yīng)答位的處理。
i2c-gpio.c中的i2c_gpio_setsda_val等函數(shù)是與具體平臺(tái)gpio相關(guān)的。
修改對(duì)應(yīng)arch-hi3520v100目錄下的gpio.h中的各個(gè)函數(shù),這些函數(shù)是通過操作寄存器來控制gpio的方向和值。
在對(duì)應(yīng)mach-hi3520v100中的platform-devices.c中添加如下:
static structi2c_gpio_platform_data pdata = {
.sda_pin = 1dev.platform_data=pdata
綜合上面的過程,我們完成了adapter的注冊(cè),并將用gpio口模擬的algorithm與adapter完成了關(guān)聯(lián)。
這樣,在rtc-x1205.c中,x1205_attach函數(shù)利用i2c核心完成client和adap的關(guān)聯(lián)。
在x1205_probe函數(shù)中填充i2c_client結(jié)構(gòu)體,并調(diào)用i2c_attach_client通知iic核心。
接著注冊(cè)rtc驅(qū)動(dòng)。
最后我們要讀取時(shí)間,就需要構(gòu)造i2c_msg結(jié)構(gòu)體,如下所示:
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;
}
關(guān)于linux驅(qū)動(dòng)設(shè)備樹接口的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
創(chuàng)新互聯(lián)成都網(wǎng)站建設(shè)公司提供專業(yè)的建站服務(wù),為您量身定制,歡迎來電(028-86922220)為您打造專屬于企業(yè)本身的網(wǎng)絡(luò)品牌形象。
成都創(chuàng)新互聯(lián)品牌官網(wǎng)提供專業(yè)的網(wǎng)站建設(shè)、設(shè)計(jì)、制作等服務(wù),是一家以網(wǎng)站建設(shè)為主要業(yè)務(wù)的公司,在網(wǎng)站建設(shè)、設(shè)計(jì)和制作領(lǐng)域具有豐富的經(jīng)驗(yàn)。
網(wǎng)站題目:深入探索:Linux下驅(qū)動(dòng)設(shè)備樹接口(linux驅(qū)動(dòng)設(shè)備樹接口)
轉(zhuǎn)載源于:http://www.5511xx.com/article/dhcpghd.html


咨詢
建站咨詢
