Binder系统核心
IPC : Inter-Process Communication, 进程间通信
RPC : Remote Procedure Call, 远程过程调用
1、IPC
源:A
目的:B向servicemanager注册led服务
A向servicemanager查询LED服务,得到一个handle
数据;char_buf[512]
2、RPC:远程过程调用
调用哪一个函数:server的函数编号
通过IPC的buf传输
传给它什么参数:
返回值:
如果A进程要打开led进行控制,但是不能直接操作led驱动,就需要A程序通过RPC发送给B进程,控制B进程
A进程:
1、封装数据
2、发送给B
B进程
1、调用led_open、led_ctrl
2、取出数据
经过RPC之后就好像是A直接操作驱动程序一样
3、Binder系统的C程序使用示例
IPC : Inter-Process Communication, 进程间通信
RPC : Remote Procedure Call, 远程过程调用
frameworks\native\cmds\servicemanager
service_manager.c :
a. binder_open
b. binder_become_context_manager
c. binder_loop(bs, svcmgr_handler);
c.1 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
c.2 binder_parse
// 解析
// 处理 : svcmgr_handler
SVC_MGR_GET_SERVICE/SVC_MGR_CHECK_SERVICE : 获取服务
SVC_MGR_ADD_SERVICE : 注册服务
// 回复
bctest.c
注册服务的过程:
a. binder_open
b. binder_call(bs, &msg, &reply, 0, SVC_MGR_ADD_SERVICE)
// 含有服务的名字
// 它会含有servicemanager回复的数据
// 0表示发给servicemanager,
// code: 表示要调用servicemanager中的"addservice函数"
获取服务的过程:
a. binder_open
b. binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE)
// 含有服务的名字
// 它会含有servicemanager回复的数据, 表示提供服务的进程
// 0表示servicemanager
// code: 表示要调用servicemanager中的"getservice函数"
4、步骤
a、client的编写
b、servermanger编写步骤
c、server步骤
5、库文件Binder.c分析
int binder_call(struct binder_state *bs,
struct binder_io *msg, struct binder_io *reply,
uint32_t target, uint32_t code)
{
int res;
struct binder_write_read bwr;
struct {
uint32_t cmd;
struct binder_transaction_data txn;
} __attribute__((packed)) writebuf;
unsigned readbuf[32];
if (msg->flags & BIO_F_OVERFLOW) {
fprintf(stderr,"binder: txn buffer overflow\n");
goto fail;
}
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;
hexdump(msg->data0, msg->data - msg->data0);
for (;;) {
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
fprintf(stderr,"binder: ioctl failed (%s)\n", strerror(errno));
goto fail;
}
res = binder_parse(bs, reply, (uintptr_t) readbuf, bwr.read_consumed, 0);
if (res == 0) return 0;
if (res < 0) goto fail;
}
fail:
memset(reply, 0, sizeof(*reply));
reply->flags |= BIO_F_IOERROR;
return -1;
}
a、首先要构造数据:数据放buf[100000],用Binder_io来描述
b、调用ioctl发数据
c、ioctl也会收数据,收到biner_write_read
先来看看怎么使用binder_call
uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
uint32_t handle;
unsigned iodata[512/4];
struct binder_io msg, reply;//构造一个binder_io
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);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))//构造好之后就开始调用binder_call
return 0;
handle = bio_get_ref(&reply);
if (handle)
binder_acquire(bs, handle);
binder_done(bs, &msg, &reply);
return handle;
}
怎么写app