Linux驱动学习之点灯(三)

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;

在卸载驱动时,注销所有节点

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值