Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1760128
  • 博文数量: 1493
  • 博客积分: 38
  • 博客等级: 民兵
  • 技术积分: 5834
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-19 17:28
文章分类

全部博文(1493)

文章存档

2016年(11)

2015年(38)

2014年(137)

2013年(253)

2012年(1054)

2011年(1)

分类:

2012-05-17 08:54:41

原文地址:[字符设备]led次设备实现 作者:Domod

--led.c

点击(此处)折叠或打开

  1. #include <linux/module.h>
  2. #include <linux/types.h>
  3. #include <linux/fs.h>
  4. #include <linux/errno.h>
  5. #include <linux/mm.h>
  6. #include <linux/sched.h>
  7. #include <linux/init.h>
  8. #include <linux/cdev.h>
  9. #include <linux/device.h>
  10. #include <linux/gpio.h>
  11. #include <asm/io.h>
  12. #include <asm/module.h>
  13. #include <asm/uaccess.h>
  14. #include <mach/regs-gpio.h>
  15. #include <mach/hardware.h>


  16. #include "leddev.h"
  17. #define DEVICE_NAME "led"
  18. #define LEDDEV_MAJOR 0
  19. #define LED_NR_DEVS 4
  20. #define LEDON 0
  21. #define LEDOFF 1

  22. struct cdev *devp;

  23. static int led_major = LEDDEV_MAJOR;

  24. static struct class *led_class[LED_NR_DEVS];

  25. static unsigned long led_table[] =
  26. {
  27.     S3C2410_GPB(5),
  28.     S3C2410_GPB(6),
  29.     S3C2410_GPB(7),
  30.     S3C2410_GPB(8),
  31. };

  32. static unsigned int led_cfg_table[] =
  33. {
  34.     S3C2410_GPIO_OUTPUT,
  35.     S3C2410_GPIO_OUTPUT,
  36.     S3C2410_GPIO_OUTPUT,
  37.     S3C2410_GPIO_OUTPUT,
  38. };

  39. static int s3c2440_leds_open(struct inode *inode, struct file *filp)
  40. {
  41.     int i = iminor(inode);
  42.     filp->private_data = inode->i_cdev;
  43.     s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  44.     s3c2410_gpio_setpin(led_table[i], 0);
  45.     return 0;
  46. }

  47. static int s3c2440_leds_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
  48. {
  49.     struct cdev *dev = filp->private_data;
  50.     switch(cmd)
  51.     {
  52.         case LEDDEV_ON:
  53.             s3c2410_gpio_setpin(led_table[MINOR(dev->dev)], LEDON);
  54.             break;
  55.         case LEDDEV_OFF:
  56.             s3c2410_gpio_setpin(led_table[MINOR(dev->dev)], LEDOFF);
  57.             break;
  58.         default:
  59.             return -EINVAL;
  60.     }
  61.     return 0;
  62. }

  63. static struct file_operations dev_fops =
  64. {
  65.     .owner = THIS_MODULE,
  66.     .ioctl = s3c2440_leds_ioctl,
  67.     .open = s3c2440_leds_open,
  68. };

  69. static void s3c2440_led_setup_cdev(struct cdev *dev, int index)
  70. {
  71.     int err, devno = MKDEV(led_major, index);

  72.     cdev_init(dev, &dev_fops);
  73.     dev->owner = THIS_MODULE;
  74.     err = cdev_add(dev, devno, 1);
  75.     if (err)
  76.         printk("Error %d adding LED%d", err, index);
  77. }

  78. static int s3c2440_led_setup_device(int index)
  79. {
  80.     int devno = MKDEV(led_major, index);
  81.     char buf[100];
  82.     memset(buf, 0, 100);
  83.     sprintf(buf, "key_class%d", index);
  84.     led_class[index] = class_create(THIS_MODULE, buf);
  85.     if (IS_ERR(led_class[index]))
  86.         return -1;
  87.     device_create(led_class[index], NULL, devno, NULL, "%s%d", DEVICE_NAME, index);
  88.     return 0;
  89. }

  90. static int __init s3c2440_led_init(void)
  91. {
  92.     int result, i;
  93.     dev_t devno = MKDEV(led_major, 0);

  94.     if (led_major)
  95.         result = register_chrdev_region(devno, LED_NR_DEVS, DEVICE_NAME);
  96.     else
  97.     {
  98.         result = alloc_chrdev_region(&devno, 0, LED_NR_DEVS, DEVICE_NAME);
  99.         led_major = MAJOR(devno);
  100.         printk("Major-->%d\n", led_major);
  101.     }

  102.     if (result < 0)
  103.         return result;

  104.     devp = kmalloc(LED_NR_DEVS * sizeof(struct cdev), GFP_KERNEL);

  105.     for (i = 0; i < LED_NR_DEVS; ++i)
  106.     {
  107.         s3c2440_led_setup_cdev(&devp[i], i);
  108.         s3c2440_led_setup_device(i);
  109.     }

  110.     return result;
  111. }

  112. static void __exit s3c2440_led_exit(void)
  113. {
  114.     int i;
  115.     for (i = 0; i < LED_NR_DEVS; ++i)
  116.     {
  117.         cdev_del(&devp[i]);
  118.         device_destroy(led_class[i], MKDEV(led_major, i));
  119.         class_destroy(led_class[i]);
  120.     }
  121.     unregister_chrdev_region(MKDEV(led_major, 0), LED_NR_DEVS);
  122. }

  123. MODULE_LICENSE("GPL");
  124. MODULE_AUTHOR("Domod");
  125. module_init(s3c2440_led_init);
  126. module_exit(s3c2440_led_exit);
