Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1808837
  • 博文数量: 272
  • 博客积分: 1272
  • 博客等级: 少尉
  • 技术积分: 1866
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-09 15:51
文章分类

全部博文(272)

文章存档

2016年(16)

2015年(28)

2014年(97)

2013年(59)

2012年(25)

2011年(47)

分类:

2011-03-09 15:53:36

比原来的好,结构体指针指向更细致了 还涉及内存管理,留下有时间好好学习研究一下

转自:http://blog.sina.com.cn/s/blog_5f8665e70100pjtz.html

这段是mini2440的led Linux驱动程序代码
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/init.h>
  5. #include <linux/delay.h>
  6. #include <linux/poll.h>
  7. #include <linux/irq.h>
  8. #include <asm/irq.h>
  9. #include <linux/interrupt.h>
  10. #include <asm/uaccess.h>
  11. #include <mach/regs-gpio.h>
  12. #include <mach/hardware.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/cdev.h>
  15. #include <linux/miscdevice.h>
  16. #include <linux/sched.h>
  17. #include <linux/gpio.h>
  18. #include <linux/slab.h>
  19. #define LED_MAJOR 0
  20. #define LED_ON 1
  21. #define LED_OFF 0
  22. struct led_dev {
  23.  struct cdev cdev;
  24.  unsigned char value;
  25. };
  26. struct led_dev *led_devp;
  27. static unsigned long led_table [] = {
  28.  S3C2410_GPB(5),
  29.  S3C2410_GPB(6),
  30.  S3C2410_GPB(7),
  31.  S3C2410_GPB(8),
  32. };
  33. static unsigned int led_cfg_table [] = {
  34.         S3C2410_GPIO_OUTPUT,
  35.         S3C2410_GPIO_OUTPUT,
  36.         S3C2410_GPIO_OUTPUT,
  37.         S3C2410_GPIO_OUTPUT,
  38. };
  39. int led_major = LED_MAJOR;
  40. int led_open(struct inode *inode, struct file *filp)
  41. {
  42.  struct led_dev *dev;
  43.  dev = container_of(inode->i_cdev, struct led_dev, cdev);
  44.  filp->private_data = dev;
  45.  
  46.  return 0;
  47. }
  48. int led_release(struct inode *inode, struct file *filp)
  49. {
  50.  return 0;
  51. }
  52. ssize_t led_read(struct file *filp, char __user *buff, size_t count, loff_t *f_pos)
  53. {
  54.  struct led_dev *dev = filp->private_data;
  55.  
  56.  if(copy_to_user(buff, &(dev->value), 1))
  57.   return -EFAULT;
  58.  
  59.  return 1;
  60. }
  61. ssize_t led_write(struct file *filp, const char __user *buff, size_t count, loff_t *f_pos)
  62. {
  63.  struct led_dev *dev = filp->private_data;
  64.  if(copy_from_user(&(dev->value), buff, 1))
  65.   return -EFAULT;
  66.  if(dev->value == 1)
  67.   s3c2410_gpio_setpin(led_table[1], 0);
  68.  else
  69.   s3c2410_gpio_setpin(led_table[1], 1);
  70.  return 1;
  71. }
  72. int led_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
  73. {
  74.  struct led_dev *dev = filp->private_data;
  75.  switch(cmd) {
  76.  case LED_ON:
  77.   dev->value = 1;
  78.   s3c2410_gpio_setpin(led_table[arg], 0);
  79.   break;
  80.  case LED_OFF:
  81.   dev->value = 0;
  82.   s3c2410_gpio_setpin(led_table[arg], 1);
  83.   break;
  84.  default:
  85.   return -ENOTTY;
  86.  }
  87.  
  88.  return 0;
  89. }
  90. struct file_operations led_fops = {
  91.  .owner = THIS_MODULE,
  92.  .read = led_read,
  93.  .write = led_write,
  94.  .ioctl = led_ioctl,
  95.  .open = led_open,
  96.  .release = led_release,
  97. };
  98. static void led_setup_cdev(struct led_dev *dev, int index)
  99. {
  100.  int err, devno = MKDEV(led_major, index);
  101.  
  102.  cdev_init(&dev->cdev, &led_fops);
  103.  dev->cdev.owner = THIS_MODULE;
  104.  dev->cdev.ops = &led_fops;
  105.  
  106.  err = cdev_add(&dev->cdev, devno, 1);
  107.  if(err)
  108.   printk(KERN_NOTICE "Error %d adding LED %d\n", err, index);
  109. }
  110. int led_init(void)
  111. {
  112.  int result;
  113.         int i;
  114.         for (i = 0; i < 4; i++) {
  115.                 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
  116.                 s3c2410_gpio_setpin(led_table[i], 0);
  117.         }
  118.  dev_t dev = MKDEV(led_major, 0);
  119.  
  120.  if(led_major)
  121.   result = register_chrdev_region(dev, 1, "leds");
  122.  else {
  123.   result = alloc_chrdev_region(&dev, 0, 1, "leds");
  124.   led_major = MAJOR(dev);
  125.  }
  126.  if(result < 0)
  127.   return result;
  128.  led_devp = kmalloc(sizeof(struct led_dev), GFP_KERNEL);
  129.  if(!led_devp) {
  130.   result = -ENOMEM;
  131.   goto fail_malloc;
  132.  }
  133.  memset(led_devp, 0, sizeof(struct led_dev));
  134.  led_setup_cdev(led_devp, 0);
  135.  return 0;
  136.  fail_malloc:
  137.   unregister_chrdev_region(dev, 1);
  138.   return result;
  139. }
  140. void led_exit(void)
  141. {
  142.  cdev_del(&led_devp->cdev);
  143.  kfree(led_devp);
  144.  unregister_chrdev_region(MKDEV(led_major, 0), 1);
  145. }
  146. module_init(led_init);
  147. module_exit(led_exit);
  148. MODULE_AUTHOR("Jackie");
  149. MODULE_LICENSE("Dual BSD/GPL");

============================================================================================
以下是测试程序:
  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/leds0", 0);
  16.  if(fd < 0) {
  17.   fd = open("/dev/leds", 0);
  18.  }
  19.  if(fd < 0) {
  20.   perror("open device leds");
  21.   exit(1);
  22.  }
  23.  ioctl(fd, on, led_no);
  24.  close(fd);
  25.  return 0;
  26. }




阅读(1174) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:Linux Device Drivers笔记:第三章字符驱动1

给主人留下些什么吧!~~