驱动框架5——基于驱动框架写led驱动
生活随笔
收集整理的這篇文章主要介紹了
驱动框架5——基于驱动框架写led驱动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
以下內容源于朱有鵬《物聯網大講堂》課程的學習整理,如有侵權,請告知刪除。
五、基于驅動框架寫led驅動1
1、分析
(1)參考哪里? ?drivers/leds/leds-s3c24xx.c文件,drivers/leds/led-class.c文件(此文件是一些函數的集合體)
(2)關鍵點?led_classdev_register函數,led_classdev_unregister函數
2、動手寫led驅動模塊
- led_classdev_unregister函數
- led_classdev_register函數
- 這里寫的驅動,沒有像leds-s3c24xx.c那樣使用驅動模型——平臺總線模型,而是參考部分,自己寫的驅動
六、基于驅動框架寫led驅動2
1、代碼實踐
(1)調試
(2)分析drivers/leds/led-class.c文件
- 我們寫的驅動確實工作了,被加載了,/sys/class/leds/目錄下確實多出來了一個表示設備的文件夾。
- 文件夾里面有相應的操控led硬件的2個屬性brightness和max_brightness。
- led-class.c中brightness方法有一個show方法和store方法,這兩個方法對應用戶在/sys/class/leds/myled/brightness目錄下直接去讀寫這個文件時實際執行的代碼。
- 當我們show brightness時,實際就會執行led_brightness_show函數。
- 當我們echo 1 > brightness時,實際就會執行led_brightness_store函數。
- 因此show方法和store方法會去操控硬件;
- 但是led-class.c文件又屬于驅動框架中的文件,它本身無法直接讀取具體硬件;
- 因此在show和store的函數實現中,使用函數指針的方式調用了struct led_classdev結構體中的相應的讀取/寫入硬件信息的方法。
2、添加硬件操作
七、基于驅動框架寫led驅動3
1、在驅動中將4個LED分開
(1)好處
- 驅動層實現對各個LED設備的獨立訪問,并向應用層展示出4個操作接口led1、led2、led3、led4,這樣應用層可以完全按照自己的需要對LED進行控制。
- 驅動的設計理念:不要對最終需求功能進行假定(不能假定用戶進行什么操作,比如是幾個led一起操作還是一個操作而已?),而應該只是直接的對硬件的操作。
- 有一個概念就是:機制和策略的問題。在硬件操作上驅動只應該提供機制(具體實現)而不是策略(方法、主意、解決方案)。策略由應用程序來做。
(2)如何實現
#include <linux/module.h> // module_init module_exit #include <linux/init.h> // __init __exit #include <linux/fs.h> #include <linux/leds.h> #include <mach/regs-gpio.h> #include <mach/gpio-bank.h> #include <linux/io.h> #include <linux/ioport.h>#define GPJ0CON S5PV210_GPJ0CON #define GPJ0DAT S5PV210_GPJ0DATstatic struct led_classdev mydev1; // 定義結構體變量 static struct led_classdev mydev2; // 定義結構體變量 static struct led_classdev mydev3; // 定義結構體變量// 這個函數就是要去完成具體的硬件讀寫任務的 static void s5pv210_led1_set(struct led_classdev *led_cdev, enum led_brightness value) {printk(KERN_INFO "s5pv210_led1_set\n");writel(0x11111111, GPJ0CON);// 在這里根據用戶設置的值來操作硬件// 用戶設置的值就是valueif (value == LED_OFF){// 用戶給了個0,希望LED滅//writel(0x11111111, GPJ0CON);// 讀改寫三部曲writel((readl(GPJ0DAT) | (1<<3)), GPJ0DAT);}else{// 用戶給的是非0,希望LED亮//writel(0x11111111, GPJ0CON);writel((readl(GPJ0DAT) & ~(1<<3)), GPJ0DAT);} }static void s5pv210_led2_set(struct led_classdev *led_cdev, enum led_brightness value) {printk(KERN_INFO "s5pv2102_led_set\n");writel(0x11111111, GPJ0CON);// 在這里根據用戶設置的值來操作硬件// 用戶設置的值就是valueif (value == LED_OFF){// 用戶給了個0,希望LED滅//writel(0x11111111, GPJ0CON);// 讀改寫三部曲writel((readl(GPJ0DAT) | (1<<4)), GPJ0DAT);}else{// 用戶給的是非0,希望LED亮//writel(0x11111111, GPJ0CON);writel((readl(GPJ0DAT) & ~(1<<4)), GPJ0DAT);} }static void s5pv210_led3_set(struct led_classdev *led_cdev,enum led_brightness value) {printk(KERN_INFO "s5pv210_led3_set\n");writel(0x11111111, GPJ0CON);// 在這里根據用戶設置的值來操作硬件// 用戶設置的值就是valueif (value == LED_OFF){// 用戶給了個0,希望LED滅//writel(0x11111111, GPJ0CON);// 讀改寫三部曲writel((readl(GPJ0DAT) | (1<<5)), GPJ0DAT);}else{// 用戶給的是非0,希望LED亮//writel(0x11111111, GPJ0CON);writel((readl(GPJ0DAT) & ~(1<<5)), GPJ0DAT);} }static int __init s5pv210_led_init(void) {// 用戶insmod安裝驅動模塊時會調用該函數// 該函數的主要任務就是去使用led驅動框架提供的設備注冊函數來注冊一個設備int ret = -1;// led1mydev1.name = "led1";mydev1.brightness = 255; mydev1.brightness_set = s5pv210_led1_set;ret = led_classdev_register(NULL, &mydev1);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}// led2mydev2.name = "led2";mydev2.brightness = 255; mydev2.brightness_set = s5pv210_led2_set;//這句話就把驅動框架第一部分,和第二部分關聯起來了!!!!!ret = led_classdev_register(NULL, &mydev2);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}// led3mydev3.name = "led3";mydev3.brightness = 255; mydev3.brightness_set = s5pv210_led3_set;ret = led_classdev_register(NULL, &mydev3);if (ret < 0) {printk(KERN_ERR "led_classdev_register failed\n");return ret;}return 0; }static void __exit s5pv210_led_exit(void) {led_classdev_unregister(&mydev1);led_classdev_unregister(&mydev2);led_classdev_unregister(&mydev3); }module_init(s5pv210_led_init); module_exit(s5pv210_led_exit);// MODULE_xxx這種宏作用是用來添加模塊描述信息 MODULE_LICENSE("GPL"); // 描述模塊的許可證 MODULE_AUTHOR("aston <1264671872@qq.com>"); // 描述模塊的作者 MODULE_DESCRIPTION("s5pv210 led driver"); // 描述模塊的介紹信息 MODULE_ALIAS("s5pv210_led"); // 描述模塊的別名信息2、和leds-s3c24xx.c的不同
3、gpiolib引入
(1)一個事實:很多硬件都要用到GPIO,GPIO會復用;
(2)如果同一個GPIO被2個驅動同時控制了,就會出現bug;
(3)內核提供gpiolib來統一管理系統中所有GPIO;
- 某個驅動需要用到GPIO時,需要申請,被許可后才可以使用,使用完后釋放,其他驅動才能使用該GPIO。
- 建議性的,希望都用gpiolib。
(4)gpiolib體系,屬于驅動框架的一部分。
總結
以上是生活随笔為你收集整理的驱动框架5——基于驱动框架写led驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机无线局域网毕业论文,谈教学设计《计
- 下一篇: mysql带入参的存储过程_MySql带