9.实例剖析

本文介绍了一个简单的LED驱动程序设计案例,包括驱动程序源代码及用户应用程序,并展示了如何使用ioctl进行LED控制。

9.1实例一

9.1.1驱动程序

  1. /****************************** 
  2.  *   LED_Driver    2007/09/20         
  3.  *****************************/  
  4. #include<linux/config.h>  
  5. #include<linux/kernel.h>  
  6. #include<linux/sched.h>  
  7. #include<linux/timer.h>  
  8. #include<linux/init.h>  
  9. #include<linux/module.h>  
  10. #include<asm/hardware.h>  
  11. #defineGPIO_LED_MAJOR   97  
  12. #defineARM_GPIO_LED_DEBUG  
  13. #defineARM_GPIO_LED (GPIO96)  
  14. #defineLED_ON  0  
  15. #defineLED_OFF 1  
  16.    
  17. #definectl_GPIO_LED1 1  
  18.    
  19. #defineVERSION         "ARM_GPIO_LED_2007/09/20"  
  20.    
  21. voidshowversion(void)  
  22. {  
  23.         printk("*********************************************\n");  
  24.         printk("\t %s \t\n",VERSION);  
  25.         printk("********************************************\n\n");  
  26. }  
  27. //------------------- READ ------------------------  
  28. ssize_tGPIO_LED_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)  
  29. {  
  30.     #ifdef ARM_GPIO_LED_DEBUG  
  31.        printk ("GPIO_LED_read [--kernel--]\n");  
  32.     #endif               
  33.     return count;  
  34. }    
  35. //------------------- WRITE -----------------------  
  36. ssize_tGPIO_LED_write (struct file * file ,const char * buf, size_t count, loff_t *f_ops)  
  37. {  
  38.     #ifdef ARM_GPIO_LED_DEBUG  
  39.            printk("GPIO_LED_write [ --kernel--]\n");  
  40.         #endif  
  41.     return count;  
  42. }    
  43. //------------------- IOCTL -----------------------  
  44. ssize_tGPIO_LED_ioctl (struct inode * inode ,struct file * file, unsigned int cmd,long data)  
  45. {  
  46.     #ifdef ARM_GPIO_LED_DEBUG  
  47.            printk("GPIO_LED_ioctl [ --kernel--]\n");  
  48.         #endif  
  49.     switch (cmd)  
  50.         {  
  51.        case LED_ON : {GPCR3 |= 0x1;break;}  
  52.        case LED_OFF: {GPSR3 |= 0x1;break;}  
  53.                 default :  
  54.                         {printk ("lcdcontrol : no cmd run  [ --kernel--]\n"); return (-EINVAL);}  
  55.         }  
  56.     return 0;  
  57.     }  
  58. //------------------- OPEN ------------------------  
  59. ssize_tGPIO_LED_open (struct inode * inode ,struct file * file)  
  60. {  
  61.     #ifdef ARM_GPIO_LED_DEBUG  
  62.            printk("GPIO_LED_open [ --kernel--]\n");  
  63.         #endif  
  64.     MOD_INC_USE_COUNT;  
  65.     return 0;  
  66. }    
  67.    
  68. //------------------- RELEASE/CLOSE ---------------  
  69. ssize_tGPIO_LED_release (struct inode  * inode,struct file * file)  
  70. {  
  71.     #ifdef ARM_GPIO_LED_DEBUG  
  72.            printk ("GPIO_LED_release [ --kernel--]\n");  
  73.         #endif  
  74.     MOD_DEC_USE_COUNT;  
  75.     return 0;  
  76. }  
  77. //-------------------------------------------------  
  78. structfile_operations GPIO_LED_ctl_ops ={  
  79.     open:      GPIO_LED_open,  
  80.     read:      GPIO_LED_read,  
  81.     write:     GPIO_LED_write,  
  82.     ioctl:     GPIO_LED_ioctl,  
  83.     release:           GPIO_LED_release,  
  84. };  
  85. //------------------- INIT ------------------------  
  86. staticint __init HW_GPIO_LED_CTL_init(void)  
  87. {  
  88.     int ret = -ENODEV;  
  89.     printk("Driver Loding.....................\n\n");  
  90.     showversion();  
  91.     // init GPIO  
  92.     GPDR3 |= 0x00000001; // SET GPIO96 OUTPUTMODE  
  93.     GPSR3 |= 0x00000001; // OFF THE LED  
  94.     #ifdef ARM_GPIO_LED_DEBUG  
  95.         printk (" GPLR3=%x\n",GPLR3);  
  96.        printk (" GPDR3=%x \n",GPDR3);  
  97.         #endif  
  98.     ret = devfs_register_chrdev(GPIO_LED_MAJOR,"led_drv", &GPIO_LED_ctl_ops);  
  99.     if( ret < 0 )  
  100.     {  
  101.        printk (" ARM: init_module failedwith %d\n [ --kernel--]", ret);   
  102.        return ret;  
  103.     }  
  104.     else  
  105.     {  
  106.        printk(" ARM gpio_led_driverregister success!!! [ --kernel--]\n");  
  107.     }  
  108.     return ret;  
  109. }  
  110. staticint __init ARM_GPIO_LED_CTL_init(void)  
  111. {  
  112.     int ret = -ENODEV;  
  113.    
  114.     #ifdef ARM_GPIO_LED_DEBUG  
  115.                 printk("ARM_GPIO_LED_CTL_init [ --kernel--]\n");  
  116.         #endif  
  117.    
  118.    
  119.     ret = HW_GPIO_LED_CTL_init();  
  120.     if (ret)  
  121.       return ret;  
  122.     return 0;  
  123. }  
  124.    
  125. staticvoid __exit cleanup_GPIO_LED_ctl(void)  
  126. {  
  127.     #ifdef ARM_GPIO_LED_DEBUG  
  128.            printk("cleanup_GPIO_LED_ctl [ --kernel--]\n");  
  129.         #endif  
  130.      
  131.     devfs_unregister_chrdev (GPIO_LED_MAJOR,"gpio_led_ctl" );  
  132.      
  133. }  
  134. MODULE_DESCRIPTION("GPIO_led driver module");  
  135. MODULE_AUTHOR("zsm");  
  136. MODULE_LICENSE("GPL");//GPL协议证书信息  
  137. module_init(ARM_GPIO_LED_CTL_init);  
  138. module_exit(cleanup_GPIO_LED_ctl);  


