5.2.11.添加读写接口

news2024/11/18 11:26:16

5.2.11.添加读写接口
5.2.11.1、在驱动中添加
5.2.11.2、在应用中添加
5.2.11.3、测试

1.  app.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


#define FILE  "/dev/test"   // 刚才mknod创建的设备文件 名,必须保持一致

char buf;

int main(void)
{
	int fd = -1;

	
	fd = open(FILE, O_RDWR);
	if(fd < 0)
	{
		printf("open %s error \n",FILE);
		return -1;
	}
	printf("open %s success..\n",FILE);
	
	//读文件
	write(fd, "hello world", 11);
	
	read(fd,buf,20);
	
	
	//关闭 文件
	close(fd);
	
	return 0;
}


2.  Makefile 文件 没有改动 只是增加了 删除 app

#ubuntu的内核源码树,如果要编译在ubuntu中安装的模块就打开这2个
#KERN_VER = $(shell uname -r)
#KERN_DIR = /lib/modules/$(KERN_VER)/build	

		
# 开发板的linux内核的源码树目录  
KERN_DIR = /root/driver/kernel

obj-m	+= module_test.o

all:
	make -C $(KERN_DIR) M=`pwd` modules 
	# app 是在 开发板运行 所以 arm-linux-gcc 
	arm-linux-gcc app.c -o app
cp:
	cp *.ko app /root/rootfs/rootfs/driver_test
	#cp app  /root/rootfs/rootfs/driver_test	

.PHONY: clean	
clean:
	rm -rf  app 
	make -C $(KERN_DIR) M=`pwd` modules clean
	

3. module_test.c 添加   .write        = test_chrdev_write,    

                                        .read        = test_chrdev_read,   

     

#include <linux/module.h>		// module_init  module_exit
#include <linux/init.h>			// __init   __exit
#include <linux/fs.h>


#define MYMAJOR 200  /* 定义 register_chrdev 注册设备的 主设备号 */

#define MYNAME  "test_char" /* 定义 register_chrdev 注册设备的 设备名字 */

int mymajor; /* 定义 register_chrdev 注册设备号*/

/* NOTE  自己定义函数指针  test_chrdev_open  */
static int test_chrdev_open(struct inode *inode, struct file *file)
{
	/* 这个函数中真正应该 放置 打开这个硬件设备的 操作代码 ,我们先 printk 代替一下 */
	printk(KERN_INFO "test_chrdev_open test.c->test_chrdev_open \n");  
	
	return 0;

} /* test_chrdev_open() */




/* NOTE  自己定义函数指针 test_chrdev_release ,   release对应的就是 close  */
static int test_chrdev_release(struct inode *inode, struct file *file)
{
	printk(KERN_INFO "test_chrdev_release test.c->test_chrdev_release \n");

	return 0;
}


static ssize_t test_chrdev_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
	printk(KERN_INFO "test_chrdev_release test.c->test_chrdev_read \n");
	return 0;
}

// 写函数的本质:将应用层 传递过来的数据先 复制到 内核中,然后将之正确的方式写入硬件完成的操作!(数据从应用层到驱动层的复制,)
// 内核有一个 虚拟地址空间,应用层有一个 虚拟地址空间
static ssize_t test_chrdev_write(struct file *file, const char __user *user_buf,
			size_t count, loff_t *ppos)
{
	printk(KERN_INFO "test_chrdev_release test.c->test_chrdev_write\n");
	return 0;	
}


//自定义  file_operations 结构体 及其元素填充
/* NOTE  定义 register_chrdev 注册设备的 设备结构体 test_fops */
static const struct file_operations test_fops = {
	.owner		= THIS_MODULE,                    /* 所有的驱动 代码这一行不需要动,所有的都是这样,不是函数指针, 惯例直接写即可 */
	
	.open		= test_chrdev_open,  /* 将来应用 open 打开这个设备时实际 调用的就是这个 .open  函数指针*/
	.release	= test_chrdev_release,         /* release对应的就是 close    函数指针 */
	.write		= test_chrdev_write, 
	.read		= test_chrdev_read, 
};









// 模块安装函数
static int __init chrdev_init(void)
{	
	int ret = -1;  /* 定义 register_chrdev 的返回值  */
	
	printk(KERN_INFO "chrdev_init helloworld init\n");
	
	
	// 在 module_init 宏 调用函数中去注册字符串 设备驱动
	mymajor = register_chrdev(0, "test_char", &test_fops);   /* major设成0,内核帮我们自动分配空白的设备号,分配的值会 做返回值 ,负数还是返回失败  */
	if(mymajor < 0)
	{
		printk(KERN_ERR "registe_chrdev fail \n");
		return -EINVAL;  /* 返回一个错误码 需要加 ’-‘负号*/
	}
	printk(KERN_INFO "自动分配 register_chrdev success....mymajor = %d \n",mymajor);
	
	return 0;
}

