zoukankan      html  css  js  c++  java
  • LED字符设备驱动实例及测试代码

    驱动代码如下:

    #include <linux/kernel.h>//内核头文件
    #include <linux/init.h>//__init等
    #include <linux/module.h>//模块加载的头文件
    #include <linux/fs.h>//file_operations
    #include <linux/errno.h>//错误状态常数
    #include <linux/types.h>//size_t,ssize_t等
    
    //--------------cdev----------------
    #include <linux/cdev.h>
    
    //-------------class_create,device_create------
    #include <linux/device.h>
    
    //--------------GPIO-----------------
    #include <mach/gpio.h>
    #include <plat/gpio-cfg.h>
    #include <mach/regs-gpio.h>
    
    //-------CMD COMMAND----------------
    #define LED1_ON 0x1
    #define LED1_OFF 0x0
    
    #define DEVICE_NAME "LED1"
    
    static int led1_gpios[]=
    {
        S5PV210_MP04(4),
        S5PV210_MP04(5),
        S5PV210_MP04(6),
        S5PV210_MP04(7)
    };
    
    #define LED1_NUM ARRAY_SIZE(led1_gpios)
    
    /*用udev机制自动添加设备节点*/
    struct class *led1_class;
    
    /*设备结构体*/
    struct led1_dev_t
    {
        struct cdev cdev;
    }led1_dev;
    
    /*
    // ------------------- READ ------------------------
    ssize_t led1_read (struct file * file ,char * buf, size_t count, loff_t * f_ops)
    {
        return count;
    }    
    
    // ------------------- WRITE -----------------------
    ssize_t led1_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)
    {
        return count;
    }    
    // ------------------- OPEN ------------------------
    ssize_t led1_open (struct inode * inode ,struct file * file)
    {
        return 0;
    }    
    // ------------------- RELEASE/CLOSE ---------------
    ssize_t led1_release (struct inode  * inode ,struct file * file)
    {
        return 0;
    }
    // -------------------------------------------------
    */
    
    // ------------------- IOCTL -----------------------
    static int  led1_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, unsigned long arg)
    {
        if(arg > LED1_NUM)
        {
            printk("arg is %u ,led num is %d\n",arg,LED1_NUM);
            printk("num is err!!\n");
            return - EINVAL;
        }
        switch (cmd)
            {
            case LED1_ON: 
                {
                    /*code*/
                    gpio_set_value(led1_gpios[arg],0);
                    printk("led1 is on!!\n");
                    break;
                }
            case LED1_OFF:
                {
                    /*code*/
                    gpio_set_value(led1_gpios[arg],1);
                    printk("led1 is off!!\n");
                    break;
                }
            default :
                {
                    printk ("CMD err!!\n");
                    return - EINVAL;
                }
            }
        return 0;
        
    }
    
    
    struct file_operations led1_fops ={
    
        .owner   =  THIS_MODULE,
    //  .open    =    led1_open,
    //    .read    =    led1_read,
    //    .write   =  led1_write,
        .ioctl   =    led1_ioctl,
    //    .release =    led1_release,
    };
    
    
    // ------------------- INIT ------------------------
    static int __init led1_init(void)
    {
        printk("led num is : %d\n",LED1_NUM);
        int i,ret;
        for (i = 0; i < LED1_NUM; i++)
        {
           
            /*
            ret=gpio_request(led1_gpios[i],"LED1");
            if(ret)//注意,是ret
            {
                printk("%s:request GPIO %d for LED1 failed,ret= %d\n",DEVICE_NAME,led1_gpios[i],ret);
                return ret;
            }
            */
            s3c_gpio_cfgpin(led1_gpios[i],S3C_GPIO_SFN(1));
            gpio_set_value(led1_gpios[i],1);
        }
            
        /*init cdev*/
        cdev_init(&led1_dev.cdev,&led1_fops);
        led1_dev.cdev.owner=THIS_MODULE;
    
        /*向系统动态申请未被占用的设备号*/
        ret = alloc_chrdev_region(&led1_dev.cdev.dev,0,1,DEVICE_NAME);//int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)
        
        if (ret)
        {
            printk("register failed\n");    
            return ret;
        }
    
        /*添加字符设备*/
        ret = cdev_add(&led1_dev.cdev, led1_dev.cdev.dev, 1);
        if (ret)
        {
            printk("cdev add failed\n");    
            goto fail1;
        }
        /*udev机制可以自动添加设备节点,只需要添加xxx_class这个类,以及device_create()*/
        led1_class = class_create(THIS_MODULE, "led1_class");/*在sys目录下创建xx_class这个类,/sys/class/~*/
        if (IS_ERR(led1_class))
        {
            printk("class create failed\n");    
            goto fail2;
        }
        device_create(led1_class, NULL, led1_dev.cdev.dev, DEVICE_NAME, DEVICE_NAME);/*自动创建设备/dev/$DEVICE_NAME*/
        return ret;
    
    fail2:
        cdev_del(&led1_dev.cdev);
    fail1:
        unregister_chrdev_region(led1_dev.cdev.dev, 1);
        return ret;
    }
    
    static void __exit led1_exit(void)
    {
        int i;
        /*
        for (i = 0; i < LED1_NUM; i++)
        {
         
            gpio_free(led1_gpios[i]);
        }
        */
        device_destroy(led1_class, led1_dev.cdev.dev);
        class_destroy(led1_class);
        cdev_del(&led1_dev.cdev);
        unregister_chrdev_region(led1_dev.cdev.dev, 1);
    }
    
    module_init(led1_init);
    module_exit(led1_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("mhb@seu");

     测试代码如下:

    #include <stdio.h>
    //#include "sys/types.h"
    #include <sys/ioctl.h>
    #include <stdlib.h>
    #include <unistd.h>
    //#include "termios.h"
    //#include "sys/stat.h"
    #include <fcntl.h>
    
    #define LED1_ON 0x1
    #define LED1_OFF 0x0
    
    main(int argc,char *argv[])
    {
        int fd;
    
        if ((fd=open("/dev/LED1",O_RDWR /*| O_NDELAY | O_NOCTTY*/)) < 0)
        {
            printf("Open Device  failed.\r\n");
            exit(1);
        }
        else
        {
            printf("Open Device  successed.\r\n");
        }
        if (argc<3)
        {
            /* code */
            printf("Usage: %s <on|off num>\n",argv[0]);
            exit(2);
        }
        if(!strcmp(argv[1],"on"))
        {
            printf("led1 will on!!\n");
            printf("argv[2]=%d\n",atoi(argv[2]));
           if(ioctl(fd,LED1_ON,atoi(argv[2]))<0)
           {
               printf("ioctl err!!\n");     
           }
        
        }
        if(!strcmp(argv[1],"off"))
        {
            printf("led1 will off!!\n");
            if(ioctl(fd,LED1_OFF,atoi(argv[2]))<0)
            {
                printf("ioctl err!!\n");
            }
        }
        close(fd);
    }
  • 相关阅读:
    散列表(Hash Table)
    MVC中TextBox事件
    AJAX控制DropDownList两级联动
    唯一标示
    检查对象属性是否有空值
    foreach枚举div控制单个显示
    JS获取DropDownList其中一项的文本值
    随便
    MVC常用
    不可用输入框
  • 原文地址:https://www.cnblogs.com/hello2mhb/p/3280845.html
Copyright © 2011-2022 走看看