日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux設(shè)備樹中的SPI驅(qū)動使用詳解(linux下設(shè)備樹spi使用)

Linux設(shè)備樹是一種描述硬件設(shè)備拓?fù)浣Y(jié)構(gòu)、資源分配等信息的機(jī)制,它的出現(xiàn)為移植嵌入式系統(tǒng)帶來了很大的便利性,但也帶來了新的學(xué)習(xí)和應(yīng)用難度。SPI(Serial Peripheral Interface)總線是一種高速串行總線協(xié)議,常用于連接嵌入式系統(tǒng)中的外設(shè)。本文將從設(shè)備樹的角度出發(fā),詳細(xì)介紹如何在Linux內(nèi)核中配置和使用SPI總線設(shè)備驅(qū)動。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:國際域名空間、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、新華網(wǎng)站維護(hù)、網(wǎng)站推廣。

一、設(shè)備樹中SPI總線設(shè)備的描述

設(shè)備樹是一棵樹形結(jié)構(gòu),每個節(jié)點(diǎn)對應(yīng)一個硬件設(shè)備或資源。下圖是一個簡單的設(shè)備樹結(jié)構(gòu)示例:

“`

/ {

spi@a0001000 {

compatible = “atmel,at91sam9263-spi”;

reg = ;

interrupt-parent = &pioA;

interrupts = ;

pinctrl-names = “default”;

pinctrl-0 = ;

};

};

“`

我們來逐個研究每個節(jié)點(diǎn)的含義和屬性:

1. 根節(jié)點(diǎn)“/”

在設(shè)備樹中,根節(jié)點(diǎn)表示整個硬件平臺。它常常是唯一的一個節(jié)點(diǎn),也可以有多個,比如多核處理器系統(tǒng)可以為每個核心生成一個根節(jié)點(diǎn)。根節(jié)點(diǎn)的屬性通常是平臺相關(guān)的,可以包括CPU類型、時鐘頻率、內(nèi)存布局等等。

2. SPI總線設(shè)備節(jié)點(diǎn)“spi@a0001000”

這是SPI設(shè)備的節(jié)點(diǎn)名,它由兩部分組成:“spi”表示節(jié)點(diǎn)類型,”a0001000”是設(shè)備的物理地址。SPI節(jié)點(diǎn)的屬性可以包括以下內(nèi)容:

* compatible:表示設(shè)備的兼容性信息,通常是一個字符串?dāng)?shù)組,字符串的格式由具體的硬件廠商或芯片開發(fā)者定義。

* reg:表示設(shè)備在總線上的地址范圍。

* interrupt-parent:表示IRQ控制器的父節(jié)點(diǎn),在AT91SAM9263芯片中使用的是PIOA。

* interrupts:表示設(shè)備的中斷號。

* pinctrl-names和pinctrl:表示設(shè)備的引腳控制信息,用于配置設(shè)備的引腳(IO口)。

3. 設(shè)備樹編譯

設(shè)備樹用源碼形式編寫,通常保存在.dts或.dtb文件中。為了將設(shè)備樹文件編譯成.dtb文件,要使用dtc工具。我們可以在Linux內(nèi)核源碼中找到dtc,并使用以下命令編譯設(shè)備樹:

“`

$ dtc -I dts -O dtb -o spi.dtb spi.dts

“`

其中-I參數(shù)指定輸入格式為dts,-O參數(shù)指定輸出格式為dtb。編譯成功后,將得到一個名為spi.dtb的設(shè)備樹二進(jìn)制文件。

二、設(shè)備驅(qū)動模型

Linux內(nèi)核的設(shè)備驅(qū)動模型通過一套抽象的結(jié)構(gòu)體和接口,將設(shè)備和驅(qū)動程序之間進(jìn)行解耦,以便更好地支持平臺移植和驅(qū)動模塊化。我們來看一下涉及到SPI總線設(shè)備驅(qū)動的關(guān)鍵結(jié)構(gòu)體和接口。

1. struct spi_master

該結(jié)構(gòu)體表示SPI總線控制器的主設(shè)備,它具有如下字段:

* bus_num:SPI總線控制器的編號,一般從0開始分配。

* max_speed_hz:該總線的更大總線速度,單位為Hz。

* mode_bits:該總線支持的SPI總線模式。

* chip_select:該總線所連接的芯片。

* num_chipselect:該總線支持的CS信號線數(shù)量。

* mode_bits:支持的SPI總線模式。

2. struct spi_device

該結(jié)構(gòu)體表示一個SPI設(shè)備,它具有如下字段:

* max_speed_hz:該設(shè)備的更大總線速度,單位為Hz。

* chip_select:設(shè)備所使用的芯片選擇線。

* mode:設(shè)備的SPI總線模式。

* bits_per_word:設(shè)備使用的每個字的位數(shù)。

