免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1086 | 回复: 0
打印 上一主题 下一主题

mini2440 LED驱动程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-22 08:51 |只看该作者 |倒序浏览
    mini2440中提供的内核自带了LED的驱动程序,但该驱动是以杂项设备的形式编写,不太适合初学者,作者因为教学工作需要,花了一点时间,根据LDD3第三章内容将代码进行了修改,希望对一些初学者有所帮助。

    注意:本案例中采用了mdev设备文件管理系统以自动生成设备节点,有兴趣的同仁可以参考本博客关于mdev的相关介绍,对于初学者,不理解的可以手动创建设备节点进行本程序的测试。

    硬件连接如下,依次对应CPU上的GPB5~GPB8引脚:
    驱动程序:
  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 <linux/gpio.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/atomic.h>
  24. #include <asm/unistd.h>

  25. #include <linux/device.h> //用于mdev操作


  26. #define DEVICE_NAME "leds"


  27. unsigned int gpio_major_number=0;
  28. struct cdev gpio_dev;
  29. struct class *gpio_class;
  30. dev_t dev_nr;


  31. static unsigned long led_table [] = {
  32. S3C2410_GPB(5),
  33. S3C2410_GPB(6),
  34. S3C2410_GPB(7),
  35. S3C2410_GPB(8),
  36. };

  37. static unsigned int led_cfg_table [] = {
  38. S3C2410_GPIO_OUTPUT,
  39. S3C2410_GPIO_OUTPUT,
  40. S3C2410_GPIO_OUTPUT,
  41. S3C2410_GPIO_OUTPUT,
  42. };

  43. static int sbc2440_leds_ioctl(
  44. struct inode *inode, 
  45. struct file *file, 
  46. unsigned int cmd, 
  47. unsigned long arg)
  48. {
  49. switch(cmd) {
  50. case 0:
  51. case 1:
  52. if (arg > 4) {
  53. return -EINVAL;
  54. }
  55. s3c2410_gpio_setpin(led_table[arg], !cmd);
  56. return 0;
  57. default:
  58. return -EINVAL;
  59. }
  60. }

  61. static struct file_operations gpio_fops = {
  62. .owner = THIS_MODULE,
  63. .ioctl = sbc2440_leds_ioctl,
  64. };

  65. static int __init dev_init(void)
  66. {
  67. int ret,i;

  68. for (i = 0; i < 4; i++) { //引脚初始化
  69. s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  70. s3c2410_gpio_setpin(led_table[i], 0);
  71. }

  72. ret = alloc_chrdev_region(&dev_nr,0,1,DEVICE_NAME); //动态分配设备号
  73. gpio_major_number = MAJOR(dev_nr);
  74. printk(KERN_INFO "Major Num ->%d\n",gpio_major_number);
  75. if (ret<0) 
  76. {
  77. printk(KERN_WARNING "gpio:can't get major number %d/n",gpio_major_number);
  78. return ret;
  79. }

  80. cdev_init(&gpio_dev,&gpio_fops); //初始化并向系统添加字符设备
  81. gpio_dev.owner = THIS_MODULE;
  82. // gpio_dev.ops   = &gpio_fops;
  83. ret = cdev_add(&gpio_dev,dev_nr,1);
  84. if (ret) 
  85. {
  86. unregister_chrdev_region(dev_nr,1);
  87. printk(KERN_NOTICE "Error %d adding gpio device/n",ret);
  88. return ret;
  89. }
  90. gpio_class = class_create(THIS_MODULE, "gpio_class"); //mdev相关,用于自动创建设备节点
  91. if(IS_ERR(gpio_class)) 
  92. {
  93. printk("Err: failed in creating class./n");
  94. return -1;
  95. }
  96. /* register your own device in sysfs, and this will cause mdev to create corresponding device node */
  97. device_create(gpio_class,NULL,dev_nr, NULL, "gpio_dev%d" ,0);//设备节点名称gpio_dev0

  98. return 0;
  99. }

  100. static void __exit dev_exit(void)
  101. {
  102. cdev_del(&gpio_dev);
  103. device_destroy(gpio_class,dev_nr);
  104. class_destroy(gpio_class);
  105. unregister_chrdev_region(dev_nr,1);
  106. }


  107. module_init(dev_init);
  108. module_exit(dev_exit);
  109. MODULE_LICENSE("GPL");
  110. MODULE_AUTHOR("Allein.Cao");
测试程序:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/ioctl.h>

  5. int main(int argc, char **argv)
  6. {
  7.         int on;
  8.         int led_no;
  9.         int fd;
  10.         if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 ||
  11.             on < 0 || on > 1 || led_no < 0 || led_no > 3) {
  12.                 fprintf(stderr, "Usage: leds led_no 0|1\n");
  13.                 exit(1);
  14.         }

  15.         fd = open("/dev/gpio_dev0", 0); //打开设备节点,需与驱动程序对应起来
  16.         if (fd < 0) {
  17.                 perror("open device leds");
  18.                 exit(1);
  19.         }
  20.         ioctl(fd, on, led_no);
  21.         close(fd);
  22.         return 0;
  23. }



您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP