qcril:第1章 RILD及Qcril初始化流程

第1章 RILD及Qcril初始化流程

    Rild是android提供的框架,位置位于AP侧(AP主处理器),对接Phone进程和BP侧modem。(BP从处理器)

图1

    双卡手机在phone进程中会有2个phone的实例对应各个卡槽,相应的RILD进程也会有2个,phone和RILD之间通过Socket保持连接,各卡槽之间的操作互相独立。

    高通用qcril+qmi机制实现,而MTK则直接使用AT指令与modem通信。

1.1 RILD进程的启动

    Rild是系统服务,在init.rc中能找到启动的描述。

/hardware/ril/rild/rild.rc中启动第一个rild

图1 rild.rc中启动第一个rild

/device/qcom/common/rootdir/etc/init.qcom.rc中启动第二个rild:

图2启动第二个rild(这里除了rild2还有rild3)

 

2.1 RILD主函数

         根据init.qcom.rc可以看出,rild的入口函数名字为main。/hardware/ril/rild/rild.c

接着看一下rild.c的main函数。

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

…….

//1.  从启动参数中获取clientID,代表几就是第几个RILD

for (i = 1; i < argc ;) {……

         if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {……

clientId = argv[i+1];

//2.  使用clientID设置RILD的socket名字

if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {……}

//3. 获取vendor ril库路径(3.1)

if (rilLibPath == NULL) {

    if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {

        goto done;

} else {  rilLibPath = libPath;     }   }

//4. 打开vendor ril库(3.1)

dlHandle = dlopen(rilLibPath, RTLD_NOW);

//5. 启动消息循环,LIdRIL开始循环监听socket事件(3.2)

RIL_startEventLoop();

//6. 获取vendor RIL的初始化入口方法(3.3)

rilInit =(const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, "RIL_Init");

//7. 调用reference-ril.so动态链接库的RIL_Init方法,传递s_rilEnv参数给reference-ril.so,并返回funcs(3.3)

rilArgv[argc++] = "-c";

rilArgv[argc++] = (char*)clientId;

rilArgv[0] = argv[0];

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

//8. 调用libril.so的RIL_register函数,将funcs传递给libril.so(3.4)

RIL_register(funcs);

总结main函数的主要内容:

1)获取vendor ril并打开;(第3、4步,对应3.1)

2)启动消息循环;调用RIL_startEventLoop函数,LibRIL开启循环监听socket连接,即可开始接收RILJ发起的socket连接请求和RIL solicited消息请求。(第5步,对应3.2)

3)获得vendor ril入口方法,并取得vendor ril的消息处理函数列表;(6、7步,对应3.3)

4)注册vendor ril回调方法。(第8步,对应3.4)

S_rilEnv对应RIL_Env;

Funcs对应RIL_RadioFunctions。

LibRIL运行环境的加载过程,体现在rild.c代码的main函数中RIL_startEventLoop和RIL_register两个函数的调用。

3.1 深入分析main函数

3.1.1 获取vendor RIL库文件路径

         Main函数中通过getprop获取了vendor ril文件的路径,property名为“rild.libpath”。/hardware/ril/rild/rild.c文件中:

首先定义LIB_PATH_PROPERTY的值;

#define LIB_PATH_PROPERTY   "rild.libpath"

然后在main函数中获取vendor ril文件的路径:

property_get(LIB_PATH_PROPERTY, libPath, NULL)。

1. 找到libril-qc-qmi-1.so库文件路径;

2. 在/vendor/qcom/proprietary/qcril/qcril_qmi/qcril_qmi.mk中有描述;

图3库文件路径描述

    在取得了vendor ril库文件路径之后,打开库并取得文件句柄,流程似乎即将进入到vendor ril。但在此之前,rild会先启动一个子线程消息循环,然后再开始qcril的流程。

3.2 RIL_startEventLoop启动监听消息循环

    RIL_startEventLoop创建了一个线程,用于执行eventLoop这个函数。

1. Ril.cpp中的RIL_startEventLoop():

启动线程,执行eventLoop函数,在eventLoop函数中会将s_started置为1.

S_started会在eventLoop被执行后置为1,保证了线程启动后才离开这个函数

图4在while循环主要是通过判断s_started的值,保证线程已经启动且eventLoop已经开始被执行,因为在eventLoop函数中会将s_started值置为1。

2. eventLoop是Rild中消息获取和分发的中心,接下来来详细查看一下:

// 1.初始化fd_set(readFds)3.2.1;

// 2.初始化几个消息链表(watch_table/pending_list/timer_list);

//使RIL_startEventLoop退出;

//获得读&写管道3.2.2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值