zoukankan      html  css  js  c++  java
  • linux中创建gpio节点

    转自:http://blog.chinaunix.net/uid-29165999-id-4296162.html

    #define GPIO_MAJOR 230 // major device NO.
    #define GPIO_MINOR 0 // minor device NO.
    #define DEVICE_NAME "gpios"

    #define SET_OUTPUT_LOW 0
    #define SET_OUTPUT_HIGH 1
    #define GET_VALUE 2
    #define SET_INPUT 3

    static struct class *gpio_class;
    static struct gpio gpio_array[] =
    {
    { GPIO_TO_PIN(0, 0), GPIOF_OUT_INIT_LOW, "RTU_WDI_SIGNAL" },
    { GPIO_TO_PIN(0, 1), GPIOF_OUT_INIT_HIGH, "RTU_PLC_BAK_IO1"},
    };

    static int gpio_open(struct inode *inode,struct file *file)
    {
    printk(KERN_WARNING"gpio open success! ");
    return 0;
    }

    static int gpio_release(struct inode *inode, struct file *filp)
    {
    printk (KERN_ALERT "Device gpio released ");
    return 0;
    }

    static long gpio_ioctl(struct file *file,unsigned int cmd,unsigned long gpio)
    {
    int i;
    unsigned long gpio_num = (gpio/100)*16+gpio%100;
    for (i = 0; i < ARRAY_SIZE(gpio_array); i++) {
    if(gpio_array[i].gpio == gpio_num)
    goto valid_gpio;
    }
    return -1;

    valid_gpio:
    switch(cmd)//cmd表示应用程序传入的 GPIO 动作
    {
    case SET_OUTPUT_LOW://0
    {
    gpio_direction_output(gpio_num, 0);
    break;
    }
    case SET_OUTPUT_HIGH://1
    {
    gpio_direction_output(gpio_num, 1);
    break;
    }
    case GET_VALUE://2
    {
    return gpio_get_value(gpio_num);
    }
    case SET_INPUT://3
    {
    gpio_direction_input(gpio_num);
    break;
    }
    default:
    {
    printk(KERN_EMERG "GPIO command mistake!!! ");
    break;
    }
    }
    return 0;
    }

    static const struct file_operations gpio_fops =
    {
    .owner = THIS_MODULE,
    .open = gpio_open,
    .release = gpio_release,
    .unlocked_ioctl = gpio_ioctl,
    };


    //驱动加载函数
    static int __init gpio_init(void)
    {
    int ret;
    //注册一些列GPIO
    ret = gpio_request_array(gpio_array, ARRAY_SIZE(gpio_array));
    if (ret < 0)
    {
    printk(KERN_EMERG "GPIO request failed ");
    goto request_failed;
    }

    const char *name = DEVICE_NAME;
    dev_t my_dev_no;
    struct cdev *gpio_cdev;
    //分配cdev结构体
    gpio_cdev = cdev_alloc();
    if(gpio_cdev == NULL)
    {
    printk(KERN_EMERG "Cannot alloc cdev ");
    goto request_failed;
    }
    //初始化cdev结构体
    cdev_init(gpio_cdev,&gpio_fops);
    gpio_cdev->owner=THIS_MODULE;
    int result=alloc_chrdev_region(&my_dev_no,0,1,DEVICE_NAME); //动态分配设备号
    if(result < 0)
    {
    printk(KERN_EMERG "alloc_chrdev_region failed ");
    goto request_failed;
    }
    kobject_set_name(&cdev->kobj, "%s", name);
    ret=cdev_add(gpio_cdev,my_dev_no,1);
    if(ret < 0)
    {
    printk(KERN_EMERG "GPIO register failed ");
    goto request_failed;
    }

    //在sysfs文件系统下创建一个类
    gpio_class = class_create(THIS_MODULE, DEVICE_NAME);
    //在/dev中创建设备节点
    device_create(gpio_class, NULL, my_dev_no, NULL, DEVICE_NAME);
    return ret;

    request_failed:
    gpio_free_array(gpio_array, ARRAY_SIZE(gpio_array));
    return ret;
    }

    static void __exit gpio_exit(void)
    {
    device_destroy(gpio_class, MKDEV(GPIO_MAJOR, GPIO_MINOR));
    class_unregister(gpio_class);
    unregister_chrdev(GPIO_MAJOR, DEVICE_NAME);
    }

    module_init(gpio_init);
    module_exit(gpio_exit);
    MODULE_LICENSE("GPL");

  • 相关阅读:
    发送短信/邮件/打电话 code(转)
    如何学习算法
    堆和栈的区别
    2010 baidu笔试
    关于TableView中图片的延时加载(转)
    sqlite + UITableView 实现iPhone大数据浏览
    2010 Google中国笔试试题
    海量数据处理方法总结(转)
    IPhone WebApp 设计开发工具与资源(转)
    DynamicDataSet
  • 原文地址:https://www.cnblogs.com/dirt2/p/5893756.html
Copyright © 2011-2022 走看看