binder系统C程序——框架

1. IPC
源:A
目的:B向serviceManager注册led服务
A向serviceManager查询led服务,得到一个handle
数据: char buf[512]

2. RPC 远程过程调用
调用哪一个函数:server的函数编号
返回值以及传递什么参数:通过IPC的buf传输

client:
a. open驱动
b. 获取服务
i.向servicemanger查询服务
ii.获得一个handle
c. 向handle发送数据
servicemanager
a. open驱动
b. 告诉驱动,它是"servicemanager"
c. while(1)
i. 读驱动数据
ii. 解析数据
iii. 调用①注册服务(在链表中记录服务) ②.获取服务(在链表中查询服务的有无),返回server进程的handle

server
a. open驱动
b. 注册服务(向servicemanager发送服务名)
c. while(1)
i.读驱动数据
ii. 解析数据
iii.调用相应的函数

binder.c函数分析
binder_call
int binder_call(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply, uint32_t target, uint32_t code)

binder_state bs: 代表binder驱动
binder_io msg: 发送数据提供的参数
binder_io reply:返回值
target: 向谁发送数据
code:调用哪个函数

binder_call的实现
a. 构造参数:放在buf[4096], 用binder_io来描述
struct binder_io msg, reply;

bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
bio_put_obj(&msg, ptr);
b. 数据转化,将binder_io转化为binder_write_read
struct binder_write_read bwr;
struct {
uint32_t cmd;
struct binder_transaction_data txn;
} __attribute__((packed)) writebuf;
unsigned readbuf[32];

writebuf.cmd = BC_TRANSACTION;
writebuf.txn.target.handle = target;
writebuf.txn.code = code;
writebuf.txn.flags = 0;
writebuf.txn.data_size = msg->data - msg->data0;
writebuf.txn.offsets_size = ((char*) msg->offs) - ((char*) msg->offs0);
writebuf.txn.data.ptr.buffer = (uintptr_t)msg->data0;
writebuf.txn.data.ptr.offsets = (uintptr_t)msg->offs0;

bwr.write_size = sizeof(writebuf);
bwr.write_consumed = 0;
bwr.write_buffer = (uintptr_t) &writebuf;
c. 调用ioctl发数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
d. ioctl也会收到数据
转化为binder_io

怎么写App?
client
a. binder_open
b. 获得服务:handle
c. 构造参数:binder_io
d. 调用binder_call
此时server会解析数据
e.返回binder_io, 取出返回值,分析

server
a.binder_open
b.注册服务
c. ioctl读数据
d. 解析数据
binder_write_read.readbuf--->binder_transaction_data
里面有code和参数
将参数(txn)转化为binder_io
bio_init(&reply, rdata, sizeof(rdata), 4);
bio_init_from_txn(&msg, txn);
e. 根据code决定调用哪个函数
如果调用的函数里面带有参数,参数可以从返回的binder_io里取得
6. 将返回值转换为binder_io,发给client
bio_put_uint32(reply, i);


posted @ 2021-05-12 15:39  zhudaheng123  阅读(190)  评论(0)    收藏  举报