Binder系统有两大核心,分别为IPC(Information Processing Center:信息处理中心,进程间的通信)与RPC(远程过程控制调用)。
数据的传输的三大要素分别为源,目的和数据。
源(进程A):发送数据,A向serviceManager查询led服务,获取一个handle(对硬件操作的服务),该handle指向进程B。
目的(进程B):B向serviceManager注册LED服务,以便A进程获取
数据:点亮,或者熄灭闪烁等。
A进程调用led_open和Led_ctrl,A进程首先按照约定好的数据封装数据,然后将数据发送出去;B进程取出数据,调用本地led_open/led_ctrl
RPC:RPC是在IPC的基础上做了一些封装。可以认为是直接调用某个进程的函数(A进程去调用B进程的函数)。即AB进程约定好相应的格式,如对函数进行编号
service_manager.c
main()
//1、open驱动
bs = binder_open(128*1024);
//打开用户态binder(前面提到过,进程间的通信都是通过binder)
bs->fd = open("/dev/binder", O_RDWR);
//调用驱动的mmap函数
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
//2、告诉驱动他是service_manager
binder_become_context_manager(bs)
ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
//3、一个循环,读取处理数据,其中的svcmgr_handler为服务处理函数
binder_loop(bs, svcmgr_handler);
//读取数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
// 解析数据
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
//处理数据,此处的func就是前面的传入的svcmgr_handler
res = func(bs, txn, &msg, &reply);
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
case SVC_MGR_CHECK_SERVICE:
//根据传入的txn->code,在链表中查找服务,查找到之后返回服务
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
case SVC_MGR_ADD_SERVICE:
//如果传入的是注册服务,则加入本地链表
do_add_service(bs, s, len, handle, txn->sender_euid,allow_isolated, txn->sender_pid)
test_client.c
int main(int argc, char **argv)
//1、打开binder驱动,映射内存的大小为128*1024
bs = binder_open(128*1024);
/*2、获取服务goodbye get service */
handle = svcmgr_lookup(bs, svcmgr, "hello");
binder_call(bs, &msg/*上边构造数据提供的参数*/, &reply/*返回值*/,
target/*向谁发送数据*/, SVC_MGR_CHECK_SERVICE/*调用那个函数*/)
//3、向handle发送数据
sayhellobye();
binder_release(bs, handle);
test_server.c
int main(int argc, char **argv)
//1、打开binder驱动,映射内存的大小为128*1024
bs = binder_open(128*1024);
/*2、注册服务 add service */
/*注册一个"hello"服务,把hello_service_handler函数指针当做参数,
为方便后面的调用*/
ret = svcmgr_publish(bs,
svcmgr/*接口句柄函数编号*/,
"hello"/*服务名称*/,
hello_service_handler/*服务处理函数*/);
/*3、循环等待,如果有"goodbye或者"hello"服务申请,
则test_server_handler函数被调用*/
binder_loop(bs, test_server_handler);
//读取数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
// 解析数据
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
//处理数据,此处的func就是前面的传入的test_server_handler
res = func(bs, txn, &msg, &reply);
int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
int status;
unsigned iodata[512/4];//用户空间传递给内核Binder驱动的数据缓存
//struct binder_io 主要用来对上述iodata数组缓存区进行有效管理和操作;
struct binder_io msg/* 发送数据提供的参数*/, reply/*返回值*/;
/**********数据构造**********/
//初始化数组的数据,预留16个字节,用于存放flat_binder_object的地址
bio_init(&msg, iodata, sizeof(iodata), 4);
//构造数据
bio_put_uint32(&msg, 0); // 存放四个字节0
/*可以放入各类型参数,反之通过get方法获取
* 写入字符串 android.os.IServiceManager
*/
bio_put_string16_x(&msg, SVC_MGR_NAME);
//写入服务的名字hello
bio_put_string16_x(&msg, name);//"hello"/*服务名称*/
//服务处理函数--传递一个biner实体传递给内核
bio_put_obj(&msg, ptr);
/*------------------------------*/
//在构建完struct binder_io msg后,调用ioctrl向驱动程序发送数据
if (binder_call(bs,
&msg/* 提供参数*/,
&reply/*返回值*/,
target/*函数编号向谁发送数据*/,
SVC_MGR_ADD_SERVICE/*调用那个函数*/))
return -1;
//获得返回值
status = bio_get_uint32(&reply);
binder_done(bs, &msg, &reply);
return status;
}