Smart210---LED驱动

  经过几天的学习,终于linux驱动的基本框架弄清楚了。。。真的很艰辛,,,不过终于还是熬过来了,虽然还是最基础的,,,

今晚也完成了我第一个linux驱动,,,心里还是有点小兴奋的,哈哈O(∩_∩)O

 

直接上驱动源程序吧:::

 我的开发板是Smart210,根据原理图,IO口输出0 led亮,输出1 led灭 

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
   
#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>




#define DEVICE_NAME "leds"
  /* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
  /*the second parameter that application program execute*/
  #define IOCTL_GPIO_ON         1
  #define IOCTL_GPIO_OFF        0
  /* 用来指定LED所用的GPIO引脚 */
  /*appoint the pin the LED will use*/
  static unsigned long leds_table [] =
  {
          S5PV210_GPJ2(0),
          S5PV210_GPJ2(1),
          S5PV210_GPJ2(2),
          S5PV210_GPJ2(3),
          //arch\arm\mach-s5pv210\include\mach\gpio.h
  };
  static char leds_name[][4]={{"LED1"},{"LED2"},{"LED2"},{"LED3"}};
  #define LED_NUM                ARRAY_SIZE(leds_table)
   /**
  *函数功能:打开/dev/led设备
  *fuction:open /dev/leds device
  *设备名是:/dev/leds
  *devce name: /dev/leds
  **/
  static int my_led_open(struct inode *inode, struct file *file)
  {
       int i;
       int err;
   
       for (i = 0; i < LED_NUM; i++)
       {
           err = gpio_request(leds_table[i], leds_name[i]);
                      //drivers/gpio/gpiolib.c
           if(err)
           {
              printk(KERN_ERR "failed to request S5PV210_GPH2(%d) for LED%d \n",i-1,i);
              return err;
           }
       }
   
       for (i = 0; i < LED_NUM; i++)
       {
         s3c_gpio_cfgpin(leds_table[i], S3C_GPIO_OUTPUT);//Configuration pin function:input output multiplex
         gpio_set_value(leds_table[i], 1);//Set the pin level
          //arch\arm\plat-samsung\gpio-config.c
//          gpio_direction_output(leds_table[i], 0);//write a value to GPIO port ,also set the port to output mode
//          gpio_set_value(leds_table[i], 0);
          //drivers/gpio/gpiolib.c
   
       }
      printk(KERN_INFO "LEDs driver successfully close\n");
       return 0;
  }



 static long my_led_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
    arg -= 1;
    if(arg > LED_NUM) {
        return -EINVAL;
    }

    switch(cmd) {
        case IOCTL_GPIO_ON:
            printk("led light\n");
            gpio_set_value(leds_table[arg], 0);
        break;

        case IOCTL_GPIO_OFF:
            printk("led no light\n");
            gpio_set_value(leds_table[arg], 1);
        break;

        default:
            printk("led failed\n");
            return -EINVAL;
    }
    return 0;
 }

 static int my_led_close(struct inode * inode,struct file * file)
 {
     int i;
    for(i= 0; i < LED_NUM; i++)
        gpio_free(leds_table[i]);
    printk(KERN_EMERG"close success\n");
    return 0;
 }

struct file_operations my_led_ops = {
    .owner = THIS_MODULE,
    .open  = my_led_open,
    .unlocked_ioctl = my_led_ioctl,
    .release = my_led_close,
};


static struct miscdevice led_misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops  = &my_led_ops,
};


static int __init my_led_init(void)
{
    int ret;

    ret = misc_register(&led_misc);
    if(ret) {
        printk(KERN_INFO"misc_register failed\n");
    }

    printk(KERN_INFO"misc_register sucessed\n");
    
    return 0;
}


static void __exit my_led_exit(void) {
    int i;
    misc_deregister(&led_misc);
    for(i= 0; i < LED_NUM; i++)
        gpio_free(leds_table[i]);
    printk(KERN_INFO "LEDs driver successfully exit\n");
}



module_init(my_led_init);
module_exit(my_led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("qigaohua");


 


应用程序:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>

#define IOCTL_GPIO_ON           1
#define IOCTL_GPIO_OFF          0



int main(int argc, char **argv)
{
    int fd;

    fd = open("/dev/leds",0);
    if(fd < 0) {
        printf("/dev/leds open failed\n");
        exit(1);
    }


    
    do {
        printf("/dev/leds open sucessed\n");
        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_OFF, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);        
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_ON, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);        
        sleep(1);

        ioctl(fd, IOCTL_GPIO_ON, 1);
        ioctl(fd, IOCTL_GPIO_ON, 2);
        ioctl(fd, IOCTL_GPIO_ON, 3);
        ioctl(fd, IOCTL_GPIO_ON, 4);        
        sleep(1);


        ioctl(fd, IOCTL_GPIO_OFF, 1);
        ioctl(fd, IOCTL_GPIO_OFF, 2);
        ioctl(fd, IOCTL_GPIO_OFF, 3);
        ioctl(fd, IOCTL_GPIO_OFF, 4);
    }while(0);

    close(fd);
    return 0;

}

 

posted @ 2016-04-26 08:31  Grace、  阅读(1146)  评论(0编辑  收藏  举报