RK3568驱动指南|第二篇 字符设备基础-第14章 内核空间与用户空间数据交互实验

本文主要是介绍RK3568驱动指南|第二篇 字符设备基础-第14章 内核空间与用户空间数据交互实验,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。

第14章 内核空间与用户空间数据交互实验

在“第12章 字符设备驱动框架实验”中,已经对file_operations结构体的进行了填充,该结构体的每一个成员都对应着一个系统调用,例如read、write等,在对应的实验中,只是对调用函数进行了标志打印,并没有真正实现设备的读写功能,而在本章节将对内核空间与用户空间的数据交换功能进行实现。

14.1 内核空间与用户空间

Linux系统将可访问的内存空间分为了两个部分,一部分是内核空间,一部分是用户空间。操作系统和驱动程序运行在内核空间(内核态),应用程序运行在用户空间(用户态)。

那么为什么要区分用户空间和内核空间呢?

(1)内核空间中的代码控制了硬件资源,用户空间中的代码只能通过内核暴露的系统调用接口来使用系统中的硬件资源,这样的设计可以保证操作系统自身的安全性和稳定性。

(2)从另一方面来说,内核空间的代码更偏向于系统管理,而用户空间中的代码更偏重业务逻辑实现,俩者的分工不同。

硬件资源管理都是在内核空间完成的,应用程序无法直接对硬件进行操作,只能通过调用相应的内核接口来完成相应的操作。比如应用程序要对磁盘上的一个文件进行读取,应用程序可以向内核发起一个“系统调用”申请——我要读取磁盘上的文件。这个过程其实是通过一个特殊的指令让进程从用户态进入到了内核态。在内核空间中,CPU可以执行任何命令,包括从磁盘上读取数据,具体过程是先把数据读取到内核空间中,然后再把数据拷贝到用户空间并从内核态切换到用户态。此时应用程序已经从系统调用中返回并拿到了想要的数据,可以继续往下执行了。

进程只有从用户空间切换到内核空间才可以使用系统的硬件资源,切换的方式有三种:系统调用,软中断,硬中断,如下图(图 14-1)所示:

14.2 用户空间和内核空间数据交换

内核空间和用户空间的内存是不能互相访问的。但是很多应用程序都需要和内核进行数据的交换,例如应用程序使用read函数从驱动中读取数据,使用write函数向驱动中写数据,上述功能就需要使用copy_from_user和copy_to_user俩个函数来完成。copy_from_user函数是将用户空间的数据拷贝到内核空间。copy_to_user函数是将内核空间的数据拷贝到用户空间。

这俩个函数定义在了kernel/include/linux/uaccess.h文件下,如下所示:

copy_to_user

函数原型:

​ unsigned long copy_to_user_inatomic(void __user *to, const void

*from, unsigned long n);

函数作用:

​ 把内核空间的数据复制到用户空间。

参数含义:

​ *to是用户空间的指针

​ *from是内核空间的指针

​ n是从内核空间向用户空间拷贝的字节数

copy_from_user

函数原型:

​ unsigned long copy_from_user(void *to, const void __user *from,

unsigned long n)

函数作用:

​ 把用户空间的数据复制到内核空间。

参数含义:

​ *to是内核空间的指针

​ *from是用户空间的指针

​ n是从用户空间向内核空间拷贝的字节数

14.3 实验程序编写

14.3.1 驱动程序编写

本驱动程序对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\09\module。

在该实验中将实现内核空间和用户空间进行数据交换的功能。以12章编写的字符设备驱动框架实验为基础编写驱动程序,程序使用copy_to_user函数和copy_from_user函数来实现内核空间和用户空间互传数据的功能,编写完成的file.c代码如下所示:

以上代码在cdev_test_read函数中使用copy_to_user函数将内核数据拷贝到用户空间,在cdev_test_write函数中使用copy_from_user函数将用户空间数据拷贝到内核空间。

14.3.2 编写测试 APP

本应用程序对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\09\app。

编写测试APP其实是在编写Linux应用,编译完成的应用程序app.c代码如下所示:

14.4 运行测试

14.4.1 编译驱动程序

