简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
🍉🍉🍉文章目录🍉🍉🍉
- 🌻1.前言
- 🌻2.Android内核binder_transaction介绍
- 🌻3.代码实例
- 🐓3.1 Binder 服务端接收请求并回复
- 🐓3.2 Binder 客户端向服务端发送请求
- 🐓3.3 Binder 驱动中实现事务处理
🌻1.前言
本篇目的:Android内核之Binder消息处理:binder_transaction用法实例
🌻2.Android内核binder_transaction介绍
-
binder_transaction 函数是 Android Binder 驱动中的一个核心函数,它用于在 Binder 机制中实现客户端向服务端发送请求并接收响应的过程。以下是对 binder_transaction 函数作用的详细介绍:
-
消息传递: 在 Android 中,Binder 机制允许不同的应用程序或系统组件之间进行进程间通信(IPC)。当一个客户端应用程序想要向一个服务端应用程序发送请求时,它会通过 Binder 机制将请求封装成一个消息,并发送给服务端。binder_transaction 函数负责将这个消息从客户端传递到服务端。
-
消息解析: 一旦消息到达服务端,binder_transaction 函数会负责解析消息的内容,提取出请求的具体信息,例如请求调用的函数或方法名称、参数等。这个过程是非常关键的,因为服务端需要根据这些信息来执行相应的操作。
-
请求处理: 服务端收到消息后,会根据消息中的内容执行相应的操作,并生成一个响应消息。binder_transaction 函数在服务端负责处理这个请求,调用相应的服务端函数或方法,并传递请求所需的参数。
-
响应返回: 当服务端完成请求处理后,会生成一个响应消息,并通过 binder_transaction 函数将这个响应消息传递回客户端。客户端收到响应后,可以继续执行相应的操作,例如更新用户界面或者执行下一步操作。
-
线程同步和错误处理: 在消息传递和处理的过程中,可能会涉及到线程同步和错误处理等问题。binder_transaction 函数需要确保消息的传递和处理是按照正确的顺序进行的,并且能够处理各种可能出现的错误情况,例如超时、服务端崩溃等。
-
binder_transaction 函数是 Android Binder 驱动中非常重要的一个函数,负责实现客户端与服务端之间的消息传递和请求处理过程。它的正确和高效运行对于 Android 系统的稳定性和性能至关重要。
🌻3.代码实例
🐓3.1 Binder 服务端接收请求并回复
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>
#define BINDER_TEST_SERVICE 1
static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct binder_thread *thread = current->binder;
struct binder_transaction_data *txn = (struct binder_transaction_data *)arg;
int ret;
if (cmd == BINDER_TRANSACTION) {
// 处理客户端请求,并生成响应
// 在这里可以执行相应的功能
// 然后构造响应消息并发送
struct binder_transaction_data reply;
reply.target.handle = txn->sender_pid; // 客户端的PID
reply.target.ptr = NULL;
reply.code = 0; // 响应码
reply.flags = 0;
ret = binder_transaction(thread, &reply, sizeof(reply), NULL, 0);
return ret;
}
return -ENOTTY;
}
static const struct file_operations binder_test_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = binder_test_ioctl,
};
static int __init binder_test_init(void)
{
if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
return -ENOMEM;
return 0;
}
static void __exit binder_test_exit(void)
{
binderfs_remove_file("binder_test");
}
module_init(binder_test_init);
module_exit(binder_test_exit);
🐓3.2 Binder 客户端向服务端发送请求
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>
#define BINDER_TEST_SERVICE 1
static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct binder_thread *thread = current->binder;
struct binder_transaction_data txn;
int ret;
if (cmd == BINDER_TRANSACTION) {
// 构造客户端请求消息
txn.target.handle = BINDER_TEST_SERVICE; // 服务端的 handle
txn.code = 0; // 请求码
txn.flags = 0; // 请求标志
// 可以添加其他请求数据
// 发送请求并等待响应
ret = binder_transaction(thread, &txn, sizeof(txn), NULL, 0);
return ret;
}
return -ENOTTY;
}
static const struct file_operations binder_test_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = binder_test_ioctl,
};
static int __init binder_test_init(void)
{
if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
return -ENOMEM;
return 0;
}
static void __exit binder_test_exit(void)
{
binderfs_remove_file("binder_test");
}
module_init(binder_test_init);
module_exit(binder_test_exit);
MODULE_LICENSE("GPL");
🐓3.3 Binder 驱动中实现事务处理
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/binder.h>
#define BINDER_TEST_SERVICE 1
static int binder_test_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct binder_thread *thread = current->binder;
struct binder_transaction_data *txn = (struct binder_transaction_data *)arg;
int ret;
if (cmd == BINDER_TRANSACTION) {
// 在这里根据请求参数执行相应的功能
// 并构造响应消息
struct binder_transaction_data reply;
reply.target.handle = txn->sender_pid; // 客户端的PID
reply.target.ptr = NULL;
reply.code = 0; // 响应码
reply.flags = 0;
ret = binder_transaction(thread, &reply, sizeof(reply), NULL, 0);
return ret;
}
return -ENOTTY;
}
static const struct file_operations binder_test_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = binder_test_ioctl,
};
static int __init binder_test_init(void)
{
if (binderfs_create_file("binder_test", &binder_test_fops) != 0)
return -ENOMEM;
return 0;
}
static void __exit binder_test_exit(void)
{
binderfs_remove_file("binder_test");
}
module_init(binder_test_init);
module_exit(binder_test_exit);
MODULE_LICENSE("GPL");