9.1.2用户程序

在编写用户应用程序过程中,考虑通过接口open()函数打开设备,再通过接口ioctl()函数来实现对LED的控制功能。

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <fcntl.h>      // open() close()  
  5. #include <unistd.h>     // read() write()  
  6. #define DEVICE_NAME "/dev/led_drv"  
  7. #define LED_ON 0  
  8. #define LED_OFF 1  
  9. int main(void)  
  10. {  
  11.         intfd;  
  12.     int ret;  
  13.     char *i;  
  14.        printf("\nstart GPIO_led_driver test\n\n");  
  15.         fd= open(DEVICE_NAME, O_RDWR);  
  16.     printf("fd= %d\n",fd);  
  17.         if(fd == -1)  
  18.         {  
  19.                printf("open device %s error\n",DEVICE_NAME);  
  20.         }  
  21.         else  
  22.         {  
  23.        while(1)  
  24.        {   ioctl(fd,LED_OFF);  
  25.            sleep(1);  
  26.            ioctl(fd,LED_ON);  
  27.            sleep(1);  
  28.        }  
  29.        ret =close(fd);  
  30.        printf("ret=%d\n",ret);  
  31.        printf("close led_driver test\n");  
  32.         }  
  33.        return 0;  
  34. }  


9.1.3执行效果

(1)Create:

[root@OURSELEC usb]# mknod /dev/led_drv c 97 0

(2)view:

[root@OURSELEC usb]# ls -l /dev/led_drv

crw-r--r--   1 root     root      97,  0 Jan  1 01:29 /dev/led_drv

(3)insmod:

[root@OURSELEC usb]# insmod led_drv.o

Using led_drv.o

ARM_GPIO_LED_CTL_init [ --kernel--]

Driver Loding .....................                                                                               

*********************************************

        ARM_GPIO_LED_2007/09/20

*********************************************

                                                                               

 GPLR3=73e7fd

 GPDR3=1efffc3

 ARMgpio_led_driver register success!!! [ --kernel--]

(4)./test_led:

[root@OURSELEC usb]# ./test_led

                                                                             startGPIO_led_driver test

                                                                                 GPIO_LED_open[ --kernel--]

fd = 3

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_ioctl [ --kernel--]

GPIO_LED_release [ --kernel--]                                                                                 

(5) remove led_drv mode:

[root@OURSELEC usb]# rmmod led_drv

