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!\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");

时间: 2024-08-08 16:18:13

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

Linux中的gpio口使用方法

Linux中的IO使用方法 应该是新版本内核才有的方法.请参考:./Documentation/gpio.txt文件 提供的API:驱动需要包含 #include <linux/gpio.h> 判断一个IO是否合法:int gpio_is_valid(int number); 设置GPIO的方向,如果是输出同时设置电平:/* set as input or output, returning 0 or negative errno */int gpio_direction_input(unsi

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

转自:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html 在Linux中创建静态库.a和动态库.so 我们通常把一些公用函数制作成函数库,供其它程序使用. 函数库分为静态库和动态库两种. 1. 静态函数库 这类库的名字一般是libxxx.a:利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译

Linux中 创建、挂载及卸载(包括自动挂载)文件系统

创建文件系统用 mkfs命令,结合 -t 选项来指定文件系统类型:如以下操作是把 /dev/sdb1 分区格式化为XFS文件系统 一般没有特殊情况,不会在Linux中创建或使用Windows操作系统的文件系统类型,若在Linux中创建FAT32文件系统,可结合 "-t vfat" 或 ".vfat" 选项指定类型,并添加 " -F 32" 选项指定FAT版本,例如,执行以下操作将把分区 /dev/sdb2 格式化为FAT32文件系统(需要先通过f

Linux中创建LVM逻辑卷并限制磁盘配额

本文重点:关于在Linux中如何建立物理卷.卷组最后生成逻辑卷?如何生成磁盘配额文件,启动磁盘配额,限制和使用磁盘配额. 这里再次说明一下,本人自己手写的Linux原理文档已经上传到我的下载里面地址:Linux原理解释技术文档 所以关于原理在实验里面就不在多说了,不然两天都写不了一篇(压力山大啊). 下面开始首先在虚拟机上添加三块硬盘(建议同样大小,不然就会造成不必要的浪费),添加完成之后需要重启才能生效. 1.添加三块硬盘.大小为5G,点击下面的添加根据引导添加就OK. 2.为各个硬盘创建分区

Linux中创建LVM详细步骤

1 什么事逻辑卷管理器LVM LVM: 将几个物理分区通过软件组合在一起,看起来像是独立的大硬盘,而要用这块大硬盘,就要将它分成可以使用的分区,然后格式化,挂载等 PV物理卷:将物理磁盘或物理分区初始化成LVM能用的物理卷,分区中的类型是8e:Linux LVM VG逻辑卷组:将一个或者多个PV组合成一个大的磁盘,将其称之为组 LV逻辑卷:从VG中分割出来的分区,称为LV,LV被用来格式化后,进行挂载,设备代为: /dev/vgname/lvname 2 LVM结构图 演示实验: 1 创建一个1

html综述一 -- jQuery基础使用(动态在body中创建div节点)

1 动态创建节点 详细说明请查看点击此处查看 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <title> 这是使用 jquery的第一个案例 </title> <style> .hh{ width: 200px; height:1

Linux中创建及管理 L V M逻辑卷

L V M是Linux中对磁盘分区进行管理的一种逻辑机制,建立在硬盘和分区之上,文件系统之下的一个逻辑层,要想建立 l v m 逻辑卷,必须先建立分区,并将分区改为物理卷,将多个物理卷建立成卷组,在卷组之上建立逻辑卷,它们之间的关系如下: l v m 的管理相关命令如下: 有了分区之后,创建逻辑卷的步骤如下: 逻辑卷的特性就是可扩展性强,能保持在卷上现有数据不变的情况下动态调整磁盘容量,增强了磁盘管理的灵活性,下面来看具体扩展过程: 注意:为逻辑卷扩展容量时,能够扩展的大小受限于所在卷组剩余空间

linux中文件索引节点知识

概念 索引节点     inode表中包含了文件系统所有文件列表     一个节点是在一个表项里,包含文件数据(元数据).         1.文件类型,权限,UID,GID         2.链接数(指向这个文件名路径名称个数)         3.文件的大小和时间戳         4.指向磁盘上文件的指针         5.有关文件的其他数据         6.inode 索引节点编号 inode表结构      直接块指针:有12个块直接指向对应的数据单元,每个数据单元可以容纳4K

linux中的inode节点

一.背景 传统的磁盘与文件系统的应用中,一个分区就只能够被格式化成一个文件系统,所以我们可以说一个文件系统就是一个分区.但是由于新技术的利用,例如我们常听到的LVM与软磁盘阵列(software raid),这些技术可以将一个分区格式化为多个文件系统(例如LVM),也能够将多个分区合成一个文件系统(LVM,RAID),通常我们可以称呼一个可被挂载的数据为一个文件系统而不是一个分区. 那么文件系统是怎么运行的呢?这与操作系统的数据有关.较新的操作系统的文件数据除了文件实际内容外,通常含有非常多的属