Chinaunix首页 | 论坛 | 博客
  • 博客访问: 94737
  • 博文数量: 17
  • 博客积分: 691
  • 博客等级: 上士
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-27 08:50
文章分类
文章存档

2012年(1)

2011年(16)

分类: 嵌入式

2011-08-02 14:26:37

    mini2440中提供的内核自带了LED的驱动程序,但该驱动是以杂项设备的形式编写,不太适合初学者,作者因为教学工作需要,花了一点时间,根据LDD3第三章内容将代码进行了修改,希望对一些初学者有所帮助。

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

    硬件连接如下,依次对应CPU上的GPB5~GPB8引脚:
    驱动程序:
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12. #include
  13. #include
  14. #include
  15. #include
  16. #include
  17. #include
  18. #include
  19. #include
  20. #include
  21. #include
  22. #include
  23. #include
  24. #include

  25. #include //用于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. }



阅读(1592) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~