cleanup_GPIO_LED_ctl [ --kernel--]

9.2实例二

  1. /************************************* 
  2. NAME:gt2440_leds.c 
  3. COPYRIGHT:www.e-online.cc 
  4. *************************************/  
  5. #include <linux/miscdevice.h>  
  6. #include <linux/delay.h>  
  7. #include <asm/irq.h>  
  8. #include <mach/regs-gpio.h>  
  9. #include <mach/hardware.h>  
  10. #include <linux/kernel.h>  
  11. #include <linux/module.h>  
  12. #include <linux/init.h>  
  13. #include <linux/mm.h>  
  14. #include <linux/fs.h>  
  15. #include <linux/types.h>  
  16. #include <linux/delay.h>  
  17. #include <linux/moduleparam.h>  
  18. #include <linux/slab.h>  
  19. #include <linux/errno.h>  
  20. #include <linux/ioctl.h>  
  21. #include <linux/cdev.h>  
  22. #include <linux/string.h>  
  23. #include <linux/list.h>  
  24. #include <linux/pci.h>  
  25. #include <asm/uaccess.h>  
  26. #include <asm/atomic.h>  
  27. #include <asm/unistd.h>  
  28.    
  29. #define DEVICE_NAME "leds"  
  30.    
  31. /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */  
  32. #define IOCTL_LED_ON     1  
  33. #define IOCTL_LED_OFF    0  
  34.    
  35. /* 用来指定LED所用的GPIO引脚 */  
  36. static unsigned long led_table [] =  
  37. {  
  38.        S3C2410_GPB5,  
  39.        S3C2410_GPB6,  
  40.        S3C2410_GPB7,  
  41.        S3C2410_GPB8,  
  42. };  
  43.    
  44. /* 用来指定GPIO引脚的功能:输出 */  
  45. static unsigned int led_cfg_table [] =  
  46. {  
  47.        S3C2410_GPB5_OUTP,  
  48.        S3C2410_GPB6_OUTP,  
  49.        S3C2410_GPB7_OUTP,  
  50.        S3C2410_GPB8_OUTP,  
  51. };  
  52.    
  53. static int gt2440_leds_ioctl(  
  54.        structinode *inode,  
  55.        structfile *file,  
  56.        unsignedint cmd,  
  57.        unsignedlong arg)  
  58. {  
  59.        if(arg > 4)  
  60.        {  
  61.               return-EINVAL;  
  62.        }  
  63.    
  64.        switch(cmd)  
  65.        {  
  66.               caseIOCTL_LED_ON:  
  67.                      //设置指定引脚的输出电平为0  
  68.                      s3c2410_gpio_setpin(led_table[arg], 0);  
  69.                      return0;  
  70.    
  71.               caseIOCTL_LED_OFF:  
  72.                      //设置指定引脚的输出电平为1  
  73.                      s3c2410_gpio_setpin(led_table[arg], 1);  
  74.                      return0;  
  75.    
  76.               default:  
  77.                      return-EINVAL;  
  78.        }  
  79. }  
  80.    
  81. static struct file_operations dev_fops = {  
  82.        .owner    =     THIS_MODULE,  
  83.        .ioctl       =     gt2440_leds_ioctl,  
  84. };  
  85.    
  86. static struct miscdevice misc = {  
  87.        .minor= MISC_DYNAMIC_MINOR,  
  88.        .name= DEVICE_NAME,  
  89.        .fops= &dev_fops,  
  90. };  
  91.    
  92. static int __init dev_init(void)  
  93. {  
  94.        intret;  
  95.    
  96.        inti;  
  97.         
  98.        for(i = 0; i < 4; i++)  
  99.        {  
  100.               s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);  
  101.               s3c2410_gpio_setpin(led_table[i], 0);  
  102.        }  
  103.    
  104.        ret= misc_register(&misc);  
  105.    
  106.        printk(DEVICE_NAME" initialized\n");  
  107.    
  108.        returnret;  
  109. }  
  110.    
  111. static void __exit dev_exit(void)  
  112. {  
  113.        misc_deregister(&misc);  
  114. }  
  115.    
  116. module_init(dev_init);  
  117. module_exit(dev_exit);  
  118.    
  119. MODULE_LICENSE("GPL");  
  120. MODULE_AUTHOR("www.e-online.cc");  
  121. MODULE_DESCRIPTION("LEDS control forGT2440 Board");




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值