* controller_data:和控制器相關(guān)的設(shè)備數(shù)據(jù)。

3. struct spi_board_info

該結(jié)構(gòu)體描述了一個SPI設(shè)備的常規(guī)屬性,用于創(chuàng)建一個spi_device結(jié)構(gòu)體。

* modalias:設(shè)備驅(qū)動名稱。

* max_speed_hz:更大總線速度。

* bus_num:控制器編號。

* chip_select:芯片選擇線編號。

* mode:SPI總線模式。

* platform_data:設(shè)備的平臺數(shù)據(jù)。

4. SPI傳輸函數(shù)

主要使用以下函數(shù)與SPI設(shè)備進(jìn)行數(shù)據(jù)傳輸:

* spi_setup:對SPI傳輸進(jìn)行一些基礎(chǔ)的設(shè)置,如極性、相位、總線速率等。

* spi_setup_transfer:配置傳輸參數(shù)(字長、模式、速度等)。

* spi_message_init:初始化SPI消息,用于將多個傳輸組織在一起。

* spi_sync:發(fā)送數(shù)據(jù)到SPI設(shè)備并等待回應(yīng)。

* spi_write_then_read:從設(shè)備中讀取和寫入數(shù)據(jù)。

* spi_write:寫入數(shù)據(jù)到設(shè)備。

以上函數(shù)的具體定義和使用方法詳見Linux內(nèi)核源碼和相關(guān)文檔。

三、SPI設(shè)備驅(qū)動的實現(xiàn)步驟

SPI設(shè)備驅(qū)動的實現(xiàn)步驟如下:

1. 注冊SPI主設(shè)備

SPI主設(shè)備的注冊可以在平臺設(shè)備的probe函數(shù)中執(zhí)行,可以使用spi_register_master函數(shù)進(jìn)行注冊。在注冊SPI主設(shè)備時,需要先通過platform_get_resource函數(shù)獲取到一個指向設(shè)備樹節(jié)點(diǎn)的指針,再從該指針中讀取設(shè)備節(jié)點(diǎn)的屬性。

“`

static int spi_probe(struct platform_device *pdev)

{

struct resource *res;

struct spi_master *master;

struct device *dev = &pdev->dev;

res = platform_get_resource_byname(pdev, IORESOURCE_MEM, “spi”);

if (!res) {

dev_err(dev, “no memory resource specified\n”);

return -ENXIO;

}

master = spi_alloc_master(&pdev->dev, sizeof(struct sam_spi));

if (!master)

return -ENOMEM;

master->bus_num = pdev->id;

master->num_chipselect = SAM_CS_NUM;

master->mode_bits = SPI_CPOL | SPI_CPHA;

master->max_speed_hz = 24000000;

master->dev.of_node = dev->of_node;

platform_set_drvdata(pdev, master);

return spi_register_master(master);

}

“`

其中,spi_alloc_master函數(shù)用于創(chuàng)建一個新的SPI主設(shè)備,sizeof(struct sam_spi)表示設(shè)備私有數(shù)據(jù)結(jié)構(gòu)的大小。

2. 注冊SPI子設(shè)備

SPI子設(shè)備的注冊可以在平臺設(shè)備的probe函數(shù)中執(zhí)行。需要使用spi_new_device函數(shù)創(chuàng)建一個spi_device結(jié)構(gòu)體,并傳入spi_master指針、spi_board_info結(jié)構(gòu)體等參數(shù)。在注冊SPI子設(shè)備時,需要根據(jù)設(shè)備樹節(jié)點(diǎn)的屬性設(shè)置相應(yīng)的參數(shù)。

“`

static int spi_probe(struct platform_device *pdev)

{

……

for (i = 0; i

if (!board_info[i].modalias)

continue;

if (board_info[i].bus_num != pdev->id)

continue;

/* create a new slave device */

slave = spi_new_device(master, &board_info[i]);

if (!slave) {

dev_err(&master->dev, “can’t create SPI slave %d\n”, i);

continue;

}

priv = spi_master_get_devdata(master);

priv->devices[i] = slave;

}

……

return 0;

}

“`

spi_new_device函數(shù)將會自動設(shè)置spi_device的max_speed_hz、chip_select、mode、bits_per_word四個參數(shù)。其中max_speed_hz的值依據(jù)設(shè)備樹節(jié)點(diǎn)的某個屬性值自動設(shè)置的。

3. SPI傳輸

在驅(qū)動程序中使用SPI傳輸數(shù)據(jù)的例子:

“`

static int spi_xfer(struct spi_device *spi, struct spi_transfer *tfr)

{

int ret;

ret = spi_setup_transfer(spi, tfr);

if (ret)

return ret;

ret = spi_sync(spi, tfr);

if (ret)

return ret;

return 0;

}

“`

