LINUX 基於裝置樹編寫按鍵中斷驅動程式

2021-10-20 17:51:04 字數 4309 閱讀 4884

linux核心版本:4.14.2

1. 在原理圖中確定home按鍵的引腳

2. 在裝置樹檔案中新增節點描述home引腳

3. 重新編譯燒寫裝置樹

4. 編寫驅動程式,呼叫裝置樹介面函式獲取home引腳的中斷號,使用中斷號註冊按鍵中斷處理程式

在原理圖中確定home按鍵的引腳

在原理圖中找到home按鍵對應的引腳是gpx1_1

在裝置樹檔案中新增節點描述home引腳

itop4412開發板中將gpio分成多個組,gpx1_1在gpx1組中,裝置樹檔案exynos4412-pinctrl.dtsi中用如下節點描述gpx1組:

編寫驅動程式,呼叫裝置樹介面函式獲取home引腳的中斷號,使用中斷號註冊按鍵中斷處理程式

驅動程式按照平台匯流排的架構編寫,用platform_driver_register註冊驅動;

4.1 裝置和驅動匹配實現過程

在裝置樹檔案中新增了home按鍵的描述節點後,核心在解析裝置樹時,就會將上述節點轉換成乙個平台裝置platform_device;在struct platform_driver結構體中,將compatible屬性設定為」irq-keys」,那麼,載入驅動後,就會和核心生成的這個平台裝置platform_device匹配,從而進入probe函式中
驅動程式中指定compatible的程式如下:

static

const

struct of_device_id irq_test_of_match=

,,};

module_device_table

(of, irq_test_of_match)

;static

struct platform_driver irq_test_device_driver =

};

4.2 home引腳資訊讀取過程

讀取子節點的個數,irqtest_keys只有乙個子節點key-home

device_get_child_node_count

獲取每個子節點的結構體

device_for_each_child_node(dev, child)

獲取子節點中引腳的虛擬中斷號,這個虛擬中斷號是核心自動生成的

irq_of_parse_and_map(to_of_node(child), 0)

獲取子節點gpio描述符gpiod

devm_fwnode_get_gpiod_from_child

使用虛擬中斷號註冊中斷處理函式

devm_request_any_context_irq

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

/* 裝置樹節點 */

#if 0

irqtest_keys ;}

;my_irq_key: my-irq-key

;#endif

struct my_gpio_keys_button

;static

char

*label[2]

;static

struct device *dev;

static

struct my_gpio_keys_button *button;

static irqreturn_t irq_test_irq_isr

(int irq,

void

*dev_id)

static

intirq_test_probe

(struct platform_device *pdev)

printk

(kern_info "child num is %d.\n"

, nbuttons)

; button =

devm_kzalloc

(dev,

sizeof

(struct my_gpio_keys_button)

* nbuttons, gfp_kernel)

;/* 獲取lable引數,父節點沒有lable屬性 */

device_property_read_string

(dev,

"label"

, label[0]

);printk

(kern_info "parent lable %s\n"

, label[0]

);/* 掃瞄處理每個子節點 */

device_for_each_child_node

(dev, child)

fwnode_property_read_string

(child,

"label"

,&button->desc)

;/* 獲取gpio描述符gpiod */

button->gpiod =

devm_fwnode_get_gpiod_from_child

(dev,

null

, child,

gpiod_in,

button->desc);if

(is_err

(button->gpiod)

)/* 檢查虛擬中斷號,可不使用 */if(

!button->irq)

button->irq = irq;

}printk

(kern_info "get virq %d for key.\n"

, button->irq)

; isr = irq_test_irq_isr;

irqflags =0;

irqflags |

= irqf_shared;

//devm_request_any_context_irq(class_dev, data->irq,int26_irq, irqf_trigger_falling, data->name, data);

/* 設定引腳為輸入模式 */

gpiod_set_value

(button->gpiod,1)

;gpiod_direction_input

(button->gpiod)

;/* 註冊中斷 */

/* 最後乙個引數是傳給中斷函式的引數 */

error =

devm_request_any_context_irq

(dev, button->irq, isr, irqf_trigger_falling, button->desc,

null);

if(error <0)

}return0;

}static

const

struct of_device_id irq_test_of_match=

,,};

module_device_table

(of, irq_test_of_match)

;static

struct platform_driver irq_test_device_driver =};

static

int __init irq_test_init

(void

)static

void __exit irq_test_exit

(void

)module_init

(irq_test_init)

;module_exit

(irq_test_exit)

;module_license

("gpl"

);

編寫裝置樹DTS

第一步就是要為這個模型機構建乙個基本結構,這是乙個有效的裝置樹最基本的結構。在這個階段你需要唯一的標識該機器。compatible marvell armada38x compatible 指定了系統的名稱。它包含了乙個 製造商 型號 形式的字串。重要的是要指定乙個確切的裝置,並且包括製造商的名子,...

基於平台匯流排的按鍵裝置驅動

平台匯流排 將裝置和驅動分離開來,便於移植,提供裝置與驅動的匹配。裝置模組的程式 include include include include include 定義key的控制暫存器 define gpncon 0x7f008830 定義資源 struct resource key resourc...

編寫Linux裝置驅動

核心版本 2.4.22 閱讀此文的目的 學會編寫linux裝置 驅動。閱讀此文的方法 閱讀以下2個 檔案 hello.c,asdf.c。此文假設讀者 已經能用c語言編寫linux應用程式,理解 字元裝置檔案,塊裝置檔案,主裝置號,次裝置號 會寫簡單的shell指令碼和makefile。1.hello...