Johannes 《Linux内核模块与设备驱动开发:编写Linux驱动程序》 (7)open,release (8) write read
视频资料https://www.bilibili.com/video/BV18SE26cEjn?spm_id_from333.788.videopod.sectionsvd_source92b7efa4daa5bb4fdcdc9f2db97c307bp4代码https://github.com/Johannes4Linux/Linux_Driver_Tutoriallesson7 字符设备的打开和释放lesson8 字符设备的读取和写入其实这两课和lesson5程序很接近不过Johannes 在内核层之外还提供了应用层测试的例程。lesson7 内核层 hello_cdev.c#include linux/module.h #include linux/init.h #include linux/fs.h static int major; //inode 表示内核设备文件的结构体靠它来获得主/附设备号flip 代表打开的设备文件 static int my_open(struct inode *inode, struct file *filp) { //主设备号 imajor(inode) iminor(inode) imajor/iminor 都是宏 pr_info(hello_cdev - Major: %d, Minor %d\n, imajor(inode), iminor(inode)); //当前打开文件的位置 pr_info(hello_cdev - filp-f_pos: %lld\n, filp-f_pos); //设备文件的权限 ls -lh 命令里面的 rwx pr_info(hello_cdev - filp-f_mode: 0x%x\n, filp-f_mode); //设备文件的标志位 比如层test.c 里面的 O_RDWR/O_WRONLY 等 pr_info(hello_cdev - filp-f_flags: 0x%x\n, filp-f_flags); return 0; } static int my_release(struct inode *inode, struct file *filp) { pr_info(hello_cdev - File is closed\n); return 0; } //设备文件支持的设备操作这里只有open/release 操作 static struct file_operations fops {//实例化fops .open my_open, .release my_release, }; static int __init my_init(void) { major register_chrdev(0, hello_cdev, fops);//注册字符设备 if (major 0) { pr_err(hello_cdev - Error registering chrdev\n); return major; } pr_info(hello_cdev - Major Device Number: %d\n, major); return 0; } static void __exit my_exit(void) { unregister_chrdev(major, hello_cdev); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Johannes 4Linux); MODULE_DESCRIPTION(A sample driver for registering a character device);和lesson5 对比十分类似lesson5 只实例化了.read 读这里有实例化.open/.release视频开始的9分钟对于设备文件这些做了相关说明。视频第十分钟做了个应用层的程序test.c说明看看代码就行略过。#include stdio.h #include stdlib.h #include unistd.h #include fcntl.h int main(int argc, char **argv) { int fd; if (argc 2) { printf(I need the file to open as an argument!\n); return 0; } fd open(argv[1], O_RDONLY); if (fd 0) { perror(open); return fd; } close (fd); fd open(argv[1], O_RDWR | O_SYNC); if (fd 0) { perror(open); return fd; } close (fd); fd open(argv[1], O_WRONLY | O_NONBLOCK); if (fd 0) { perror(open); return fd; } close (fd); return 0; }两个程序都写完了视频开始编译驱动程序insmod之后mknod /dev/hello0 从236 0 mknod /dev/hello0 236 10 ; 这就造了两个字符设备 /dev/hello0 ,主设备号236,次设备号分别是0,10最后在应用层跑测试分别做这两个字符设备打印不同的次设备号不同模式表明测试程序成功。mknod 生成设备文件现在已经不推荐了不过linux还保留这个方法。这几个课程加起来就是对字符设备常用的操作开关读写的操作构成了字符设备的开发架构。我认为字符设备其实都可以理解为在这个架构上开发的。综合lesson3/lesson7 仿照写一个字符设备控制led开关的程序#include linux/module.h #include linux/init.h #include linux/fs.h #include linux/gpio/consumer.h static int major; static struct gpio_desc *led; #define IO_LED 21 #define IO_OFFSET 0 static int my_open(struct inode *inode, struct file *filp) { int status; led gpio_to_desc(IO_LED IO_OFFSET); if (!led) { printk(gpioctrl - Error getting pin %d\n, IO_LED); return -ENODEV; } status gpiod_direction_output(led, 0); if (status) { printk(gpioctrl - Error setting pin %d to output\n, IO_LED); return status; } gpiod_set_value(led, 1); return 0; } static int my_release(struct inode *inode, struct file *filp) { gpiod_set_value(led, 0); pr_info(hello_cdev - File is closed\n); return 0; } static struct file_operations fops { .open my_open, .release my_release, }; static int __init my_init(void) { major register_chrdev(0, hello_cdev, fops); if (major 0) { pr_err(hello_cdev - Error registering chrdev\n); return major; } pr_info(hello_cdev - Major Device Number: %d\n, major); return 0; } static void __exit my_exit(void) { unregister_chrdev(major, hello_cdev); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(DOK); MODULE_DESCRIPTION(A sample driver for led);lesson8 代码#include linux/module.h #include linux/init.h #include linux/fs.h static int major; static char text[64];//文本缓冲区 //flip 打开的设备文件 user_buf 数据空指针本例没用 len 缓冲区长度 off 文件位置偏移里 static ssize_t my_read(struct file *filp, char __user *user_buf, size_t len, loff_t *off) { /* not_copied 从应用层读取的字符长度 to_copy (len *off) sizeof(text) ? len : (sizeof(text) - *off) 计算需要复制的可复制字符长度确保文本缓冲区位置不溢出 delta to_copy-not_copied 文本指针移动长度 */ int not_copied, delta, to_copy (len *off) sizeof(text) ? len : (sizeof(text) - *off); pr_info(hello_cdev - Read is called, we want to read %ld bytes, but actually only copying %d bytes. The offset is %lld\n, len, to_copy, *off); if (*off sizeof(text)) return 0; //复制文本缓冲区内容到用户空间user_buf文本缓冲区 text(*off)文本当前位置 to_copy 复制长度 not_copied copy_to_user(user_buf, text[*off], to_copy); delta to_copy - not_copied; if (not_copied) pr_warn(hello_cdev - Could only copy %d bytes\n, delta); *off delta; return delta; } static ssize_t my_write(struct file *filp, const char __user *user_buf, size_t len, loff_t *off) { int not_copied, delta, to_copy (len *off) sizeof(text) ? len : (sizeof(text) - *off); pr_info(hello_cdev - Write is called, we want to write %ld bytes, but actually only copying %d bytes. The offset is %lld\n, len, to_copy, *off); if (*off sizeof(text)) return 0; not_copied copy_from_user(text[*off], user_buf, to_copy); delta to_copy - not_copied; if (not_copied) pr_warn(hello_cdev - Could only copy %d bytes\n, delta); *off delta; return delta; } static struct file_operations fops { .read my_read, .write my_write }; static int __init my_init(void) { //动态配置字符设备不需要设备号 major register_chrdev(0, hello_cdev, fops); if (major 0) { pr_err(hello_cdev - Error registering chrdev\n); return major; } printk(hello_cdev - Major Device Number: %d\n, major); return 0; } static void __exit my_exit(void) { unregister_chrdev(major, hello_cdev); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(Johannes 4Linux); MODULE_DESCRIPTION(A sample driver for registering a character device);重点了解 copy_to_user /copy_from_user 两个函数实现应用层的读写控制内核层这个和正点原子里面led 读写驱动很像了

