




已阅读5页,还剩9页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Android RIL 结构分析与移植 介绍 本文档对 Android RIL 部分的内容进行了介绍 其重点放在了 Android RIL 的原生代码 部分 包括四个主题 1 Android RIL 框架介绍 2 Android RIL 与 WindowsMobile RIL 3 Android RIL porting 4 Android RIL 的 java 框架 在本文档中将 Android 代码中的重要模块列出进行分析 并给出了相关的程序执行流 程介绍 以加深对模块间交互方式的理解 对于 java 代码部分 这里仅进行简单的介绍 如果需要深入了解 可以查看相关参考 资料 本文档中还对 Android RIL 的 Porting 部分内容进行了描述和分析 针对对 unix 操作系统环境并不熟悉的读者 本文档中所涉及到的相关知识包括 Unix file system Unix socket Unix thread Unix 下 I O 多路转接 以上信息可以在任意一份描述 Unix 系统调用的文档中找到 1 Android1 Android RILRIL 框架介绍框架介绍 术语 fd unix 文件描述符 pipe unix 管道 cond 一般是 condition variable 的缩写 tty 通常使用 tty 来简称各种类型的终端设备 unsolicited response 被动请求命令来自 baseband event loop android 的消息队列机制 由 unix 的系统调用 select 实现 init rc init 守护进程启动后被执行的启动脚本 HAL 硬件抽象层 Hardware Abstraction Layer HAL 1 1 Android RIL 概况 Android RIL 提供了无线硬件设备与电话服务之间的抽象层 下图展示了 RIL 在 Android 体系中的位置 android 的 ril 位于应用程序框架与内核之间 分成了两个部分 一个部分是 rild 它负 责 socket 与应用程序框架进行通信 另外一个部分是 Vendor RIL 这个部分负责向下 是通过两种方式与 radio 进行通信 它们是直接与 radio 通信的 AT 指令通道和用于传 输包数据的通道 数据通道用于手机的上网功能 对于 RIL 的 java 框架部分 也被分成了两个部分 一个是 RIL 模块 这个模块主要用 于与下层的 rild 进行通信 另外一个是 Phone 模块 这个模块直接暴露电话功能接口 给应用开发用户 供他们调用以进行电话功能的实现 1 2 Android RIL 目录结构 Android 的 RIL 模块位于 Android hardware ril 文件夹 有三个子模块 rild libril reference ril include 文件夹 包含 RIL 头文件 最主要的是 ril h rild 文件夹 RIL 守护进程 开机时被 init 守护进程调用启动 里面仅有 main 函数作为入口点 负 责完成 RIL 初始化工作 在 rild c 文件中 将完成 ril 的加载过程 它会执行如下操作 动态加载 Vendor RIL 的 so 文件 执行 RIL startEventLoop 开启消息队列以进行事件监听 通过执行 Vendor RIL 的 rilInit 方法来进行 Vendor RIL 与 libril 的关系建立 在 rild 文件夹中还包括一个 radiooptions c 文件 它的作用是通过串口将一些 radio 相关 的参数直接传给 rild 来对 radio 进行配置 libril 文件夹 在编译时 libril 被链入 rild 它为 rild 提供了 event 处理功能 还提供了在 rild 与 Vendor RIL 之间传递请求和响应消息的能力 Libril 提供的主要功能分布在两个主要方法内 一个是 RIL startEventLoop 方法 另 一个是 RIL register 方法 RIL startEventLoop 方法所提供的功能就是启用 eventLoop 线程 开始执行 RIL 消息 队列 RIL register 方法的主要功能是启动名为 rild 的监听端口 等待 java 端通过 socket 进行连接 reference ril 文件夹 Android 自带的 Vendor RIL 的参考实现 被编译成 so 文件 由于本部分是厂商定制的 重点所在 所以被设计为松散耦合 且可灵活配置的 在 rild 中通过 opendl 的方式 加载 librefrence so 负责直接与 radio 通信 这包括将来自 libril 的指令转换为 AT 指令 并 且将 AT 指令写入 radio 中 reference ril 会接收调用者传来的参数 参数内容为与 radio 的通信方式 如通过串口 连接 radio 那么参数为这种形式 d dev ttySx 1 3 Android RIL 中的消息 event 队列机制 在 Android RIL 中 为了达到等待多路输入并且不出现阻塞的目的 使用了 IO 多路复 用机制 如果使用阻塞 I O 进行网络的读取写入 这意味着假如需要同时从两个网络文件描述符 中读内容 那么如果读取操作在等待网络数据到来 这将可能很长时间阻塞在一个描 述符上 另一个网络文件描述符不管有没有数据到来都无法被读取 一种解决方案是 如果使用非阻塞 I O 进行网络的读取写入 在读取其中一个网络文件描述符如果阻塞 将直接返回 再读取另外一个 这种方式的循环被称之为轮询 轮询方式确实能解决 进行多路 io 操作时的阻塞问题 但是这种方法的不足之处是反复的执行读写调用将浪 费 cpu 时钟 I O 多路转接技术在这里提供了另一种比较好的解决方案 它会先构造一张有关 I O 描述符的列表 然后调用 select 函数 当 IO 描述符列表中的 一个描述符准备好进行 I O 时 该函数返回 并告知可以读或写哪个描述符 Android RIL 中消息队列的核心实现思想就是这种 I O 多路转接技术 消息队列机制的实现在 ril event cpp 中 其中被定义的 ril event 结构是消息的主体 每个 ril event 结构 与一个 fd 句柄绑定 可以是文件 socket 管道等 并且带一个 func 指针 这个 func 指针所指的函数是个回调函数 它指定了当所绑定的 fd 准备好进 行读取时所要进行的操作 消息队列的开始点为 RIL startEventLoop 函数 RIL startEventLoop 在 ril cpp 中实现 它的主要目的是通过 pthread create struct ril event prev int fd int index bool persist struct timeval timeout ril event cb func void param 初始化一个新 ril event 的操作是通过 ril event set 来完成的 并通过 ril event add 加入到消息队列之中 add 会把队列里所有 ril event 的 fd 放入一 个 fd 集合 readFds 中 这样 ril event loop 能通过一个多路复用 I O 的机制 select 来 等待这些 fd 在进入 ril event loop 之前 在 eventLoop 中已经创建和挂入了 s wakeupfd event 它是通过 pipe 的机制实现的 这个管道 fd 的回调函数并没有实 现什么功能 它的目的只是为了让 select 方法能返回一次 这样 select 方法就能重新 跟踪新加入事件队列的 fd 和 timeout 设置 所以在添加新 fd 到 eventLoop 时 往往不是直接调用 ril event add 实际通常用 rilEventAddWakeup 来添加 这个方法除了会间接调用 ril event add 外 还会调用 triggerEvLoop 函数来向 s fdWakeupWrite 中写入一个空字符 这样 select 函数会返 回并重新执行 新加入的文件描述符便得以被 select 加载并跟踪 如果在 ril event 队列中任何一个 fd 已经准备好 则进入分析流程 processTimeouts processReadReadies rfds n firePending 其中 firePending 方法执行这个 event 的 func 也就是回调函数 在 Android RIL 初始化完成后 将有几个 event 被挂入到 eventLoop 中 1 s listen event 名为 rild 的 socket 主要 requeset response 通道 2 s debug event 名为 rild debug 的 socket 调试用 requeset response 通道 3 s wakeupfd event 无名管道 用于队列主动唤醒 这其中最为重要的 event 就是 s listen event 它作为 request 与 response 的通道实 现 在 ril event cpp 中还持有一个 watch table 数组 一个 timer list 链表和一个 pending list 链表 watch table 数组的目的很单纯 存放当前被 eventLoop 等待的 ril event 非 timer event 供 eventLoop 唤醒时使用 timer list 是存放 timer event 的链表 在 eventLoop 唤醒时要对这些 timer event 单独 进行处理 pending list 待处理 对其回调函数进行调用 的所有 ril event 的链表 1 4 Android RIL 中初始化流程分析 Rild 的初始化流程 初始化流程从 rild c 中的 main 函数开始 它被 init 守护进行调用执行 首先在 main 函数内会首先通过 dlopen 函数加载 Vendor RIL 在自带的参考实现中 为 librefrence ril so 接着调用 RIL startEventLoop 函数来启动消息队列机制 调用 librefrence ril so 的 RIL Init 函数来进行 Vendor RIL 的初始化 RIL Init 函数 执行后会返回一个 RIL RadioFunction 结构体 这个结构体内最重要的成员就是 onRequest 方法 onRequest 方法会被 dispatchFunction 调用 也就是说 dispatchFunction 调用是程序流从 rild 转入 Vendor RIL 的分界点 RIL register 函数将实现两个目地 一个是将 RIL INIT 中获得的 RIL RadioFunction 进行注册 rild 通过此种方式保证自己持有一个 RIL RadioFunction 实例 第二个是将 s fdListen 加入到消息队列机制中 开启 s fdListen 的事件监听 Vendor RIL 的初始化流程 RIL Init 被调用后首先通过参数获取硬件接口的设备文件或模拟硬件接口的 socket 参见上文中对 reference ril 文件夹的介绍 接下来是创建 mainLoop 线程 并跳入到线程内执行 mainLoop 会建立起与硬件的通 信 然后通过 read 方法阻塞等待硬件的主动上报或响应 mainLoop 还会调用 initlizeCallBack 函数来向 radio 发送一系列的 AT 命令来进行 radio 的初始化设置工作 1 5 Android RIL 中 request 流程分析 上层应用开始向 rild 通过 socket 传输数据时 通过 RIL 消息队列机制 s listen event 的回调函数 listenCallBack 将会被调用 开始进行数据流的分析与处理 接下来 s fdCommand accept s fdListen sockaddr peeraddr socklen 获取 传入的 socket 描述符 也就是上层的 java RIL 传入的连接 然后 通过 record stream new 建立起一个 RecordStream 将这个 record stream 与 s fdCommand 绑定 RecordStream 实际上是一个用于存放数据的结构体 这个结构体 提供了一些操作类来保证这个 RecordStream 所绑定的文件描述符被读取时里面的数据 会被完整读取 一旦 s fdCommand 中有数据 它的回调函数 processCommandsCallback 将会被调用 processCommandsCallback 通过 record stream get next 阻塞读取 s fdCommand 上 发来的 数据 直到收到一完整的 request 然后将其传递进 processCommandBuffer 函数 processCommandBuffer 正式进入了命令的解析部分 每个接收到的命令将以 RequestInfo 的形式存在 从 socket 过来的数据流 是 Parcel 处 理过的序列化字节流 在这里会通过反序列化的方法提取出来 最前面的是 request 号 以及 token 域 request 的递增序列号 request 号是一个 CommandInfo 它在 ril command h 中定义 接下来 这个 RequestInfo 会被挂入 pending 的 request 队列 执行具体的 dispatchFunction 进行详细解析 dispatchFunction 方法有着多种实现 如 dispatchVoid dispatchString 它们的调用取 决于 Parcel 的参数传入形式 比如说在 dispatchDial 方法中 Parcel 对象将被解析为 RIL Dial 结构 这是 disptachFunction 的任务之一 它的另一个任务就是调用 onRequest 方法 并将解析的内容传入 onRequest 方法 从 onRequest 方法开始 程序控制流脱离了 RILD 进入到了 Vendor RIL 中 onRequest 方法会通过传入的请求类型来调用指定的 request 方法 request 方法则负责组装 AT 指令并下发给 at send command 方法集合中的一 个 这个方法集合提供了针对不同类型 AT 指令的实现 如单行 AT 指令 at send command singleline 短信息指令 at send command sms 等 最后 执行 at send command full 再通过一个互斥的 at send command full nolock 调用 完成最终的写出操作 在 writeline 中 写出到初 始化时打开的设备中 需要注意的是 at send command full nolock 在将指令写入 radio 后并不会直接返 回 而是通过条件变量等待响应信息 得到响应信息后会携带这些信息返回 具体流 程可以参考下面的 response 流程分析 1 6 Android RIL 中 response 流程分析 AT 的 response 有两种 一种是 unsolicited 另一种是普通 response 也就是命令的 响应 response 信息的获取在 readerLoop 中 由 readline 函数读取上来 读取到的 line 将被传入 processLine 函数进行解析 processLine 函数首先会判断当 前的响应是主动响应还是普通响应 如果是主动响应 将调用 handleUnsolicited 函数 如果为普通响应 那么将调用 handleFinalResponse 函数进行处理 对响应串的主要的解析过程 由 at tok c 中的各种解析函数完成 提供字符串分析解 析功能 对主动上报的解析 handleUnsolicited 方法处理主动上报 它会调用 onUnsolicited 来进行进一步的解析 这个函数在 Vendor RIL 初始化时被传入 at open 函数 onUnsolicited 只解析出头 部 一般是 XXXX 的形式 然后按类型决定下一步操作 操作为 RIL onUnsolicitedResponse 和 RIL requestTimedCallback 两种 在 RIL onUnsolicitedResponse 函数中 通过 Parcel 传递 将 RESPONSE UNSOLICITED unsolResponse request 号 写入 Parcel 然后调用对应的 responseFunction 完成进一步的的解析 将解析的数据写入 Parcel 中 最后通过 sendResponse sendResponseRaw blockingWrite writeLine 将数据写回给与 应用层通信的 socket 在 RIL requestTimedCallback 函数中 通过 event 机制实现的 timer 机制 回调对应 的内部处理函数 通过 internalRequestTimedCallback 将回调添加到 event 循环 最终 完成 callback 上挂的函数的回调 比如 pollSIMState onPDPContextListChanged 等回 调 不用返回上层 内部处理就可以 对普通上报的解析 IsFinalResponse 和 isFinalResponseError 所处理的是一条 AT 指令的响应上报 它们 将转入 handleFinalResponse 方法 handleFinalResponse 函数会将所有响应信息装入 sp response 这是一个 ATResponse 结构 它的成员包括成功与否 success 以及一个中间结果 p intermediates handleFinalResponse 在将响应结果保存至 sp response 后 设置 s commandcond 这一条件变量 此条件变量由 at send command full nolock 等待 at send command full nolock 获得到了完整的响应信息 在 sp response 中 便 开始进行响应信息的处理 最后由 RIL onRequestComplete 将响应数据序列化并通过 sendResponse 传递至与应用层通信的 socket 这一部分与 RIL onUnsolicitedResponse 函数的功能非常相似 请参考对主动上报的解析部分 2 Android2 Android RILRIL 与与 WindowsMobileWindowsMobile RILRIL Android RIL 与 WindowsMobile RIL 在设计思路上都是作为一个 radio 的抽象 为 上层提供电话服务 但在实现方式上两者有着一定的差异 这种差异的产生主要是 源自操作系统机制的不同 Android RIL 被实现为 HAL 相对于 windows mobile 中被实现为驱动的方式 Android RIL 模块的内聚性更为理想 可维护性也将更强 你也可以把 Android Ril 看做一个中间件 Android RIL 部分的开发工作 只需要拿到相应的 radio 文件描 述符 就可以进行操作 无需关注 radio 的 I O 驱动实现 2 1 两者在与应用通信上的实现对比 WindowsMobile RIL 在实现与应用的通信时提供了 RIL Proxy 在这个层面中它定义 了大量的 RIL 函数来作为电话服务请求 这一点与 Android RIL 的实现比较 相似 Android RIL 中在 ril h 内提供了一系列的宏来定义电话服务请求 在 Android 中的 rild 功能类似于 windows mobile RIL 的 RIL proxy 它同样也是起 到一个中介的作用 为上层接口向下传递请求 并上传回响应 在 windows mobile RIL 中要为每一个应用程序客户提供一份 Ril Proxy 实例 对于这两种操作系统平台 RIL 所定义的所有请求是不可更改的 2 2 两者在线程结构与回调机制上的对比 在 windows mobile 的设计中 request 与 response 被设计为异步执行的 他们分 别使用两个队列来对它们的异步行为进行管理 执行命令下发和上报命令处理的过 程也互不影响 下发命令与命令的相应响应之间的依赖关系由应用程序来捏合 在 android ril 中的 request 与 response 设计与 windows mobile 不同 它的命令与 响应之间是同步的过程 也就是说一条命令被下发后 将等待执行结果 并进行处 理 再上向上层发 而不是直接异步的进行处理和向上发送 3 Android3 Android RILRIL portingporting 3 1 命名 要实现某个无线模块的 RIL 需要创建一个实现了所有请求方法的共享库 保证 Android 能够响应无线通信请求 所有的请求被定义 ril h 中 不同的 Modem 使用不同的端口 这个在 init rc 中设置 Android 提供了一个参考 Vendor RIL RIL 参考源码在 reference ril 将你自己的 Vendor RIL 实现编译为共享库形式 libril so 比如 libril techfaith 124 so 其中 libril 所有 vendor RIL 的开头 公司缩写 RIL 版本 number so 文件扩展 3 2 Android RIL 的配置与加载 在 init rc 文件中 将通过这种方式来进行 Android RIL 的加载 service ril daemon system bin rild l system lib libreference ril so d dev ttyS0 也可以手动加载 system bin rild l system lib libreference ril so d dev ttyS0 这两种方式 都将启动 rild 守护进程 然后通过 l 参数将 libreference ril so 共享库 链入 libreference ril so 的参数 d 是指加载一个串口设备 dev ttyS0 则是这个串 口设备的具体设备文件 除了参数 d 外 还有 s 代表加载类型为 socket 的设备 p 代表回环接口 3 3 Android RIL 的编译结构 rild 被编译成可执行文件 rild 以守进程的形式执行 libril 将被编译为共享库 并被链入 rild Vendor RIL 可以以两种方式来运行 如果定义了 RIL SHLIB 宏 那么它将被编译成共享库 如 果没定义 RIL SHLIB 宏 它将以守护进程程序的方式被调用执行 4 4 Android RIL 的 java 框架 Android RIL 的 Java 部分也被分为了两个模块 RIL 模块与 Phone 模块 其中 RIL 模块负责进行请求以及相应的处理 它将直接与 RIL 的原声代码进行通信 而 Phone 模块则向应用程序开发者提供了一系列的电话功能接口 4 1 RIL 模块结构 在 RIL java 中实现了几个类来进行与下层 rild 的通信 它实现了如下几个类来完成操作 RILRequest 代表一个命令请求 RIL RILSender 负责 AT 指令的发送 RIL RILReceiver 用于处理主动和普通上报信息 RIL RILSender 与 RIL RILReceiver 是两个线程 RILRequest 提供了 obtain 方法
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 合同贷款抵押6篇
- 2025年黑河海关综合技术中心招聘考前自测高频考点模拟试题附答案详解
- 赛事氛围营造技术-洞察与解读
- 微生物降解炸药机理-洞察与解读
- 2025成都农商银行社会招聘(综合柜员)考前自测高频考点模拟试题附答案详解(模拟题)
- 2025江苏连云港市金灌投资发展集团有限公司、灌南城市发展集团有限公司等招聘34人模拟试卷及答案详解(夺冠系列)
- 2025湖南学院后勤处招聘5人考前自测高频考点模拟试题含答案详解
- 2025北京市平谷区教育委员会所属事业单位面向应届毕业生招聘教师140名考前自测高频考点模拟试题有答案详解
- 2025湖南邵阳市洞口县教育局所属事业单位公开招聘工作人员39人模拟试卷及答案详解(网校专用)
- 2025年山东兴罗投资控股有限公司招聘工作人员(14人)考前自测高频考点模拟试题及答案详解(必刷)
- 稳评从业人员培训考试及答案解析
- 2025年甘肃省兰州市榆中县招聘乡村医生考试参考试题及答案解析
- 燃气入户安检课件
- 预防静电安全知识培训课件
- 临时用电专项施工方案(老旧小区改造项目)
- 2025党校中青班入学考试试题及答案
- GB/T 8165-2025不锈钢复合钢板和钢带
- 2025年中国咖啡饮料行业市场深度分析及发展战略规划报告
- 小学生科普课件向日葵
- 铁路工务介入管理办法
- 25年一建建筑实务真题及答案
评论
0/150
提交评论