简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2.Android内核之binder_thread_write介绍
- 🌻3.代码实例
- 🐓3.1 发送Binder消息
- 🐓3.2 发送Binder事件通知
- 🐓3.3 发送Binder异步消息
🌻1.前言
本篇目的:Android内核之Binder通信写操作:binder_thread_write用法实例
🌻2.Android内核之binder_thread_write介绍
-
binder_thread_write
函数是Android内核中用于Binder线程通信的关键函数之一。Binder是Android系统中用于进程间通信(IPC)的机制,它通过驱动程序实现。在Binder机制中,每个进程都有一个专门的Binder线程,用于处理与其他进程的通信请求。 -
binder_thread_write
函数主要负责向目标Binder线程发送消息。它接受参数包括目标线程的信息、要发送的数据、数据的大小等,并将这些信息封装成一个Binder交易数据结构,最终通过驱动程序发送给目标线程。 -
该函数的关键步骤如下:
-
参数验证: 首先,函数会验证传入的参数,确保它们的有效性和合法性,包括目标线程的有效性、发送数据的大小等。
-
构造Binder交易数据: 接下来,函数会根据传入的参数构造一个Binder交易数据结构。这个数据结构包含了要发送的消息内容、目标线程的标识符等信息。
-
调用Binder驱动发送消息: 函数将构造好的Binder交易数据结构传递给Binder驱动程序,通过驱动程序实现消息的发送。Binder驱动会负责将消息传递给目标线程,并处理相关的错误情况。
-
返回结果: 最后,函数根据发送结果返回相应的错误码或成功状态,通知调用者发送消息的结果。
binder_thread_write
函数的调用通常发生在Android系统的内核空间,例如系统服务或驱动程序中。它允许不同的进程之间进行通信,实现了Android系统中各个组件之间的协作与交互。作为Android系统中IPC机制的核心之一,Binder机制在实现高效稳定的进程通信方面发挥着重要作用,而binder_thread_write
函数则是其中的关键环节之一。
🌻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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_transaction_data *transaction_data;// 从用户空间拷贝数据到内核空间if (copy_from_user(&transaction_data, buffer, sizeof(struct binder_transaction_data)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder消息binder_thread_write(transaction_data);return count;
}// 初始化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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_event *event;// 从用户空间拷贝数据到内核空间if (copy_from_user(&event, buffer, sizeof(struct binder_event)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder事件通知binder_thread_write(event);return count;
}// 初始化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设备的write操作
static ssize_t binder_write(struct file *file, const char __user *buffer, size_t count, loff_t *offset) {struct binder_thread *thread;// 从用户空间拷贝数据到内核空间if (copy_from_user(&thread, buffer, sizeof(struct binder_thread)) != 0) {return -EFAULT;}// 使用binder_thread_write发送Binder异步消息binder_thread_write(thread);return count;
}// 初始化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");