相关新闻

Python图形学实战:从零编码生成动漫风格图像与动画

Python图形学实战:从零编码生成动漫风格图像与动画

1. 项目概述:用Python“画”出二次元世界 最近几年,AI绘画的火爆让很多人觉得,生成一张动漫风格的图片,似乎只需要输入几个关键词,点一下鼠标就能完成。但作为一个从零开始用代码“画”过不少动漫角色的程序员&#xf…

2026/7/30 13:43:31 阅读更多 →
从零构建C++文本编辑器:Qt实战与核心架构解析

从零构建C++文本编辑器:Qt实战与核心架构解析

1. 项目概述:从零构建一个C文本编辑器 最近在整理一些代码片段和笔记,发现系统自带的记事本功能太简陋,而像VS Code、Sublime这类专业编辑器又过于庞大,启动慢,而且很多高级功能我根本用不上。于是萌生了一个想法&…

2026/7/30 13:42:30 阅读更多 →
【单片机毕业设计】基于 STM32 传感器数据采集与智能出水控制系统 基于 STM32 的饮水设备安全防护控制系统开发(012101)

【单片机毕业设计】基于 STM32 传感器数据采集与智能出水控制系统 基于 STM32 的饮水设备安全防护控制系统开发(012101)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/30 13:42:30 阅读更多 →

最新新闻

从稚晖君现象看全栈硬件开发:如何构建跨领域技术能力与项目思维

从稚晖君现象看全栈硬件开发:如何构建跨领域技术能力与项目思维

1. 从“稚晖君现象”谈起:我们究竟在向往什么?最近几年,在科技创客圈乃至更广泛的互联网上,“稚晖君”这个名字几乎成了一个符号。每当他在视频平台更新一个硬核项目,从自制机械臂到自动驾驶自行车,总能引发…

2026/7/30 13:51:33 阅读更多 →
Python图像处理实战:15个核心模块构建自动化处理框架

Python图像处理实战:15个核心模块构建自动化处理框架

最近在图像处理项目中,你是不是经常遇到这样的场景:需要批量处理大量图片,但手动操作既耗时又容易出错?或者想要实现一些复杂的图像变换,却不知道从何入手?今天我们就来深入探讨一个实用的图像处理项目——…

2026/7/30 13:51:33 阅读更多 →
自回归模型(AR)原理与Python实战:时间序列预测经典方法

自回归模型(AR)原理与Python实战:时间序列预测经典方法

1. 自回归模型:时间序列预测的经典武器 第一次接触自回归(AR)模型时,我被它简洁的数学表达和强大的预测能力震撼了。这个诞生于1927年的方法(由尤尔Yule提出),至今仍是金融、气象、工业控制等领域的标配工具。不同于那…

2026/7/30 13:51:33 阅读更多 →
Visual C++ Build Tools:轻量级C++构建工具链配置与实战指南

Visual C++ Build Tools:轻量级C++构建工具链配置与实战指南

1. 项目概述:为什么你需要独立的C Build Tools? 如果你是一名C开发者,尤其是刚入门不久,或者需要在多台机器上配置开发环境,那么“Visual C Build Tools”这个名字你一定不陌生,也可能被它搞得一头雾水。它…

2026/7/30 13:51:33 阅读更多 →
外卖优惠卡分佣裂变小程序系统开发哪家靠谱

外卖优惠卡分佣裂变小程序系统开发哪家靠谱

外卖优惠卡分佣裂变小程序系统开发哪家靠谱外卖优惠卡分佣裂变小程序是目前本地生活轻创业的主流项目,依托外卖优惠卡发放、用户省钱下单、分享裂变赚佣金的模式,实现用户自增长与平台持续变现。市面上多数小程序开发方案仅实现基础的领卡、分佣、分享功…

2026/7/30 13:51:33 阅读更多 →
商品主图点击率上不去,有没有AI工具能生成高转化主图

商品主图点击率上不去,有没有AI工具能生成高转化主图

一、主图换了十几版,点击率还是半死不活做电商运营的团队,经常遇到这种情况:商品主图反复拍摄、反复设计,换了十几版,点击率始终在平均水平徘徊,上不去。问题可能不是产品不好,而是主图没有打中…

2026/7/30 13:50:32 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