转自: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. Laravel 5.1 文档攻略 —— Eloquent:模型对象序列化

    在写api的时候,数据一般是以json格式进行传输的,没有对象可以直接使用.这个时候,对数据的序列化转换就很重要,Eloquent提供了很方便的方法和约定,不仅可以转换,还可以控制里面的键值. 基本用 ...

  2. C#高级编程笔记 Day 1, 2016年8月 30日 名词定义

    1.C# 中的命名空间 namespace,我觉得和Java中的package 差不多,相当于一个"包" 一样. 2.修饰符 static 修饰方法表示方法不能在类的实例化上执行, ...

  3. am等adb命令小总结

    本文的am部分参考了:http://www.cnblogs.com/dyllove98/archive/2013/07/08/3178094.html 的博客 今天研究adb的时候发现在pc端也可以启 ...

  4. INI文件的读取(C语言:GetPrivateProfileString/GetPrivateProfileInt)

    INI文件格式说明 /********************************************* ini文件说明 ini文件是文本文件,由节点(Section)和键值对(key=val ...

  5. func_num_args, func_get_arg, func_get-args 的区别与用法

    func_num_args 返回传递给函数的参数个数 <?php header("Content-Type: text/html; charset=UTF-8"); func ...

  6. django xadmin 模板的定制

    编辑新增等页面对应的modelform为ModelFormAdminView (xadmin.views.edit.ModelFormAdminView) 通过源码分析,新增对象的template属性 ...

  7. postgresql 函数&存储过程 ; 递归查询

    函数:http://my.oschina.net/Kenyon/blog/108303 紧接上述,补充一下: 输入/输出参数的函数demo(输入作为变量影响sql结果,输出作为结果返回) create ...

  8. py代码模糊工具

    https://github.com/astrand/pyobfuscate 使用方法,调用下图文件即可,方法 python  pyobfuscate.py your_code.py 即可输出在cmd ...

  9. phpcms评论的url替换问题

    在整个项目改ip之前,评论里的url是127.0.1.113 改成localhost之后,更新了所有的url和缓存,但是v9_comment表中的url字段没有更新. 想一下后台只有一个地方是替换数据 ...

  10. REACT 学习

    1.React/React Native 的ES5 ES6写法对照表 http://bbs.reactnative.cn/topic/15/react-react-native-%E7%9A%84es ...