// 模块卸载函数
static void __exit chrdev_exit(void)
{
	printk(KERN_INFO "chrdev_exit helloworld exit\n");
	
	// 在 module_exit宏 调用函数中去注销 字符串 设备驱动
	unregister_chrdev(mymajor, "test_char");  /* 这里不判断返回值 了,一般不会出错 */
}


module_init(chrdev_init);
module_exit(chrdev_exit);

// MODULE_xxx这种宏作用是用来添加模块描述信息
MODULE_LICENSE("GPL");				// 描述模块的许可证
MODULE_AUTHOR("aston");				// 描述模块的作者
MODULE_DESCRIPTION("module test");	// 描述模块的介绍信息
MODULE_ALIAS("alias xxx");			// 描述模块的别名信息




/***********************************************************
如果 KERN_DEBUG 打印不出来,更改打印级别 或者  	
printk(KERN_DEBUG "chrdev_init helloworld init\n"); 

[root@liang_x210 driver_test]# cat /proc/sys/kernel/printk
7       4       1       7
[root@liang_x210 driver_test]# echo 8 > /proc/sys/kernel/printk
[root@liang_x210 driver_test]# cat /proc/sys/kernel/printk
8       4       1       7
************************************************************/


运行结果:

 

             
5.2.11.4、应用和驱动之间的数据交换
(1)copy_from_user,用来将数据从  用户空间复制到内核空间
(2)copy_to_user   从内核空间  复制 到 用户空间


注意:复制  是和  mmap的映射相对应去区分的

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/788717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8S中网络如何通信

Kubernetes 提出了一个自己的网络模型“IP-per-pod”&#xff0c;能够很好地适应集群系统的网络需求&#xff0c;它有下面的这 4 点基本假设&#xff1a; 集群里的每个 Pod 都会有唯一的一个 IP 地址。Pod 里的所有容器共享这个 IP 地址。集群里的所有 Pod 都属于同一个网段。…

WT588F02B-8S 血压计语音芯片如何选型?低功耗语音ic方案

一、血压计语音提示方案需求设计&#xff1f; 血压计语音提示方案的需求设计是为了实现在测量血压过程中&#xff0c;通过语音提示用户操作指引、测量结果和健康建议等功能。以下是血压计语音提示方案需求设计的主要需求&#xff1a; &#xff08;1&#xff09;测量操作引导 …

QT---day1(QT的介绍、常用类及组件)

代码&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//设置窗口尺寸this->setFixedSize(600,500);//设置窗口标题this->setWindowTitle(&q…

【MySQL】库和表的操作

目录 一、库的操作 1.1创建数据库 1.2创建数据库案例 1.3字符集和校验规则 &#xff08;1&#xff09;查看系统默认字符集以及校验规则 &#xff08;2&#xff09;查看数据库支持的字符集 &#xff08;3&#xff09;查看数据库支持的字符集校验规则 &#xff08;4&…

万向节死锁

要理解万向节死锁的产生原因&#xff0c;首先要理解欧拉角变换&#xff0c;欧拉角变换是基于最初始的坐标进行变换而非变换后的坐标进行变换。 欧拉角变换需要空间中的三个角&#xff08;即变换后每个轴的偏移量&#xff09;&#xff0c;另外还有每个轴的变换顺序。值得注意的…

SpringSecurity6--认证和授权的原理

SpringSecurity6–认证和授权的原理&#xff0c;项目gitee地址在文章末尾。 文章目录 一、Spring Security简介二、Spring Security框架中认证流程中几个非常重要的类1、 FilterChainProxy2、 AbstractAuthenticationProcessingFilter3、 UsernamePasswordAuthenticationFilter…

打开Android device monitor

X:\assdk\tools monitor.bat 双击 更新到最新

如何优雅地下载huggingface上模型,以llama2模型下载为例

背景 由于llama2模型的下载需要经过官方的授权&#xff0c;这就需要登陆hugging face的&#xff0c;对模型页面进行申请。等待审核通过后&#xff0c;才能够下载。如果在单纯用 git lfs 的方式进行下载&#xff0c;需要输入账号和密码。为了更快速地进行下载&#xff0c;既能够…

Java刷题记录(小白边刷边学)7.25

