基於exynos4412的開發板,編寫了一個使用中斷的按鍵程序,實現按鍵點燈的功能。
實現效果是按下按鍵燈亮,再按一次燈滅。
旨在學習中斷的用法。
linux kernel version:4.4.38
1 gpx3: gpx3 {
2 gpio-controller; 3 #gpio-cells = <2>; 4 5 interrupt-controller; 6 #interrupt-cells = <2>; 7 }; 8 9 gpm4: gpm4 { 10 gpio-controller; 11 #gpio-cells = <2>; 12 13 interrupt-controller; 14 #interrupt-cells = <2>; 15 }; 16 17 my_keys { 18 compatible = "interrupt-keys"; 19 20 interrupt-parent = <&gpx3>; 21 interrupts = <2 IRQ_TYPE_EDGE_FALLING>; 22 key1-gpios = <&gpm4 0 GPIO_ACTIVE_LOW>; 23 };
mykeys是在DTS的根目錄下創建的資源:描述使用的中斷資源和led燈的gpio資源。
中斷是GPX3的bit2,下降沿觸發,led是GPM4的bit0
系統會自動將dts解析成platform device注冊到內核,compatible用來和platform driver匹配。
接下來看原理圖,可以看到和dts描述一致:
static struct gpio_desc *gpiod;
1 static int mykey_probe(struct platform_device *pdev) 2 {
8 unsigned int irq; 9 int ret; 13 struct device_node* np = pdev->dev.of_node; 14 if(np == NULL) 15 { 16 printk(KERN_ALERT "%s %d of_node is NULL\n", __FUNCTION__, __LINE__); 17 return 0; 18 } 19 /*get irq num*/ 21 irq = platform_get_irq(pdev, 0); 22 printk(KERN_ALERT "%s %d irq = %d\n", __FUNCTION__, __LINE__, irq);
/*register irq handler*/ 23 ret = devm_request_irq(&pdev->dev, irq, my_irq, 0, dev_name(&pdev->dev), NULL); 24 printk(KERN_ALERT "%s %d ret = %d\n", __FUNCTION__, __LINE__, ret); 25 26 gpiod = devm_gpiod_get_optional(&pdev->dev, "key1", GPIOD_OUT_HIGH); 27 if(gpiod == NULL){ 28 printk(KERN_ALERT "%s %d devm_gpiod_get_optional fail!!!\n", __FUNCTION__, __LINE__); 29 } 75 printk(KERN_ALERT "%s %d success===\n", __FUNCTION__, __LINE__); 76 return error; 77 }
21行:使用platform相關函數platform_get_irq,從platform device中獲取irq num
23行:使用devm_request_irq注冊中斷,其中my_irq是中斷處理函數,從原理圖可知,按下按鍵產生下降沿,那么按下按鍵就會觸發中斷,執行中斷處理函數my_irq
26行:gpiod是全局變量,旨在中斷處理函數中操作它實現按鍵點燈滅燈功能。devm_gpiod_get_optional從platform device中獲取信息,組成gpiod。第二個參數為dts中gpios的名字,第三個參數是將gpio設置為輸出高電平(此處為邏輯高電平)
所以probe函數執行后,燈默認為亮的狀態。
1 static irqreturn_t my_irq(int irqno, void *dev_id)
2 { 3 int level = gpiod_get_value(gpiod); 4 gpiod_set_value(gpiod, !level); 5 return IRQ_HANDLED; 6 }
中斷處理函數中只做一件事,觸發中斷后改變led的亮滅狀態。
這是我第一篇博客,程序也是demo級程序,如有錯誤還望指教~