在上一小节中的file.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下 所示:

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放file.c和Makefile文件目录下,如下图(图14-2)所示:

然后使用命令“make”进行驱动的编译,编译完成如下图(图14-3)所示:

编译完生成 file.ko目标文件,如下图(图 14-4)所示:

至此我们的驱动模块就编译成功了,下面进行应用程序编译.

下面进行驱动程序的测试。

输入以下命令运行应用程序,如下图(图 14-7)所示

由上图可知,打印“This is cdev_test_open”信息说明成功打开了字符设备驱动。

打印“ This is cdev_test_read”和“buf1 is This is cdev_test_read!”说明应用程序成功读取到内核的数据。

打印“This is cdev_test_write”和“kbuf is nihao”说明应用程序向内核写数据成功。

最后打印“This is cdev_test_release”说明卸载字符设备。

更多内容可以了解迅为RK3568开发板

这篇关于RK3568驱动指南|第二篇 字符设备基础-第14章 内核空间与用户空间数据交互实验的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/883039

相关文章

Python+FFmpeg实现视频自动化处理的完整指南

《Python+FFmpeg实现视频自动化处理的完整指南》本文总结了一套在Python中使用subprocess.run调用FFmpeg进行视频自动化处理的解决方案,涵盖了跨平台硬件加速、中间素材处理... 目录一、 跨平台硬件加速:统一接口设计1. 核心映射逻辑2. python 实现代码二、 中间素材处

Java利用Spire.Doc for Java实现在模板的基础上创建Word文档

《Java利用Spire.DocforJava实现在模板的基础上创建Word文档》在日常开发中,我们经常需要根据特定数据动态生成Word文档,本文将深入探讨如何利用强大的Java库Spire.Do... 目录1. Spire.Doc for Java 库介绍与安装特点与优势Maven 依赖配置2. 通过替换

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

Spring Boot基于 JWT 优化 Spring Security 无状态登录实战指南

《SpringBoot基于JWT优化SpringSecurity无状态登录实战指南》本文介绍如何使用JWT优化SpringSecurity实现无状态登录,提高接口安全性,并通过实际操作步骤... 目录Spring Boot 实战:基于 JWT 优化 Spring Security 无状态登录一、先搞懂:为什

Nginx概念、架构、配置与虚拟主机实战操作指南

《Nginx概念、架构、配置与虚拟主机实战操作指南》Nginx是一个高性能的HTTP服务器、反向代理服务器、负载均衡器和IMAP/POP3/SMTP代理服务器,它支持高并发连接,资源占用低,功能全面且... 目录Nginx 深度解析:概念、架构、配置与虚拟主机实战一、Nginx 的概念二、Nginx 的特点

C#实现插入与删除Word文档目录的完整指南

《C#实现插入与删除Word文档目录的完整指南》在日常的办公自动化或文档处理场景中,Word文档的目录扮演着至关重要的角色,本文将深入探讨如何利用强大的第三方库Spire.Docfor.NET,在C#... 目录Spire.Doc for .NET 库:Word 文档处理利器自动化生成:C# 插入 Word

Python列表去重的9种方法终极指南

《Python列表去重的9种方法终极指南》在Python开发中,列表去重是一个常见需求,尤其当需要保留元素原始顺序时,本文为大家详细介绍了Python列表去重的9种方法,感兴趣的小伙伴可以了解下... 目录第一章:python列表去重保持顺序方法概述使用字典去重(Python 3.7+)使用集合辅助遍历性能

在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南

《在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南》在SpringBoot和MyBatis项目中实现MySQL读写分离,主要有两种思路:一种是在应用层通过代码和配置手动控制... 目录如何选择实现方案核心实现:应用层手动分离实施中的关键问题与解决方案总结在Spring Boot和

JavaScript装饰器从基础到实战教程

《JavaScript装饰器从基础到实战教程》装饰器是js中一种声明式语法特性,用于在不修改原始代码的情况下,动态扩展类、方法、属性或参数的行为,本文将从基础概念入手,逐步讲解装饰器的类型、用法、进阶... 目录一、装饰器基础概念1.1 什么是装饰器?1.2 装饰器的语法1.3 装饰器的执行时机二、装饰器的

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.