九鼎创展论坛中文版English
登录 | 立即注册 设为首页收藏本站 切换到宽版
查看: 5333|回复: 1
打印 上一主题 下一主题

x4412&ibox项目实战23-使用devfs设备文件系统创建LED驱动

[复制链接]
跳转到指定楼层
楼主
发表于 2014-9-28 09:51:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
有了上一节的基础,就可以很轻松的用register_chrdev函数实现LED驱动了。编写LED驱动及相应的应用程序,实现LED灯每一秒闪烁一次。
参考驱动源码如下:
  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <asm/uaccess.h>
  4. #include <plat/gpio-cfg.h>
  5. #include <mach/gpio.h>
  6. #include <linux/fs.h>
  7. #include <linux/device.h>

  8. #define LED_ON 0x11
  9. #define LED_OFF 0x22
  10. #define LED_MAJOR 97 //主设备号
  11. static struct class *led_class;

  12. long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  13. {
  14.          switch(cmd)
  15.          {
  16.          case LED_ON:
  17.                    gpio_set_value(EXYNOS4_GPX1(6), 0);
  18.                    gpio_set_value(EXYNOS4_GPX1(7), 0);
  19.                    gpio_set_value(EXYNOS4_GPX2(6), 0);
  20.                    gpio_set_value(EXYNOS4_GPX2(7), 0);
  21.          break;
  22.          case LED_OFF:
  23.                    gpio_set_value(EXYNOS4_GPX1(6), 1);
  24.                    gpio_set_value(EXYNOS4_GPX1(7), 1);
  25.                    gpio_set_value(EXYNOS4_GPX2(6), 1);
  26.                    gpio_set_value(EXYNOS4_GPX2(7), 1);
  27.          break;
  28.          default:break;
  29.          }
  30.          return 0;
  31. }

  32. ssize_t led_open(struct inode * inode,struct file * file)
  33. {
  34.          return 0;
  35. }

  36. ssize_t led_release(struct inode * inode, struct file * file)
  37. {
  38.          return 0;
  39. }

  40. static const struct file_operations
  41. x4412_ibox_ctl_ops={
  42.          .owner = THIS_MODULE,
  43.          .open = led_open,
  44.          .unlocked_ioctl = led_ioctl,
  45.          .release = led_release,
  46. };

  47. static int led_init(void)
  48. {
  49.          int ret = -ENODEV;
  50.          //初始化端口,GPX1_6,GPX1_7,GPX2_6,GPX2_7
  51.          ret = gpio_request(EXYNOS4_GPX1(6), "GPX1");
  52.          if(ret)
  53.                    printk("x4412-led: request gpio GPX1(6) fail\n");
  54.          s3c_gpio_setpull(EXYNOS4_GPX1(6), S3C_GPIO_PULL_UP);
  55.          gpio_direction_output(EXYNOS4_GPX1(6), 1);

  56.          ret = gpio_request(EXYNOS4_GPX1(7), "GPX1");
  57.          if(ret)
  58.                    printk("x4412-led: request gpio GPX1(7) fail\n");
  59.          s3c_gpio_setpull(EXYNOS4_GPX1(7), S3C_GPIO_PULL_UP);
  60.          gpio_direction_output(EXYNOS4_GPX1(7), 1);

  61.          ret = gpio_request(EXYNOS4_GPX2(6), "GPX2");
  62.          if(ret)
  63.                    printk("x4412-led: request gpio GPX2(6) fail\n");
  64.          s3c_gpio_setpull(EXYNOS4_GPX2(6), S3C_GPIO_PULL_UP);
  65.          gpio_direction_output(EXYNOS4_GPX2(6), 1);

  66.          ret = gpio_request(EXYNOS4_GPX2(7), "GPX2");
  67.          if(ret)
  68.                    printk("x4412-led: request gpio GPX2(7) fail\n");
  69.          s3c_gpio_setpull(EXYNOS4_GPX2(7), S3C_GPIO_PULL_UP);
  70.          gpio_direction_output(EXYNOS4_GPX2(7), 1);

  71.          /*静态方式注册驱动*/
  72.          ret = register_chrdev(LED_MAJOR, "x4412_ibox_led", &x4412_ibox_ctl_ops);
  73.          if (ret < 0)
  74.          {
  75.                    printk(KERN_ERR "x4412_ibox_led: unable to get major %d\n", ret);
  76.                    return ret;
  77.          }
  78.          //创建class
  79.          led_class = class_create(THIS_MODULE, "x4412_ibox_led");
  80.          if (IS_ERR(led_class))
  81.          {
  82.                    unregister_chrdev(LED_MAJOR, "x4412_ibox_led");
  83.                    return PTR_ERR(led_class);
  84.          }
  85.          //创建节点
  86.          device_create(led_class, NULL, MKDEV(LED_MAJOR, 0), NULL, "x4412-led");
  87.          return 0;
  88. }

  89. static int __init x4412_ibox_LED_init(void)
  90. {
  91.          int ret = -ENODEV; //调用函数
  92.          printk("x4412_ibox_LED_init\n");
  93.          ret = led_init();
  94.          if(ret)
  95.          {
  96.                    printk("x4412_ibox_LED_init fail!\n");
  97.                    return ret;
  98.          }
  99.          return 0;
  100. }

  101. static void __exit x4412_ibox_LED_exit(void)
  102. {
  103.          //注销设备
  104.          device_destroy(led_class, MKDEV(LED_MAJOR, 0));
  105.          class_destroy(led_class);
  106.          unregister_chrdev(LED_MAJOR, "x4412_ibox_led");
  107. }

  108. MODULE_LICENSE("GPL");
  109. MODULE_DESCRIPTION("liu qiming");
  110. MODULE_ALIAS_CHARDEV(LED_MAJOR, 0);
  111. module_init(x4412_ibox_LED_init);
  112. module_exit(x4412_ibox_LED_exit);
复制代码
参考应用程序源码如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #define DEVICE_NAME  "/dev/x4412-led"
  5. #define LED_ON 0x11
  6. #define LED_OFF 0x22
  7. int main(int argc,char **argv)
  8. {
  9.          int fd;
  10.          int ret;
  11.          char *i;
  12.          printf("\n x4412/ibox:start led test \r\n");
  13.          fd = open(DEVICE_NAME,O_RDWR);//Open device ,get the handle
  14.          printf("fd = %d \n",fd);
  15.          if(fd == -1)
  16.          {
  17.                    printf("open device %s error \n",DEVICE_NAME);
  18.          }
  19.          else
  20.          {
  21.                    while(1)
  22.                    {
  23.                             ioctl(fd,LED_OFF);
  24.                             sleep(1);//wait 1 second
  25.                             ioctl(fd,LED_ON);
  26.                             sleep(1);
  27.                    }
  28.                    ret = close(fd);
  29.          }
  30.          return 0;
  31. }
复制代码
       编译测试,注意观察/proc/devices文件的内容,以及/dev下生成的节点,主次设备号等。

附:做好的LED应用映像:
led (6.14 KB, 下载次数: 18)
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|深圳市九鼎创展科技官方论坛 ( 粤ICP备11028681号-2  

GMT+8, 2024-11-23 14:54 , Processed in 0.020950 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表