Linux驱动编程实践之LED驱动


开发板:TQ2440

内核:2.6.30.4-EmbedSky

实现目标:控制led开关,并当前读取状态

-------驱动实现  mini2440_leds.c-------

  1. #include <linux/miscdevice.h>   
  2. #include <linux/delay.h>   
  3. #include <asm/irq.h>   
  4. #include <mach/regs-gpio.h>   
  5. #include <mach/hardware.h>   
  6. #include <linux/kernel.h>   
  7. #include <linux/module.h>   
  8. #include <linux/init.h>   
  9. #include <linux/mm.h>   
  10. #include <linux/fs.h>   
  11. #include <linux/types.h>   
  12. #include <linux/delay.h>   
  13. #include <linux/moduleparam.h>   
  14. #include <linux/slab.h>   
  15. #include <linux/errno.h>   
  16. #include <linux/ioctl.h>   
  17. #include <linux/cdev.h>   
  18. #include <linux/string.h>   
  19. #include <linux/list.h>   
  20. #include <linux/pci.h>   
  21. #include <asm/uaccess.h>   
  22. #include <asm/atomic.h>   
  23. #include <asm/unistd.h>   
  24.   
  25.   
  26. #define DEVICE_NAME "leds"   //要操作的设备名称,加载成功后在/dev/下出现   
  27. //操作的4个led   
  28. static unsigned long led_table [] = {  
  29.  S3C2410_GPB5,  
  30.  S3C2410_GPB6,  
  31.  S3C2410_GPB7,  
  32.  S3C2410_GPB8,  
  33. };  
  34. //输出   
  35. static unsigned int led_cfg_table [] = {  
  36.  S3C2410_GPB5_OUTP,  
  37.  S3C2410_GPB6_OUTP,  
  38.  S3C2410_GPB7_OUTP,  
  39.  S3C2410_GPB8_OUTP,  
  40. };  
  41.   
  42. /*static unsigned int led_cfg_table1 [] = { 
  43.  S3C2410_GPB5_INP, 
  44.  S3C2410_GPB6_INP, 
  45.  S3C2410_GPB7_INP, 
  46.  S3C2410_GPB8_INP, 
  47. };*/  
  48.   
  49. static int sbc2440_leds_ioctl(  
  50.  struct inode *inode,   
  51.  struct file *file,   
  52.  unsigned int cmd,   
  53.  unsigned long arg)  
  54. {  
  55.         unsigned char i,tmp;           
  56.   
  57.  switch(cmd) {  
  58.  case 0:  
  59.  case 1:  
  60.   if (arg > 4) {  
  61.    return -EINVAL;  
  62.   }  
  63.   s3c2410_gpio_cfgpin(led_table[arg], led_cfg_table[arg]);  
  64.   s3c2410_gpio_setpin(led_table[arg], !cmd); //关或开   
  65.   return 0;  
  66.  case 2:    
  67.   tmp = s3c2410_gpio_getpin(led_table[arg]); //读取状态   
  68.                 tmp = tmp >>(arg+5);  
  69.   
  70.   return (unsigned int)tmp;  
  71.  default:  
  72.   return -EINVAL;  
  73.  }  
  74. }  
  75.   
  76. static struct file_operations dev_fops = {  
  77.  .owner = THIS_MODULE,  
  78.  .ioctl = sbc2440_leds_ioctl,  
  79. };  
  80. //混杂结构   
  81. static struct miscdevice misc = {  
  82.  .minor = MISC_DYNAMIC_MINOR,  
  83.  .name = DEVICE_NAME,  
  84.  .fops = &dev_fops,  
  85. };  
  86.   
  87. static int __init dev_init(void)  
  88. {  
  89.  int ret;  
  90.   
  91.  int i;  
  92.  //初始化四个led,并打开   
  93.  for (i = 0; i < 4; i++) {  
  94.   s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);  
  95.   s3c2410_gpio_setpin(led_table[i], 0);  
  96.  }  
  97.   
  98.  ret = misc_register(&misc);  
  99.   
  100.  printk (DEVICE_NAME"\tinitialized\n");  
  101.   
  102.  return ret;  
  103. }  
  104.   
  105. static void __exit dev_exit(void)  
  106. {  
  107.  misc_deregister(&misc);  
  108. }  
  109.   
  110. module_init(dev_init);  
  111. module_exit(dev_exit);  
  112. MODULE_LICENSE("GPL");  
  113. MODULE_AUTHOR("FriendlyARM Inc.");  

======应用程序app-led.c======

  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3. #include <unistd.h>   
  4. #include <sys/ioctl.h>   
  5.   
  6. int main(int argc, char **argv)  
  7. {  
  8.     int on;  
  9.     int led_no;  
  10.     int fd;  
  11.     if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||  
  12.             on < 0 || on > 2 || led_no < 0 || led_no > 3) {  
  13.         fprintf(stderr, "Usage: leds led_no 0|1|2\n");  
  14.         exit(1);  
  15.     }  
  16.     fd = open("/dev/leds", 0);  
  17.     if (fd < 0) {  
  18.         perror("open device leds");  
  19.         exit(1);  
  20.     }  
  21.     if(on==2) //读取led状态   
  22.     {  
  23.         printf("state:=%d\n",ioctl(fd, on, led_no));  
  24.     }  
  25.     else      //控制led开或关,即0,1   
  26.     {  
  27.         ioctl(fd, on, led_no);  
  28.     }    
  29.     close(fd);  
  30.     return 0;  
  31. }  

=========Makefile==========

  1. ifneq ($(KERNELRELEASE),)  
  2.   
  3. obj-m := mini2440_leds.oelse   
  4. KDIR := /opt/guoqian/opt/EmbedSky/linux-2.6.30.4  
  5.   
  6. all:  
  7.  make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-  
  8. clean:  
  9.  rm -f *.ko *.o *.mod.o *.mod.c *.symvers  modul*  
  10. endif  

=======操作结果======
[root@EmbedSky /tmp]# insmod mini2440_leds.ko
[root@EmbedSky /tmp]# ./app-led 1 2
state:=0
[root@EmbedSky /tmp]# ./app-led 1 0
[root@EmbedSky /tmp]# ./app-led 1 2
state:=1
[root@EmbedSky /tmp]#

相关内容