您的位置:首页 > 其它

RILD - 第一章 - RILD流程概览

2017-08-20 21:35 176 查看
注:本文基于MTK Android N平台分析

参考:

- 《深入理解Android:Telephony原理剖析与最佳实践》—杨清平

- 大神写的分析博客

前言

目前在负责Telephony模块,自己也想从上到下看下Telephony模块的相关代码流程。如此,就讲自己的总结的笔记保存于此,既可以随时查阅,也希望能帮助到有缘人。

一、框架入口

1.1 说明

RILC主要分三块RILD,LibRILReferenceRIL

RILD的作用:

在init.modem.rc(AOSP为init.rc)中设置为系统服务启动。

service ril-daemon-mtk /vendor/bin/mtkrild


代码主要在
vendor/mediatek/proprietary/hardware/ril/gsm/ rild


主要文件:

rild.c
: 函数入口

主要功能是启动LibRIL和ReferenceRIL,以及打通它们之间的连接

LibRIL的作用:

RILD中启动

代码主要在
vendor/mediatek/proprietary/hardware/ril/gsm/librilmtk/


主要文件:

ril.cpp
: LibRIL主逻辑实现

ril_event.h
:定义EventLoop机制的Event结构体和关键的处理方法

ril_event.cpp
:EventLoop相关逻辑实现

ril_commands.h
:定义了LibRIL接收到RILJ发送的SOL消息的处理函数和返回函数

ril_unsol_commands.h
:定义了LibRIL UNSOL消息的处理函数

主要功能是从RILJ与 ReferenceRIL的信息中介。

ReferenceRIL的作用:

RILD中启动

代码主要在
vendor/mediatek/proprietary/hardware/ril/gsm/mtk-ril/


主要文件:

ril_callbacks.c
(AOSP中为reference_ril.c):ReferenceRIL主要逻辑文件

atchannels.c
:跟AT通道逻辑相关文件

mtk_ril.h
:定义了一些ReferenceRIL使用的常量和数据结构。

主要功能是直接从Modem获取信息,并传给LibRIL

1.2 RILC层的入口函数

//@rild.c

extern void RIL_startEventLoop();

int main(int argc, char **argv) {

//动态库路径

const char * rilLibPath = NULL;

void *dlHandle;

...

//加载动态库

dlHandle = dlopen(rilLibPath, RTLD_NOW);

...

//①开启event loop 机制

RIL_startEventLoop();

...

//从链接库中(也就是reference-ril.c)寻找RIL_Init函数地址

rilInit =

(const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))

dlsym(dlHandle, "RIL_Init");

...

//②调用reference-ril.c中的RIL_Init函数进行初始化INIT,同时得到reference-ril的回调函数

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

//③注册得到的reference的回调函数

RIL_register(funcs);

}


在main函数中,主要干了三件事情:

RIL_startEventLoop()开启EventLoop循环。此循环在LibRIL中,主要是RILC用来获取RILD传递的信息(使用Socket)。见下图①

打开reference-ril.so动态库,构建ReadLoop循环。此循环主要是ReferenceRIL用来与Modem通信(使用AT)。其传入的参数s_rilEnv可以让ReferenceRIL调用LibRIL。见下图②。

RIL_register()是将reference-ril.so的回调函数,即一些控制ReaderLoop的函数,注册到LibRIL中。这样ReferenceLIB可以通过funcs调用LibRIL。我们可以把他们看成为一些接口函数,而接口的具体实现在reference库中。见下图③。

RILD,LibRIL,ReferenceRIIL三者的关系及初始化流程如下:



再来一张初始化时的流程图,下面介绍的EventLoop机制建立和ReadLooper建立都在此主流程中:



1.3 总结梳理

通过上面三件事情,分别开启了LibRIL的EventLoop和ReferenceRIL的ReaderLoop,且打通了他们之间的通道(使用回调函数),使得他们可以脱离RILD来直接进行相互通信。

Step2构建EventLoop的流程在第二章讲述

Step5初始化ReferenceRIL,构建ReaderLoop在第三章讲述

Step9初始化注册监听在第四章讲述。

那么还有两个问题:

LibRIL如何使用ReferenceRIL的回调向其传递信息。

ReferenceRIL如何使用回调向LibRIL回传信息。

由于这两点在实际的流程中更便于说明,所以放到第五章的完整流程中来说明。

附: reference-ril.so库说明

此库是一个与AT相关的动态链接库,它有不同的厂商实现。之所以使用库的形式,就是考虑到每个厂商使用的Modem不同,我们没法用统一的接口去向底层负责,因此使用库的形式。这样一来,不同的Modem厂商提供不同的链接库,只要符合RIL层的框架即可。而当前的链接库中最主要的就是就是reference-ril.c和atchannel.c文件。

reference-ril.so回调函数:一些控制ReadLoop的函数,我们可以把他们看成为一些接口函数,而接口的具体实现在reference库中。其关键回调函数见3.2.3

注:在MTK中reference-ril.c改名为ril_callbacks.c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rild