转自: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. 从Objective-C转战C++ Android平台开发实践(C++/Java)

    是否使用虚拟方法 最好在不用“virtual”关键字的情况下声明所有cpp成员方法 但是在写CPP头文件时,请检查有没有父类的方法被当前的工作覆盖.如果有,请确保将这些方法改为虚拟方法. 如果从父类继 ...

  2. ImageView显示网络图片

    package com.example.urlimage; import java.io.InputStream; import java.net.HttpURLConnection; import ...

  3. 一次简单的绕过apk签名校验

    朋友发来一个apk,需要分析其中的一些算法,分析过程涉及到了重新打包apk,打包后的apk运行失败,估计是apk内部有检验是否被篡改的代码.检验apk是否被篡改,简单的方法是直接校验签名,如果apk签 ...

  4. vs2012+qt5.2.0环境搭建

    1.安装vs2012: 2.下载Qt 5.2.0 for Windows 32-bit(VS 2012, 579 MB) 和 Visual Studio Add-in 1.2.2for Qt5 注意: ...

  5. C语言文件操作

    C语言文件操作,以下以基本的例子和说明来展开怎么通过C语言来进行文件操作. 操作文件,我们得需要知道什么?当然是路径和文件名. 首先我需要知道我操作的文件在哪里,叫什么名字.在C语言中还存在一个打开方 ...

  6. Hibernate中的GetCurrentSession()方法

    从3.0.1版本开 始,Hibernate增加了SessionFactory.getCurrentSession()方法. 采用getCurrentSession()创建的session在commit ...

  7. UOJ 做题记录

    UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...

  8. 批量 kill mysql 中运行时间长的sql

    1.通过information_schema.processlist表中的连接信息生成需要处理掉的MySQL连接的语句临时文件,然后执行临时文件中生成的指令 mysql> select conc ...

  9. CentOS Linux VPS安装IPSec+L2TP VPN

    CentOS Linux VPS安装IPSec+L2TP VPN 时间 -- :: 天使羊波波闪耀光芒 相似文章 () 原文 http://www.live-in.org/archives/818.h ...

  10. meteor 为基础,联合 Apollo + React + React-Router

    Graphql with Apollo, Meteor and React: https://janikvonrotz.ch/2016/10/09/graphql-with-apollo-meteor ...