Linux驱动学习之点灯(四,linux2.6)

上篇最后的第二种点灯方法年代比较久远,register_chrdev()这个函数一下申请了255个设备号,不建议使用 如下图

下图的函数在linux2.6里是上图函数的升级版,不过他是静态分配,后续还得添加到cdev里

从上图函数不难发现,静态申请多个设备号,主设备号不变,次设备号++
一般我们会使用下图函数动态申请设备号,并添加到cdev里

第一个参数:无符号32位设备号的地址,申请成功后该地址空间里存放的就是设备号

第二个参数:次设备号起始地址,

第三个参数:申请设备号的数量(主设备号不变,次设备号++)

第四个参数:名字(随便给)

申请完设备号后,把它加入cdev链表里

cpp 复制代码
struct cdev cdev; //定义cdev
struct file_operations led_fops = {
    .owner=THIS_MODULE,
    .open=led_open,
    .release=led_close,
    .write=led_write,
};
cdev_init(&cdev, &led_fops);  //用文件操作结构体初始化cdev
cdev_add(&cdev, dev, 1);     //添加设备号

也可以动态分配

cpp 复制代码
struct cdev *cdev; //定义cdev
cdev=cdev_alloc();
struct file_operations led_fops = {
    .owner=THIS_MODULE,
    .open=led_open,
    .release=led_close,
    .write=led_write,
};
cdev.ops=&fops;  //用文件操作结构体初始化cdev
cdev_add(cdev, dev, 1);     //添加设备号

这里不需要cdev_init 因为cdev_alloc 跟cdev_init 内操作一样,只是少了一个操作结构体赋值,所以单独补上。
接下里就是创建/dev/led

cpp 复制代码
    struct class *led;
    led = class_create(THIS_MODULE, "myled_class");
    device_create(led,NULL,dev,NULL,"led");

完整代码

cpp 复制代码
#include "linux/device.h"
#include "linux/export.h"
#include "linux/gpio.h"
#include "linux/module.h"
#include "linux/kernel.h"
#include "linux/init.h"
#include "linux/fs.h"
#include "linux/cdev.h"
#include "linux/uaccess.h"

dev_t dev;
struct cdev cdev;
struct class *led;
static int led_open (struct inode *a, struct file *b){

    return 0;
}
static int led_close (struct inode *a, struct file *b){

    return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    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;
}
struct file_operations led_fops = {
    .owner=THIS_MODULE,
    .open=led_open,
    .release=led_close,
    .write=led_write,
};
static int __init led_init(void)
{
    //申请设备号
    int ret=  alloc_chrdev_region(&dev,0,1,"led_dev");
    if(ret<0)
    {
        return -1;   //加载失败
    }
    printk(KERN_INFO "LED driver loaded successfully\n");
    //初始化LINUX2.6 cdev结构体
    cdev_init(&cdev, &led_fops);
    cdev_add(&cdev, dev, 1);
    gpio_request(21,"led");
    gpio_direction_output(21, 0);
    gpio_request(22,"led");
    gpio_direction_output(22, 0);
    led = class_create(THIS_MODULE, "myled_class");
    device_create(led,NULL,dev,NULL,"led");

    return 0;
}
static void __exit led_exit(void)
{
    device_destroy(led, dev);
    class_destroy(led);
    cdev_del(&cdev);
    printk(KERN_INFO "LED driver unloaded successfully\n");
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
相关推荐
amazinging4 分钟前
北京-4年功能测试2年空窗-报培训班学测开-第五十天
python·学习·面试
没有羊的王K17 分钟前
SSM框架学习DI入门——day2
java·spring boot·学习
公子绝18 分钟前
JAVA学习笔记 使用notepad++开发JAVA-003
java·学习·notepad++·java开发环境
本杰明15227 分钟前
2025/7/14——java学习总结
java·开发语言·学习
LGGGGGQ4 小时前
嵌入式学习-PyTorch(4)-day21
学习
艾莉丝努力练剑5 小时前
【LeetCode&数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
c语言·开发语言·数据结构·学习·算法·leetcode·链表
人生游戏牛马NPC1号6 小时前
学习 Flutter (三):玩安卓项目实战 - 上
android·学习·flutter
没有羊的王K10 小时前
SSM框架学习——day1
java·学习
林林要一直努力11 小时前
AOSP Settings模块问题初窥
android·学习·bug·android studio
余大侠在劈柴14 小时前
pdf.js 开发指南:在 Web 项目中集成 PDF 预览功能
前端·javascript·学习·pdf