歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

字符驅動設計----mini2440 LED驅動設計之路

大多數書籍在介紹字符驅動過於理論化,縱覽一章都是些文字,再附上一些零碎的代碼,看的人頭暈,時間長了自然就不想看了。 對於驅動的學習,剛開始不能過於理論化,一定要結合實際,要不然像空中樓台,住在上面,心裡老感覺不踏實。那麼如何入手呢?我覺得三點是很重要的:

1  驅動設計的總體框架(對於每種類型的驅動設計,最好畫出模型圖)

2  參考現有實例化的驅動

3  針對某一具體硬件,自己寫驅動來實現

 接下來以字符驅動設計為例,也是mini2440led驅動實現。

1 字符設備驅動模型如下圖所示,這是一個總體調用框架圖,具體的字符設備驅動模型參照另外一篇引用的文章【字符設備驅動模型】,驅動層主要做的工作是file_operations結構體中一些關鍵函數的實現,包括open,read,ioctl。本例中主要實現open,ioctl。

2 現有驅動模型實例

  1. #include <linux/module.h>   
  2. #include <linux/kernel.h>   
  3. #include <linux/fs.h>   
  4. #include <linux/init.h>   
  5. #include <linux/delay.h>   
  6. #include <asm/irq.h>   
  7. #include <asm/arch/regs-gpio.h>   
  8. #include <asm/hardware.h>   
  9.   
  10. #define DEVICE_NAME     "leds"  /* 加載模式後,執行”cat /proc/devices”命令看到的設備名稱 */   
  11. #define LED_MAJOR       231     /* 主設備號 */   
  12.   
  13. /* 應用程序執行ioctl(fd, cmd, arg)時的第2個參數 */  
  14. #define IOCTL_LED_ON    0   
  15. #define IOCTL_LED_OFF   1   
  16.   
  17. /* 用來指定LED所用的GPIO引腳 */  
  18. static unsigned long led_table [] = {  
  19.     S3C2410_GPB5,  
  20.     S3C2410_GPB6,  
  21.     S3C2410_GPB7,  
  22.     S3C2410_GPB8,  
  23. };  
  24.   
  25. /* 用來指定GPIO引腳的功能:輸出 */  
  26. static unsigned int led_cfg_table [] = {  
  27.     S3C2410_GPB5_OUTP,  
  28.     S3C2410_GPB6_OUTP,  
  29.     S3C2410_GPB7_OUTP,  
  30.     S3C2410_GPB8_OUTP,  
  31. };  
  32.   
  33. /* 應用程序對設備文件/dev/leds執行open(...)時, 
  34.  * 就會調用s3c24xx_leds_open函數 
  35.  */  
  36. static int s3c24xx_leds_open(struct inode *inode, struct file *file)  
  37. {  
  38.     int i;  
  39.       
  40.     for (i = 0; i < 4; i++) {  
  41.         // 設置GPIO引腳的功能:本驅動中LED所涉及的GPIO引腳設為輸出功能   
  42.         s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);  
  43.     }  
  44.     return 0;  
  45. }  
  46.   
  47. /* 應用程序對設備文件/dev/leds執行ioclt(...)時, 
  48.  * 就會調用s3c24xx_leds_ioctl函數 
  49.  */  
  50. static int s3c24xx_leds_ioctl(  
  51.     struct inode *inode,   
  52.     struct file *file,   
  53.     unsigned int cmd,   
  54.     unsigned long arg)  
  55. {  
  56.     if (arg > 4) {  
  57.         return -EINVAL;  
  58.     }  
  59.       
  60.     switch(cmd) {  
  61.     case IOCTL_LED_ON:  
  62.         // 設置指定引腳的輸出電平為0   
  63.         s3c2410_gpio_setpin(led_table[arg], 0);  
  64.         return 0;  
  65.   
  66.     case IOCTL_LED_OFF:  
  67.         // 設置指定引腳的輸出電平為1   
  68.         s3c2410_gpio_setpin(led_table[arg], 1);  
  69.         return 0;  
  70.   
  71.     default:  
  72.         return -EINVAL;  
  73.     }  
  74. }  
  75.   
  76. /* 這個結構是字符設備驅動程序的核心 
  77.  * 當應用程序操作設備文件時所調用的open、read、write等函數, 
  78.  * 最終會調用這個結構中指定的對應函數 
  79.  */  
  80. static struct file_operations s3c24xx_leds_fops = {  
  81.     .owner  =   THIS_MODULE,    /* 這是一個宏,推向編譯模塊時自動創建的__this_module變量 */  
  82.     .open   =   s3c24xx_leds_open,       
  83.     .ioctl  =   s3c24xx_leds_ioctl,  
  84. };  
  85.   
  86. /* 
  87.  * 執行“insmod s3c24xx_leds.ko”命令時就會調用這個函數 
  88.  */  
  89. static int __init s3c24xx_leds_init(void)  
  90. {  
  91.     int ret;  
  92.   
  93.     /* 注冊字符設備驅動程序 
  94.      * 參數為主設備號、設備名字、file_operations結構; 
  95.      * 這樣,主設備號就和具體的file_operations結構聯系起來了, 
  96.      * 操作主設備為LED_MAJOR的設備文件時,就會調用s3c24xx_leds_fops中的相關成員函數 
  97.      * LED_MAJOR可以設為0,表示由內核自動分配主設備號 
  98.      */  
  99.     ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c24xx_leds_fops);  
  100.     if (ret < 0) {  
  101.       printk(DEVICE_NAME " can't register major number\n");  
  102.       return ret;  
  103.     }  
  104.       
  105.     printk(DEVICE_NAME " initialized\n");  
  106.     return 0;  
  107. }  
  108.   
  109. /* 
  110.  * 執行”rmmod s3c24xx_leds.ko”命令時就會調用這個函數  
  111.  */  
  112. static void __exit s3c24xx_leds_exit(void)  
  113. {  
  114.     /* 卸載驅動程序 */  
  115.     unregister_chrdev(LED_MAJOR, DEVICE_NAME);  
  116. }  
  117.   
  118. /* 這兩行指定驅動程序的初始化函數和卸載函數 */  
  119. module_init(s3c24xx_leds_init);  
  120. module_exit(s3c24xx_leds_exit);  
  121.   
  122. /* 描述驅動程序的一些信息,不是必須的 */  
  123. MODULE_AUTHOR("http://my.csdn.net/czxyhll.");        // 驅動程序的作者  
  124. MODULE_DESCRIPTION("S3C2410/S3C2440 LED Driver");   // 一些描述信息   
  125. MODULE_LICENSE("GPL");                              // 遵循的協議  
Copyright © Linux教程網 All Rights Reserved