转自: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!\n");
return 0;
}

static int gpio_release(struct inode *inode, struct file *filp)
{
printk (KERN_ALERT "Device gpio released\n");
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!!!\n");
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\n");
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\n");
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\n");
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\n");
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");

linux中创建gpio节点的更多相关文章

  1. 在Linux中创建静态库.a和动态库.so

    转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用 ...

  2. 在Linux中创建静态库和动态库

    我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 静态库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库. 动态库在程序编译时并不会被连接到目标代码中 ...

  3. 在Linux中创建静态库和动态库 (转)

    我们通常把一些公用函数制作成函数库,供其它程序使用.函数库分为静态库和动态库两种.静态 库在程序编译时会被连接到目标代码中,程序运行时将不再需要该静态库.动态库在程序编译时并不会被连接到目标代码中,而 ...

  4. Labview中创建属性节点和调用节点的用法

    创建属性节点 个人感觉有点像C中的指针 创建调用节点

  5. Linux中创建Daemon进程的三种方法

    什么是daemon进程? Unix/Linux中的daemon进程类似于Windows中的后台服务进程,一直在后台运行运行,例如http服务进程nginx,ssh服务进程sshd等.注意,其英文拼写为 ...

  6. linux中创建和解压文档的 tar 命令教程

    linux & zip & tar https://www.cnblogs.com/xgqfrms/p/9714161.html 1 linux中的tar命令 tar(磁带归档)命令是 ...

  7. Linux中的gpio口使用方法

    Linux中的IO使用方法 应该是新版本内核才有的方法.请参考:./Documentation/gpio.txt文件 提供的API:驱动需要包含 #include <linux/gpio.h&g ...

  8. 在linux上创建slave节点

    在slave机器上创建一登录用户,步骤如下: 切换至/usr/sbin目录,执行useradd -m test007  -d /home/test007,test007就是我们所创建的用户 执行su+ ...

  9. Linux中创建自己的欢迎登陆界面

    /etc 在Linux中相当于Windows的注册表 修改其中文件可以影响整个Linux系统 MOTD motd:message of the day /etc/motd /etc/motd文件作用是 ...

随机推荐

  1. 1.xrange和range不要混了,2.range(len(xx))不如用enumerate

    range()是列表, xrange()是迭代 >>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i i ...

  2. [POJ1068]Parencodings

    [POJ1068]Parencodings 试题描述 Let S = s1 s2...s2n be a well-formed string of parentheses. S can be enco ...

  3. Oracle Database 11g Express Edition学习笔记

    修改字符集 使用用户system,通过sqlplus程序连接到Oracle数据库,输入以下命令,查看字符集: SQL> select userenv('language') from dual; ...

  4. 剑指Offer 二叉树中和为某一值的路径(dfs)

    题目描述 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.     思路: 递归,然后深搜,因为题目定义的, ...

  5. Android 中的消息传递,详解广播机制

    --------------------------------------广播机制简介--------------------------------------------- Android中的广 ...

  6. 补上题代码 hdu1520

    #include<iostream> #include<cmath> #include<algorithm> #include<vector> #inc ...

  7. python自动化之装饰器

    1 高阶函数 满足下列条件之一就可成函数为高阶函数 某一函数当做参数传入另一个函数中 函数的返回值包含n个函数,n>0 高阶函数示范 def bar(): print 'in the bar' ...

  8. C#的contextMenuStrip右键没反应的可能原因

    contextMenuStrip设置右键菜单,但是新手常常忽略一个问题,我要遇到了,即没有设置contextMenuStrip所在控件的contextMenuStrip属性,需要把contextMen ...

  9. PHP 面向对象:抽象类继承抽象类

    抽象类继承另外一个抽象类时,不用重写其中的抽象方法.抽象类中,不能重写抽象父类的抽象方法.这样的用法,可以理解为对抽象类的扩展. 下面的例子,演示了一个抽象类继承自另外一个抽象类时,不需要重写其中的抽 ...

  10. js隐藏div和class

    <style type="text/css"> //div用点//class# .footer {  display:none;  } #footer {  displ ...