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

server/2024/11/9 17:08:55/

上篇最后的第二种点灯方法年代比较久远,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/server/103692.html

相关文章

三、Socket多路复用介绍

一、Socket连接方式 二、多路复用 三、Socket连接包含的内容

操作系统

1.Linux中根目录下的目录有哪些&#xff1f; bin目录 存放二进制文件&#xff0c;一般是常用的一些指令 sbin目录 su管理员才能访问的二进制文件&#xff0c;一般是得用su才能使用的指令 home目录 家目录&#xff0c;存放的是除了root用户以外其他用户的家目录 etc目录 …

网络编程day6

1、C语言中指针数组和数组指针的区别&#xff1f; 指针数组本质上是个数组&#xff0c;其中各个元素都是指针变量 数组指针本质上是个指针变量&#xff0c;其储存的地址为数组的地址 2、结构体字节对齐 字节对齐的原则有两个&#xff1a; 1、结构体中的每个成员在分配内存时…

【文献及模型、制图分享】多期DID模型之高铁网络化对区域城市商服用地价格的影响——以长三角为例

文献介绍 高铁作为一种快速、高效的现代化交通工具&#xff0c;其网络化进程深刻影响着区域经济发展和空间结构演变。基于2009—2019年长三角地区215个县级及以上研究单元铁路数据、城市社会经济数据及商服用地交易数据&#xff0c;构建高铁开通、可达性、连通性等指标&#x…

利用贝叶斯和决策树 来进行医疗诊断的

要使用Python实现一个基于贝叶斯分类器和决策树的医疗诊断功能&#xff0c;我们需要构建一个模型&#xff0c;该模型可以根据病人描述的症状预测可能的病症。这个模型将利用贝叶斯分类器和决策树来进行预测。以下是一个基本的实现思路&#xff1a; 数据准备&#xff1a;我们需要…

SpringBoot事务-调度-缓存

一.Spring Boot中的事务管理 设置事务 Transactional(isolation Isolation.DEFAULT) Transactional(propagation Propagation.REQUIRED) 开启事务 EnableTransactionManagement 1. 开启事务管理 要开启 Spring 的事务管理&#xff0c;你需要在你的 Spring Boot 应用中添加 …

深入理解逻辑回归

深入理解逻辑回归 文章目录 深入理解逻辑回归什么是逻辑回归&#xff1f;Sigmoid 函数几率&#xff08;Odds&#xff09;与对数几率&#xff08;Logit&#xff09;函数为什么使用对数几率函数&#xff1f;总结 逻辑回归&#xff08;Logistic Regression&#xff09;是机器学习和…

C++ | Leetcode C++题解之第344题反转字符串

题目&#xff1a; 题解&#xff1a; class Solution { public:void reverseString(vector<char>& s) {int n s.size();for (int left 0, right n - 1; left < right; left, --right) {swap(s[left], s[right]);}} };