Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2.Android内核之binder_ioctl_write_read介绍
- 🌻3.代码实例
- 🐓3.1 发送Binder消息
- 🐓3.2 接收Binder消息
- 🐓3.3 Binder事件通知
🌻1.前言
本篇目的:Android内核之IPC通信:binder_ioctl_write_read用法实例
🌻2.Android内核之binder_ioctl_write_read介绍
-
binder_ioctl_write_read
是Android系统中Binder驱动的关键函数之一,用于在用户空间和内核空间之间进行进程间通信(IPC)。Android的Binder机制是一种高效的IPC机制,用于在Android系统中进行进程间通信,特别是在应用程序和系统服务之间。 -
该函数的主要作用是通过ioctl系统调用在用户空间和内核空间之间传递数据。在Binder中,进程可以通过Binder节点向Binder驱动发送请求消息,而Binder驱动负责将这些消息传递到目标进程。在内核空间中,这些请求消息和响应消息被表示为数据结构,并通过
binder_ioctl_write_read
函数进行读写。 -
具体而言,
binder_ioctl_write_read
函数的作用包括:
-
消息传递: 通过该函数,应用程序可以向Binder驱动发送请求消息,例如调用远程服务的请求或发送数据给其他进程。
-
数据交换: 该函数允许应用程序和内核空间之间交换数据,实现进程间通信。数据可以是任何形式的信息,如函数调用、参数、返回值等。
-
事件通知: Binder机制还支持事件通知,例如进程间的状态变化或系统服务的可用性。
binder_ioctl_write_read
函数可以用于发送和接收这些事件通知。 -
错误处理: 除了消息传递外,该函数还负责处理可能发生的错误情况。例如,当发送消息失败或接收到无效的消息时,函数会返回相应的错误码,应用程序可以据此进行错误处理。
-
使用
binder_ioctl_write_read
函数需要一定的内核编程知识和经验。开发者需要了解Binder驱动的工作原理以及消息传递的机制,同时要熟悉ioctl系统调用的使用方法。在实际开发中,通常会使用高级别的API和框架来进行Binder通信,这些API和框架会封装底层的细节,简化开发过程。 -
binder_ioctl_write_read
函数在Android系统中扮演着至关重要的角色,它为应用程序提供了一种强大的IPC机制,支持应用程序之间和应用程序与系统服务之间的通信,促进了Android系统的功能丰富和性能优化。
🌻3.代码实例
🐓3.1 发送Binder消息
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_SEND_MESSAGE:// 发送Binder消息// 在这里构造消息数据,并使用binder_ioctl_write_read发送消息break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");
🐓3.2 接收Binder消息
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_RECEIVE_MESSAGE:// 接收Binder消息// 在这里构造消息数据,并使用binder_ioctl_write_read接收消息break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");
🐓3.3 Binder事件通知
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/android/binder.h>#define DEVICE_NAME "binder_example"
#define BINDER_DEV_PATH "/dev/binder_example"static int major_number;
static struct class *binder_class = NULL;
static struct device *binder_device = NULL;// 打开Binder设备
static int binder_open(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device opened\n");return 0;
}// 释放Binder设备
static int binder_release(struct inode *inode, struct file *file) {printk(KERN_INFO "Binder device closed\n");return 0;
}// 实现Binder设备的ioctl操作
static long binder_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {int ret = 0;struct binder_write_read bwr;switch (cmd) {case BINDER_RECEIVE_EVENT:// 接收Binder事件通知// 在这里构造事件数据,并使用binder_ioctl_write_read接收事件break;default:printk(KERN_ERR "Unknown command\n");ret = -EINVAL;break;}return ret;
}// 初始化Binder设备
static int __init binder_init(void) {// 分配主设备号major_number = register_chrdev(0, DEVICE_NAME, &binder_fops);if (major_number < 0) {printk(KERN_ALERT "Failed to register a major number\n");return major_number;}// 创建设备类binder_class = class_create(THIS_MODULE, DEVICE_NAME);if (IS_ERR(binder_class)) {unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to register device class\n");return PTR_ERR(binder_class);}// 创建设备节点binder_device = device_create(binder_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME);if (IS_ERR(binder_device)) {class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_ALERT "Failed to create the device\n");return PTR_ERR(binder_device);}printk(KERN_INFO "Binder module initialized\n");return 0;
}// 卸载Binder设备
static void __exit binder_exit(void) {device_destroy(binder_class, MKDEV(major_number, 0));class_unregister(binder_class);class_destroy(binder_class);unregister_chrdev(major_number, DEVICE_NAME);printk(KERN_INFO "Binder module exit\n");
}module_init(binder_init);
module_exit(binder_exit);
MODULE_LICENSE("GPL");
相关文章:

Android内核之Binder读写通信:binder_ioctl_write_read用法实例(七十)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

【C语言/数据结构】经典链表OJ习题~第二期——链中寻环
🎈🎈🎈欢迎采访小残风的博客主页:残风也想永存-CSDN博客🎈🎈🎈 🎈🎈🎈本人码云 链接:残风也想永存 (FSRMWK) - Gitee.com🎈…...

MySQL日志机制【undo log、redo log、binlog 】
前言 SQL执行流程图文分析:从连接到执行的全貌_一条 sql 执行的全流程?-CSDN博客文章浏览阅读1.1k次,点赞20次,收藏12次。本文探讨 MySQL 执行一条 SQL 查询语句的详细流程,从连接器开始,逐步介绍了查询缓存、解析 S…...
SSL通信、证书认证原理和失败原因
目录 SSL通信SSL认证原理SSL证书认证失败的原因分析 SSL通信 SSL通信指的是使用SSL(Secure Sockets Layer)协议进行的加密通讯。SSL是一种标准的安全技术,用于建立一个加密链接,确保从用户的浏览器到服务器之间的数据传输是私密和…...

【MsSQL】数据库基础 库的基本操作
目录 一,数据库基础 1,什么是数据库 2,主流的数据库 3,连接服务器 4,服务器,数据库,表关系 5,使用案例 二,库的操作 1,创建数据库 2,创建…...

AI编码工具-通义灵码功能实测
AI编码工具-通义灵码功能实测 通义灵码功能介绍行级/函数级实时续写自然语言生成代码单元测试生成异常排错智能排查生成代码注释生成代码解释研发领域自由问答 在上一篇文章中,我介绍了通义灵码的功能以及支持的操作系统,主流IDE等,详细内容可…...
直接显示二进制图片
Option Explicit Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type Private Declare Function CreateStreamOnHGlobal Lib “ole32.dll” (ByRef hGlobal As Any, ByVal fDeleteOnResume As Long, ByRef ppstr As Any) As Long P…...

微软exchange邮箱发送
使用java发送exchange类型的邮件,foxmail中配置如下图: 需要的maven依赖如下: <dependency><groupId>com.microsoft.ews-java-api</groupId><artifactId>ews-java-api</artifactId><version>2.0</ve…...

AI绘画Stable Diffusion SDXL 超赞!高质量万能大模型,写实人像、时尚设计、建筑设计、电影制作—筑梦工业XLV4.0
大家好,我是阿威 今天为大家带来了一款多功能大模型——Dream Tech XL | 筑梦工业XL V4.0。该模型是大佬Dr_Dream基于V3.0训练而来的迭代版本,在提升画面质感的同时,对于提示词理解能力有跨越式提升,可以做到100%还原提示词。筑梦…...

数字人捕捉、建模与合成
在感知系统中,我们与外部合作者一起创建逼真的 3D 人类,其行为可以像虚拟世界中的真实人类一样。这项工作在今天有许多实际应用,并且对于元宇宙的未来至关重要。但是,在感知系统中,我们的目标是科学的——通过重现人类…...
Yarn:下一代JavaScript包管理器的安装与实战指南
当然,让我们深入探讨Yarn——一个高效、可靠的JavaScript包管理器,它为前端开发带来了新的速度和便利。Yarn由Facebook、Google、Exponent和Tilde公司共同推出,旨在解决npm(Node.js包管理器)存在的问题,如依…...
JVM进程缓存 Caffeine
JVM进程缓存 Caffeine 初识Caffeine Caffeine是一个基于Java8开发的,提供了近乎最佳命中率的高性能的本地缓存库。 ben-manes/caffeine: A high performance caching library for Java (github.com) 实例代码 Test void testBasicOps() {// 创建缓存对象Cache&…...

c++ 线程交叉场景试验
1.需求 处理一个列表的数据,要求按照列表的数据处理10个数据可以使用多线程处理,但是针对每个线程,1~10的处理顺序不能变。每个数据的处理必须原子,即只有一个线程可以针对某个数据进行处理,但是10个数据是可以由10个…...

Cell:如何升华你的单细胞数据——PCF空间单细胞蛋白组联合scRNA-seq解析骨髓微环境
骨髓微环境非常复杂,含有不同的细胞类型,包括了造血、间充质、内皮、血管平滑肌和神经谱系细胞等。非造血细胞对于骨髓造血非常关键。然而,这些细胞在人骨髓中的异质性和空间定位在很大程度上仍未被表征。来自佩雷尔曼医学院的研究者使用scRN…...
vue强制刷新组件
在Vue中强制刷新一个组件,通常不是一个推荐的做法,因为Vue的响应式系统设计就是为了自动处理依赖的更新。要强制重新渲染组件,以下是几种方法: 使用key属性: 最常见的方法是改变组件的key属性。当key发生变化时&#x…...

分享5款对工作学习有帮助的效率软件
今天再来推荐5个超级好用的效率软件,无论是对你的学习还是办公都能有所帮助,每个都堪称神器中的神器,用完后觉得不好用你找我。 1.文件复制——ClipClip ClipClip是一款功能强大、操作简便的文件复制与管理软件。它改变了传统的复制粘…...
redis秒杀(PHP版本)
前提提要 今天产品端提了个需求,院校组要求借调我去帮忙,因为我以前做过商城,现在他们需求做一个积分商城,需要做一个秒杀模块,结果毫无意外的我被借调过去了,刚好可以复习一下以前的知识,现在介…...

图形用户界面(GUI)在AI去衣技术中的作用与重要性
引言: 随着人工智能技术的不断进步,AI去衣这一概念逐渐进入公众视野。它指的是利用深度学习算法,从图片或视频中自动移除人物的衣物,生成相应的“裸体”图像。尽管这项技术在道德和隐私方面引发了诸多争议,但其背后的技…...

如何阅读:一个已被证实的低投入高回报的学习方法的笔记
系列文章目录 如何有效阅读一本书笔记 如何阅读:一个已被证实的低投入高回报的学习方法 麦肯锡精英高效阅读法笔记 读懂一本书笔记 文章目录 系列文章目录第一章 扫清阅读障碍破解读不快、读不进去的谜题一切为了阅读小学教师让你做,但中学老师阻止你做的…...

pycharm 安装“通义灵码“并测试
过程:“File>setting>Plugins” 提示: 翻译之后: 点击"接受"之后,提示一下图片,点击ok 安装完成: 安装完"通义灵码"之后,需要登陆,登陆后测试 参考…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
为什么要创建 Vue 实例
核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...

Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验
2024年初,人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目(一款融合大型语言模型能力的云端AI编程IDE)时,技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力,TRAE在WayToAGI等…...
【题解-洛谷】P10480 可达性统计
题目:P10480 可达性统计 题目描述 给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。 输入格式 第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 …...

【技巧】dify前端源代码修改第一弹-增加tab页
回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码,在知识库增加一个tab页"HELLO WORLD",完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...

C#中用于控制自定义特性(Attribute)
我们来详细解释一下 [AttributeUsage(AttributeTargets.Class, AllowMultiple false, Inherited false)] 这个 C# 属性。 在 C# 中,Attribute(特性)是一种用于向程序元素(如类、方法、属性等)添加元数据的机制。Attr…...