GPIO子系统
什么是GPIO子系统?
他就是 Linux提供的中间层接口,这是一个真通用的接口之一这个接口就可以在任意的 Linux 系统下控制 GPIO 口这个功能有限 -> 只能控制 GPIO 的两大功能:输入输出
GPIO子系统结构
gpio_request();//获取/申请一个IO口使用
gpio_free();//释放不再使用这个IO口
gpio_direction_output (); // 引脚调节为输出模式gpio_direction_input (); // 调节引脚为输入模式gpio_set_value (); // 设置引脚当前的输出状态gpio_get_value (); // 获取当前引脚的状态 -> 不限制输入还是输出
函数头文件
#include <linux/gpio.h>
int gpio_request(unsigned gpio,const char*label)
//参数1,那个IO口,参数二可以随便给
voidgpio_free(unsigned gpio);
//参数引脚号
gpio_direction_output(gpio_num,value);
//参数1 IO口,参数2初值
gpio_direction_input(gpio_num);
//参数io口
gpio_set_value(gpio_num,value);
//参数 1 io口
//参数2 0/1
int gpio_get_value(gpio_num);
//参数 io口
GPIO子系统的应用->点亮一盏LED灯
方法一
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/miscdevice.h"
static int open(structinode *i,structfile *f)
{
gpio_set_value(21,1);
printk("open\r\n");
return 0;
}
static int close(structinode *i,structfile *f)
{
gpio_set_value(21,0);
printk("close\r\n");
return 0;
}
struct file_operations misc_fops={
.owner=THIS_MODULE;
.open=open;
.release=close;
};
struct miscdevice misc={
.minor=255; //系统自动分配
.name="led";
.fops=&misc_fops;
};
static int __int led_init(void)
{
gpio_request(21,"LED");
gpio_direction_output(21,0);
misc_register(&misc);
return 0;
}
static void __exit led_exit(void)
{
gpio_free(21);
misc_deregister(&misc);
}
module_init(led_init);
moudle_exit(led_exit);
MODULE_LICENSE("GPL");
方法二
#include "linux/device.h"
#include "linux/export.h"
#include "linux/kdev_t.h"
#include "linux/printk.h"
#include "linux/types.h"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/gpio.h>
int major;
static struct class *led;
static int myled_open(struct inode *inode,struct file *file)
{
return 0;
}
static ssize_t myled_write(struct file *file,const char __user *buf,size_t len,loff_t *offset)
{
char val;
unsigned long a=copy_from_user(&val,buf,1);
if(a)
{
}
else
{
}
if(val=='1')
{
printk("开灯\r\n");
gpio_set_value(21,1);
gpio_set_value(22,1);
printk("ok\r\n");
}
else
{
printk("关灯\r\n");
gpio_set_value(21,0);
gpio_set_value(22, 0);
printk("ok\r\n");
}
return 0;
}
static struct file_operations led_fops={
.owner=THIS_MODULE,
.open=myled_open,
.write=myled_write,
};
static int __init start(void)
{
major = register_chrdev(0, "myled", &led_fops);
if(major < 0)
{
printk("Failed to register major number\n");
return major;
}
printk("Major number allocated: %d\n", major);
led = class_create(THIS_MODULE, "myled_class");
device_create(led,NULL,MKDEV(major,0),NULL,"led");
gpio_request(21,"led");
gpio_request(22,"led");
gpio_direction_output(21,0);
gpio_direction_output(22,0);
return 0;
}
static void __exit stop(void)
{
gpio_free(21);
gpio_free(22);
device_destroy(led,MKDEV(major,0));
class_destroy(led);
unregister_chrdev(major,"myled");
}
module_init(start);
module_exit(stop);
MODULE_LICENSE("GPL");
方法二用
major = register_chrdev(0, "myled", &led_fops);
直接注册一个字符设备,获得一个主设备号
参数1位 主设备号填0 自动分配,参数2填设备名,参数3填文件操作结构体
然后用
static struct class *led;
led = class_create(THIS_MODULE, "myled_class");
device_create(led,NULL,MKDEV(major,0),NULL,"led");创建设备节点 /dev/led
MKDEV函数参数一为主设备号,参数2为次设备号,我们直接填0;
在卸载驱动时,注销所有节点