--leddev.h

点击(此处)折叠或打开

  1. #ifndef __LEDDEV_H__
  2. #define __LEDDEV_H__

  3. #include
  4. #define LEDDEV_IOC_MAGIC 'l'

  5. #define LEDDEV_ON _IO(LEDDEV_IOC_MAGIC, 1)
  6. #define LEDDEV_OFF _IO(LEDDEV_IOC_MAGIC, 2)

  7. #define LEDDEV_IOC_MAXNR 2

  8. #endif
--app-led.c
这部分有应付得嫌疑 ^_^

点击(此处)折叠或打开

  1. #include "leddev.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <sys/ioctl.h>
  6. #include <string.h>

  7. int main(int argc, char **argv)
  8. {
  9.     int i, on, led_no;
  10.     int fd[4];
  11.     char buf[100];
  12.     memset(buf, 0, 100);
  13.     
  14.     if (argc == 2)
  15.     {
  16.         for (i = 0; i < 4; ++i)
  17.         {
  18.             memset(buf, 0, 100);
  19.             sprintf(buf, "/dev/led%d", i);
  20.             fd[i] = open(buf, 0);
  21.             if (fd[i] < 0)
  22.             {
  23.                 perror("open device leds");
  24.                 exit(1);
  25.             }
  26.             if (sscanf(argv[1], "%d", &on) == 1 && on == 1)
  27.                 ioctl(fd[i], LEDDEV_ON, 0);
  28.             if (sscanf(argv[1], "%d", &on) == 1 && on == 0)
  29.                 ioctl(fd[i], LEDDEV_OFF, 0);
  30.         }
  31.     }
  32.     if (argc == 3)
  33.     {
  34.         sscanf(argv[1], "%d", &led_no);
  35.         sscanf(argv[2], "%d", &on);
  36.         sprintf(buf, "/dev/led%d", led_no);    
  37.         fd[led_no] = open(buf, 0);
  38.         if (on)
  39.             ioctl(fd[led_no], LEDDEV_ON, 0);
  40.         else
  41.             ioctl(fd[led_no], LEDDEV_OFF, 0);
  42.     }

  43.     for (i = 0; i < 4; ++i)
  44.     {
  45.         if (fd[i] >= 0)
  46.             close(fd[i]);
  47.     }
  48.     return 0;

  49. }
--Makefile

点击(此处)折叠或打开

  1. CFILE=app-led.c
  2. TFILE=led.ko
  3. ifneq ($(KERNELRELEASE),)

  4. obj-m := led.o

  5. else

  6. KDIR := /home/domod/arm/kernel/src/linux-2.6.32.2
  7. all:
  8. make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
  9. app:
  10. arm-linux-gcc $(CFILE) -o key
  11. sub:
  12. cp $(TFILE) ../rootfs
  13. clean:
  14. rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*

  15. endif



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