Java刷题记录&#xff08;小白边刷边学&#xff09;7.25 1 最长公共前缀 题目分析: 首先一定需要创建一个数组存储最长公共前缀的值 为了方便比较&#xff0c;先把strs的第一个字符串放进新的数组中即strs[0] 因此比较时从strs【1】开始 数字j需要小于两个被比较的字符串的长度…

视频超分新方法--助力实现高清wav2lip数字人

文章目录 前言一、解决方案详解总结前言 ` 随着人工智能的不断发展,数字人技术也越来越重要,很多人都开启了学习模型 但是使用神级模型wav2lip生成的数字人嘴部不清晰怎么办。 很影响使用效果,接下来教大家如何优化这个问题,如下图所示: 一、解决方案详解 因为wav2lip是…

Centos8+Jenkins+微信小程序前端自动发布体验版

文章目录 **一、 实现&#xff1a;****二、项目&#xff1a;****三、环境配置&#xff1a;****四、步骤&#xff1a;****五、遇到的问题** 一、 实现&#xff1a; jenkins打通微信开发平台&#xff0c;自动上传代码 二、项目&#xff1a; 微信小程序原生开发 三、环境配置&…

PowerPoint如何修改“默认保存路径”?

很多时候&#xff0c;我们做好PPT后都要保存&#xff0c;一般会保存在创建PPT的文件夹里&#xff0c;或者另外设置保存的路径。 如果经常需要制作PPT&#xff0c;又不想每次都要重新选择保存位置&#xff0c;我们可以创建或修改“默认保存路径”&#xff0c;这样每次关闭PPT后…

集群及LVS简介、LVSNAT模式原理、LVSNAT模式配置、LVSDR模式原理、LVSDR模式配置、LVS错误排查

day01 day01集群LVS配置LVS NAT模式配置LVS NAT模式步骤LVS DR模式配置LVS DR模式 集群 将很多机器组织到一起&#xff0c;作为一个整体对外提供服务 集群在扩展性、性能方面都可以做到很灵活 集群分类&#xff1a; 负载均衡集群&#xff1a;Load Balance高可用集群&#x…

wangeditor编辑器配置

vue项目中使用编辑器&#xff0c;轻量&#xff0c;操作栏选取自己需要的 官网地址&#xff1a;用于 Vue React | wangEditor 使用在vue项目中引入 npm install wangeditor/editor --savenpm install wangeditor/editor-for-vue --save 封装成组件使用 <template>&…

[LitCTF 2023]作业管理系统

打开环境后是一个登录框&#xff0c;还以为是sql注入&#xff0c;但是尝试之后没有回显&#xff0c;尝试一下弱密码爆破咯 爆出都是admin 进入后可以看到很多选项&#xff0c;都是可以访问的 &#xff0c;说明这道题还有很多解决方法 我们可选择上传文件&#xff0c;没有任何过…

STM32CubeIDE(外部中断)

目录 一、配置时钟树 二、配置IO 三、配置中断优先级 四、当发生外部中断时会进入中断服务函数 一、配置时钟树 二、配置IO 三、配置中断优先级 四、当发生外部中断时会进入中断服务函数

Stable Diffusion本地化部署,实现免费的AI绘制图片

利用Claude进行问答&#xff0c;首先我们询问如何进行AI画图&#xff1a; 我们得到了答案&#xff0c;这里我们问问第三个的网址&#xff1a; 由于在线的都需要收费和限制次数&#xff0c;所以问问有没有本地化的项目&#xff1a; 这里我们得到了答案&#xff0c;前面两个链…

flutter开发实战-jsontodart及 生成Dart Model类

flutter开发实战-jsontodart及 生成Dart Model类。 在开发中&#xff0c;经常遇到请求的数据Json需要转换成model类。这里记录一下Jsontodart生成Dart Model类的方案。 一、JSON生成Dart Model类 在开发中经常用到将json转成map或者list。通过json.decode() 可以方便 JSON 字…

mysql主从复制 读写分离

目录 1.主从复制类型 2.主从复制工作流程(原理) 3.mysql三种同步方式 4.案例 1.主从复制类型 基于语句的复制 基于行的复制 混合类型的复制 2.主从复制工作流程(原理) 两日志 三线程 收到数据主放入二进制日志中 从服务器通过io线程发送请求进入主的dump线程…

element实现角色管理页面

用的element&#xff0c;Tree 树形控件来实现的 <template><div class"p-t-20"><div class"table-bg"><Title title"角色名称"><span>{{role.roleName}}</span></Title><div class"menu-lis…