該函數(shù)將使用spi_setup_transfer函數(shù)以及spi_sync函數(shù)來實現(xiàn)SPI傳輸。spi_setup_transfer函數(shù)用于設(shè)置SPI傳輸?shù)哪J胶蜁r鐘速度等參數(shù);spi_sync函數(shù)用于發(fā)送SPI信號并等待響應(yīng)。在spi_transfer結(jié)構(gòu)體中,填充好了tx_buf和rx_buf兩個緩沖區(qū),它們分別存放待發(fā)送和接收的數(shù)據(jù)。spi_transfer結(jié)構(gòu)體中的屬性例如bit_per_word、speed_hz等,表示該傳輸?shù)奈粩?shù)和時鐘速度,之前已經(jīng)通過spi_new_device函數(shù)自動設(shè)置。

四、設(shè)備樹使用示例

設(shè)備樹的配置有很多種方式,下面給出一種情況下SPI設(shè)備樹的相關(guān)配置方式。

在設(shè)備樹文件中添加SPI節(jié)點(diǎn):

“`

spi@11007000 {

compatible = “atmel,sam9x60-spi”;

reg = ;

interrupts = ;

clocks = , ;

clock-names = “spi”, “peripheral_clk”;

pinctrl-names = “default”;

pinctrl-0 = ;

};

pinctrl_spi0_default: spi0-default {

atmel,pins = ;

atmel,groups = “spi0_grp”;

};

“`

其中spi節(jié)點(diǎn)描述如前面二節(jié)所述,pinctrl_spi0_default節(jié)點(diǎn)描述了該SPI總線的引腳控制信息。

用戶驅(qū)動程序代碼:

“`

static struct spi_board_info spidev_board_info[] = {

{

.modalias = “spidev”,

.max_speed_hz = 1000000,

.bus_num = 0,

.chip_select = 0,

.mode = SPI_MODE_0,

},

};

static int __init spidev_init(void)

{

struct spi_master *master;

struct spi_device *spi;

master = spi_busnum_to_master(0);

if (!master) {

pr_err(“spi_busnum_to_master(%d) returned NULL\n”, 0);

return -ENODEV;

}

spi = spi_new_device(master, &spidev_board_info[0]);

if (!spi) {

pr_err(“spi_new_device fled\n”);

return -EBUSY;

}

spi_setup(spi);

return 0;

}

module_init(spidev_init);

“`

以上代碼使用spi_busnum_to_master函數(shù)獲取到SPI主設(shè)備,然后使用spi_new_device函數(shù)創(chuàng)建一個SPI子設(shè)備,并進(jìn)行spi_setup。由于在設(shè)備樹文件中設(shè)置了唯一的一個SPI總線節(jié)點(diǎn),因此我們可以在代碼中寫死SPI總線的bus_num為0,而不必再通過設(shè)備樹來查找SPI總線的節(jié)點(diǎn)。

相關(guān)問題拓展閱讀:

  • linux環(huán)境可以跑c語言跑spi

linux環(huán)境可以跑c語言跑spi

!??!

(1)打開Linux虛擬機(jī)在桌面創(chuàng)建一個文件夾,在文件夾里面創(chuàng)建一個以.c或者.cpp為后綴的文件

(2)把你的源程序敲在你的.c/.cpp文件里面,保存!

(3)ctrl+alt+t 同時按住打開終端

(4)輸入cd 然后把你在之一步創(chuàng)建的文件夾拖到終端里,你就會得到“cd 這個文件夾森早的位置”

(5)把文件路徑的引號刪掉,回車后你就會發(fā)現(xiàn)讀到這個文件夾里面了

(6)然后輸入gcc 文件全名(g++ 文件全名)例如:gcc a.c  然后運(yùn)行

這時如果你沒有安裝編譯器,終端上會提示你??!會提示你!會提示你!就像下面這樣

然此激雀后你復(fù)制自鉛瞎己的提示運(yùn)行就可以了,安裝會要你輸入密碼,輸入的時候是沒有符號提示的!輸入了就回車等下載好就可以

(7)然后會在你的文件夾里生成一個名為a.out的文件

(8)輸入./a.out就可以執(zhí)行了!

linux下設(shè)備樹spi使用的介紹就聊到這里吧,感謝你花時間閱讀本站內(nèi)容,更多關(guān)于linux下設(shè)備樹spi使用,Linux設(shè)備樹中的SPI驅(qū)動使用詳解,linux環(huán)境可以跑c語言跑spi的信息別忘了在本站進(jìn)行查找喔。

香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。


當(dāng)前文章:Linux設(shè)備樹中的SPI驅(qū)動使用詳解(linux下設(shè)備樹spi使用)
網(wǎng)頁鏈接:http://www.5511xx.com/article/djidodp.html