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

ops/2024/9/22 15:47:01/

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

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

从上图函数不难发现,静态申请多个设备号,主设备号不变,次设备号++

一般我们会使用下图函数动态申请设备号,并添加到cdev里

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

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

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

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

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

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);     //添加设备号

也可以动态分配

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_init(cdev, &led_fops);  //用文件操作结构体初始化cdev
cdev_add(cdev, dev, 1);     //添加设备号

接下里就是创建/dev/led

    struct class *led;led = class_create(THIS_MODULE, "myled_class");device_create(led,NULL,dev,NULL,"led");

完整代码 

#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");


http://www.ppmy.cn/ops/97652.html

相关文章

Pandas DataFrame的创建方法(Create DataFrame)

pandas是一个第三方数据分析库&#xff0c;其集成了大量的数据模型和分析工具&#xff0c;可以方便的处理和分析各类数据。其中主要对象类型有Series&#xff0c;DataFrame和Index。本文介绍DataFrame对象的基本创建方法。 关于DataFrame的基础用法&#xff0c;可以查看下面的…

AIGC 与 ChatGPT 的区别与联系

前言 在人工智能技术飞速发展的今天&#xff0c;生成式人工智能内容&#xff08;AIGC&#xff09;和对话式 AI&#xff08;如 ChatGPT&#xff09;成为了备受瞩目的话题。虽然这两者在技术基础和应用领域上有很多重叠之处&#xff0c;但它们也各自有独特的特点和用途。本文将深…

使用Go env命令设置Go的环境

前言 在进行Go开发的时候&#xff0c;设置Go的环境变量信息是必须的。下面介绍windows和Linux&#xff0c;以及Go自身提供的命令进行设置的形式 Linux的设置 In Linux or macOS, you can execute the below commands.(在Linux或者macOS&#xff0c;你可以执行下面的命令) 复制…

SI4463直接模式发送接收

终于知道程序Debug卡死在startup_stm32fxxx_hd.s问题

BaseCTF2024 WP (主要为Rev)

Rev Rev视频解析&#xff1a;[Rev0&#xff1a;从零开始的逆向生活]BaseCTF2024 Week1 Rev 讲解_哔哩哔哩_bilibili [Week1] You are good at IDA [Week1] UPX mini 脱UPX标准壳&#xff0c;解base64 [Week1] Ez Xor 简单的反向异或&#xff0c;数据动调取一下 #base_xor e…

舜宇光学科技社招校招入职测评:商业推理测验真题汇总、答题要求、高分技巧

舜宇光学科技&#xff08;集团&#xff09;有限公司&#xff0c;成立于1984年&#xff0c;是全球领先的综合光学零件及产品制造商。2007年在香港联交所主板上市&#xff0c;股票代码2382.HK。公司专注于光学产品的设计、研发、生产及销售&#xff0c;产品广泛应用于手机、汽车、…

多重示例详细说明Eureka原理实践

Eureka原理&#xff08;Eureka Principle&#xff09;是指在长时间的思考和积累之后&#xff0c;通过偶然的瞬间获得灵感或发现解决问题的方法的一种认知现象。这个过程通常包括三个主要阶段&#xff1a;准备阶段、潜伏期以及突然的灵感爆发。下面详细说明Eureka原理的实践步骤…

类与对象(中(2))

开头 大家好啊&#xff0c;上一期内容我们介绍了类与对象中六大默认成员函数中的两种--->构造函数与析构函数&#xff0c;相信大家多少都形成了自己的独到见解。那么今天&#xff0c;我将继续就拷贝构造函数与运算符重载函数来展开讲解&#xff0c;话不多说&#xff0c;我们…