linux环境下LED驱动编程一例

效果:流水灯

 

led_drv.h

 

   1:  #ifndef __LED_DRV_H__
   2:  #define __LED_DRV_H__
   3:   
   4:  struct led_cmd
   5:  {
   6:      int status;
   7:      int num;
   8:  };
   9:   
  10:  #define LED_ALL_ON _IOW('L',0,int)
  11:  #define LED_ALL_OFF _IOW('L',1,int)
  12:  #define LED_S_ON _IOW('L',2,int)
  13:  #define LED_S_OFF _IOW('L',3,int)
  14:   
  15:   
  16:  #endif

 

led_drv.c

 

   1:  #include <linux/module.h>
   2:  #include <linux/kernel.h>
   3:  #include <linux/fs.h>
   4:  #include <linux/cdev.h>
   5:  #include <asm/io.h>
   6:  #include "led_drv.h"
   7:   
   8:  MODULE_LICENSE("GPL");
   9:  static struct led_dev
  10:  {
  11:      struct cdev cdev;
  12:      void *map_con;
  13:      void *map_data;
  14:      dev_t devno;
  15:   
  16:  }my_led_dev;
  17:   
  18:   
  19:  static int led_open(struct inode *inode, struct file *file)
  20:  {
  21:      printk(KERN_INFO "led opened\n");
  22:      return 0;
  23:  }
  24:   
  25:  static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
  26:  {
  27:  //    LED_CMDP cmd = (LED_CMDP)buf;
  28:      struct led_cmd *cmd = (struct led_cmd *)buf;
  29:      if(cmd->status == 0)
  30:      {
  31:          writel(readl(my_led_dev.map_data) & (~(0x1<<(cmd->num))), my_led_dev.map_data);  
  32:      }
  33:      else
  34:      {
  35:   
  36:          writel(readl(my_led_dev.map_data) | (0x1<<(cmd->num)), my_led_dev.map_data);  
  37:      }
  38:      return 0;
  39:  }
  40:  static int led_close (struct inode *inode , struct file *file)
  41:  {
  42:      printk(KERN_INFO "led closed\n");
  43:      return 0;
  44:  }
  45:   
  46:  static int led_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg)
  47:  {
  48:      switch (cmd)
  49:      {
  50:   
  51:      case LED_ALL_ON:
  52:          writel((readl(my_led_dev.map_data) | 0xf), my_led_dev.map_data);  
  53:          break;
  54:      case LED_ALL_OFF:
  55:          writel((readl(my_led_dev.map_data) & (~0xf)), my_led_dev.map_data);  
  56:          break;
  57:      case LED_S_ON:
  58:          writel((readl(my_led_dev.map_data) | (0x1<<arg)), my_led_dev.map_data);  
  59:          break;
  60:      case LED_S_OFF:
  61:          writel((readl(my_led_dev.map_data)) & (~(0x1<<arg)), my_led_dev.map_data);  
  62:          break;
  63:      default:
  64:          return -EINVAL;
  65:      }
  66:   
  67:      return 0;
  68:  }
  69:  static struct file_operations led_fops =
  70:  {
  71:      .owner = THIS_MODULE,
  72:      .open = led_open,
  73:      .release = led_close,
  74:      .write = led_write,
  75:      .ioctl = led_ioctl
  76:  };
  77:   
  78:   
  79:  int led_init(void)
  80:  {
  81:   
  82:      int ret;
  83:      my_led_dev.devno = MKDEV(250, 0);
  84:   
  85:      ret = register_chrdev_region(my_led_dev.devno,1, "pengdonglin");
  86:   
  87:      if(ret < 0)
  88:      {
  89:          return ret;
  90:      }
  91:   
  92:      cdev_init(&my_led_dev.cdev, &led_fops);    
  93:      my_led_dev.cdev.owner = THIS_MODULE;
  94:      ret = cdev_add(&my_led_dev.cdev, my_led_dev.devno, 1);
  95:      if(ret)
  96:      {
  97:          return ret;    
  98:      }
  99:  /*
 100:      my_led_dev.map_con = ioremap(0xe03001c0, 4); 
 101:      my_led_dev.map_data = ioremap(0xe03001c4, 4); 
 102:  */    
 103:      my_led_dev.map_con = ioremap(0xe03001c0, 8); 
 104:      my_led_dev.map_data = my_led_dev.map_con + 4 ; 
 105:   
 106:      writel((readl(my_led_dev.map_con) & (~0xffff)) | 0x1111, my_led_dev.map_con);  
 107:      writel((readl(my_led_dev.map_data) & (~0xf))|0xf, my_led_dev.map_data);  
 108:   
 109:      printk(KERN_INFO "init led\n");
 110:   
 111:      return 0;
 112:  }
 113:   
 114:  void led_exit(void)
 115:  {
 116:      iounmap(my_led_dev.map_data); 
 117:      iounmap(my_led_dev.map_con); 
 118:      cdev_del(&my_led_dev.cdev);
 119:      unregister_chrdev_region(my_led_dev.devno,1);
 120:      printk(KERN_INFO "led exit\n");
 121:  }
 122:   
 123:  module_init(led_init);
 124:  module_exit(led_exit);

 

 

Makefile

 

   1:  $(warning KERNELRELEASE=$(KERNELRELEASE))
   2:  ifeq ($(KERNELRELEASE),)
   3:   
   4:  KERNELDIR ?= /home/linux/arm/linux-2.6.35/
   5:   
   6:  #KERNELDIR ?= /lib/modules/$(shell uname -r)/build  
   7:  PWD := $(shell pwd)
   8:   
   9:  modules:
  10:      $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
  11:   
  12:  modules_install:
  13:      $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
  14:   
  15:  clean:
  16:      rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module* modules*
  17:   
  18:  .PHONY: modules modules_install clean
  19:   
  20:  else
  21:      obj-m := led_drv.o
  22:  endif
  23:   

 

led_test.c

 

   1:  #include <stdio.h>
   2:  #include <sys/types.h>
   3:  #include <sys/stat.h>
   4:  #include <fcntl.h>
   5:  #include <stdlib.h>
   6:  #include <sys/ioctl.h>
   7:  #include "led_drv.h"
   8:   
   9:  int main(void)
  10:  {
  11:      int fd;
  12:      int num = 0;
  13:      struct led_cmd led = {
  14:          1,0
  15:      };
  16:   
  17:      printf("start!\n");
  18:   
  19:      if((fd = open("/dev/led", O_RDWR)) < 0)
  20:      {
  21:          perror("open error\n");
  22:          exit(-1);
  23:      }
  24:      write(fd, &led, 1);
  25:      sleep(1);
  26:   
  27:      ioctl(fd, LED_ALL_ON,0);    
  28:   
  29:      sleep(1);
  30:      ioctl(fd, LED_ALL_OFF,0);    
  31:   
  32:      while(1)
  33:      {
  34:          usleep(50000);
  35:          ioctl(fd, LED_S_ON,num);    
  36:          usleep(50000);
  37:          ioctl(fd, LED_S_OFF,num);    
  38:          num = (++num) % 4;
  39:      }
  40:   
  41:      close(fd);
  42:      return 0;
  43:  }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/pengdonglin137/p/3038575.html