云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > Android中RIL层详细分析解析

Android中RIL层详细分析解析

  • 62 次阅读
  • 3 次下载
  • 2025/5/1 7:32:38

argc = argc -i + 1; } else {

static char * newArgv[MAX_LIB_ARGS]; static char args[PROPERTY_VALUE_MAX]; rilArgv = newArgv;

property_get(LIB_ARGS_PROPERTY, args, \ argc = make_argv(args, rilArgv); }

// Make sure there's a reasonable argv[0] rilArgv[0] = argv[0];

/*利用得到的rilInit函数指针,调用真正的RIL_Init ,实际是动态加载动态库去链接reference-ril.c ,由dlopen()函数加载*/

funcs = rilInit(&s_rilEnv, argc, rilArgv);

/*RIL_register作用一:把vendor RIL(即RIL_init) 注册到reference-ril库去等待,dopen()函数加载链接

附:RIL_init通过是onRequest()方法,将上层来的请求进行映射后转换成对应的AT命令发给硬件,rild通过RIL_register注册这一指针。

RIL_register作用二:创建rild socket主要是等待java层得数据通过,传到下一层,还创建debug socket*/ RIL_register(funcs); done: while(1) {

// sleep(UINT32_MAX) seems to return immediately on bionic sleep(0x00ffffff); }

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 所有文件:

hardware/ril/libril$ ls

Android.mk NOTICE ril_event.h ril.cpp ril_event.cpp ril_commands.h ril_unsol_commands.h MODULE_LICENSE_APACHE2

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

与rild结合相当紧密,是其共享库,编译时就已经建立了这一关系。组成部分为ril.cpp,ril_event.cpp。libril.so驻留在rild这一守护进程中,主要完成同上层通信的工作,接受ril请求并传递给librefrence_ril.so, 同时把来自librefrence_ril.so的反馈回传给调用进程

在编译时libril被链入rild,它为rild提供了event处理功能,还提供了在rild与Vendor RIL之间传递请求和响应消息的能力。

Libril提供的主要功能分布在两个主要方法内,一个是RIL_startEventLoop()方法,另一个是RIL_register()方法

RIL_startEventLoop()方法所提供的功能就是启用eventLoop线程,开始执行RIL消息队列。

RIL_register()方法的主要功能是启动名为rild 的监听端口,等待java 端通过socket进行连接。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

RIL_startEventLoop函数 libril/ril.cpp->RIL_startEventLoop()

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- extern \

RIL_startEventLoop(void) {

int ret;

pthread_attr_t attr;

LOGD(\

/* spin up eventLoop thread and wait for it to get started */ s_started = 0;

pthread_mutex_lock(&s_startupMutex); pthread_attr_init (&attr);

pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

LOGD(\

ret = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);//创建线程,为入口函数 LOGD(\ while (s_started == 0) {

pthread_cond_wait(&s_startupCond, &s_startupMutex); }

pthread_mutex_unlock(&s_startupMutex); if (ret < 0) {

LOGE(\ return; } }

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

开启libril.so中的event机制, 在RIL_startEventLoop中,是最核心的由多路I/O驱动的消息循环

RIL_startEventLoop函数。RIL_startEventLoop在ril.cpp中实现, 它的主要目的是通过pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL)建立一个dispatch线程,入口点在eventLoop. 而eventLoop中,会调ril_event.cpp中的ril_event_loop()函数,建立起消息(event)队列机制。

我们来仔细看看这一消息队列的机制,这些代码都在ril_event.cpp中。 void ril_event_init();

void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param); void ril_event_add(struct ril_event * ev);

void ril_timer_add(struct ril_event * ev, struct timeval * tv); void ril_event_del(struct ril_event * ev); void ril_event_loop();

----------------------------------------------- struct ril_event { struct ril_event *next; struct ril_event *prev; int fd;

int index; bool persist;

struct timeval timeout; ril_event_cb func; void *param; };

-----------------------------------------------------

每个ril_event结构,与一个fd句柄绑定(可以是文件,socket,管道等),并且带一个func指针去执行指定的操作。

具体流程是: ril_event_init完成后,通过ril_event_set来配置一新ril_event,并通过ril_event_add加入队列之中(实际通常用rilEventAddWakeup来添加),add会把队列里所有ril_event的fd,放入一个fd集合readFds中。这样ril_event_loop能通过一个多路复用I/O的机制(select)来等待这些fd, 如果任何一个fd有数据写入,则进入分析流程processTimeouts(),processReadReadies(&rfds, n),firePending()。 后文会详细分析这些流程。另外我们可以看到, 在进入ril_event_loop之前, 已经挂入了一s_wakeupfd_event, 通过pipe的机制实现的, 这个event的目的是可以在一些情况下,能内部唤醒ril_event_loop的多路复用阻塞,比如一些带timeout的命令timeout到期的时候。 至此第一个任务分析完毕,这样便建立起了基于event队列的消息循环,稍后便可以接受上层发来的的请求了(上层请求的event对象建立,在第三个任务中)。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- static void *

eventLoop(void *param) { int ret; int filedes[2];

LOGD(\LOGD(\ ril_event_init();//初始化

LOGD(\ pthread_mutex_lock(&s_startupMutex); s_started = 1;

pthread_cond_broadcast(&s_startupCond); pthread_mutex_unlock(&s_startupMutex); ret = pipe(filedes); if (ret < 0) {

LOGE(\ return NULL; }

s_fdWakeupRead = filedes[0];// 消息循环中侦听

s_fdWakeupWrite = filedes[1];// 用于通知消息循环定义消息已发送

LOGD(\ processWakeupCallback, NULL);--\ fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);

/*先执行 processWakeupCallback中的read函数,再把参数,传给ril_event_set进行设置*/

ril_event_set(&s_wakeupfd_event, s_fdWakeupRead, true, processWakeupCallback, NULL); /*在ilEventAddWakeup进行ril_evnet_add事件添加和triggerEvLoop()实现管道写端*/

LOGD(\ rilEventAddWakeup (&s_wakeupfd_event); LOGD(\ // Only returns on error

LOGD(\ ril_event_loop();

LOGD(\ LOGE (\ return NULL; }

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ril_event_init()主要工作是清零和处理三种函数(定时,监听,挂起);

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Initialize internal data structs

void ril_event_init()

{

MUTEX_INIT();

LOGD(\ FD_ZERO(&readFds); init_list(&timer_list); init_list(&pending_list);

memset(watch_table, 0, sizeof(watch_table)); }

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ril_event_set()的作用是:通过管道,对读到的数据进行初始化 ---------注册进程唤醒事件回调

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)

{

LOGD(\* param)-\

dlog(\ memset(ev, 0, sizeof(struct ril_event)); ev->fd = fd; ev->index = -1; ev->persist = persist; ev->func = func; ev->param = param;

fcntl(fd, F_SETFL, O_NONBLOCK); }

搜索更多关于: Android中RIL层详细分析解析 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

argc = argc -i + 1; } else { static char * newArgv[MAX_LIB_ARGS]; static char args[PROPERTY_VALUE_MAX]; rilArgv = newArgv; property_get(LIB_ARGS_PROPERTY, args, \ argc = make_argv(args, rilArgv); } // Make sure there's a reasonable argv[0] rilArgv[0] = argv[0]; /*利用得到的rilInit函数指针,调用真正的RIL_Init ,实际是动态加载动态库

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com