说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Android GSM驱动模块详细分析

HTML文档下载 WORD文档下载 PDF文档下载
本文详细介绍了Android的GSM驱动模块的基本架构与初始化工作过程。

作者:熊猫哥哥

 

Android的RIL驱动模块, 在hardware/ril目录下,一共分rild,libril.so以及librefrence_ril.so三个部分,另有一radiooptions可供自动或手动调试使用。都依赖于include目录中ril.h头文件。目前cupcake分支上带的是gsm的支持,另有一cdma分支,这里分析的是gsm驱动。
  GSM模块,由于Modem的历史原因,AP一直是通过基于串口的AT命令与BB交互。包括到了目前的一些edge或3g模块,或像omap这类ap,bp集成的芯片,已经使用了USB或其他等高速总线通信,但大多仍然使用模拟串口机制来使用AT命令。这里的RIL(Radio Interface Layer)层,主要也就是基于AT命令的操作,如发命令,response解析等。(gprs等传输会用到的MUX协议等在这里并没有包含,也暂不作介绍。)
  以下是详细分析,本文主要涉及基本架构和初始化的内容:
  首先介绍一下rild与libril.so以及librefrence_ril.so的关系:
1. rild:
仅实现一main函数作为整个ril层的入口点,负责完成初始化。
2. libril.so:
与rild结合相当紧密,是其共享库,编译时就已经建立了这一关系。组成部分为ril.cpp,ril_event.cpp。libril.so驻留在rild这一守护进程中,主要完成同上层通信的工作,接受ril请求并传递给librefrence_ril.so, 同时把来自librefrence_ril.so的反馈回传给调用进程。
3. librefrence_ril.so:
rild通过手动的dlopen方式加载,结合稍微松散,这也是因为librefrence.so主要负责跟Modem硬件通信的缘故。这样做更方便替换或修改以适配更多的Modem种类。它转换来自libril.so的请求为AT命令,同时监控Modem的反馈信息,并传递回libril.so。在初始化时, rild通过符号RIL_Init获取一组函数指针并以此与之建立联系。
4. radiooptions:
radiooptiongs通过获取启动参数, 利用socket与rild通信,可供调试时配置Modem参数。
  接下来分析初始化流程,主入口是rild.c中的main函数,主要完成三个任务:
1. 开启libril.so中的event机制, 在RIL_startEventLoop中,是最核心的由多路I/O驱动的消息循环。
2. 初始化librefrence_ril.so,也就是跟硬件或模拟硬件modem通信的部分(后面统一称硬件), 通过RIL_Init函数完成。
3. 通过RIL_Init获取一组函数指针RIL_RadioFunctions, 并通过RIL_register完成注册,并打开接受上层命令的socket通道。
  首先看第一个任务,也就是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中。

Android的RIL驱动模块, 在hardware/ril目录下,一共分rild,libril.so以及librefrence_ril.so三个部分,另有一radiooptions可供自动或手动调试使用。都依赖于include目录中ril.h头文件。目前cupcake分支上带的是gsm的支持,另有一cdma分支,这里分析的是gsm驱动。

  GSM模块,由于Modem的历史原因,AP一直是通过基于串口的AT命令与BB交互。包括到了目前的一些edge或3g模块,或像omap这类ap,bp集成的芯片,已经使用了USB或其他等高速总线通信,但大多仍然使用模拟串口机制来使用AT命令。这里的RIL(Radio Interface Layer)层,主要也就是基于AT命令的操作,如发命令,response解析等。(gprs等传输会用到的MUX协议等在这里并没有包含,也暂不作介绍。)

  以下是详细分析,本文主要涉及基本架构和初始化的内容:

  首先介绍一下rild与libril.so以及librefrence_ril.so的关系:

1. rild:

仅实现一main函数作为整个ril层的入口点,负责完成初始化。

2. libril.so:

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

3. librefrence_ril.so:

rild通过手动的dlopen方式加载,结合稍微松散,这也是因为librefrence.so主要负责跟Modem硬件通信的缘故。这样做更方便替换或修改以适配更多的Modem种类。它转换来自libril.so的请求为AT命令,同时监控Modem的反馈信息,并传递回libril.so。在初始化时, rild通过符号RIL_Init获取一组函数指针并以此与之建立联系。

4. radiooptions:

radiooptiongs通过获取启动参数, 利用socket与rild通信,可供调试时配置Modem参数。

  接下来分析初始化流程,主入口是rild.c中的main函数,主要完成三个任务:

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

2. 初始化librefrence_ril.so,也就是跟硬件或模拟硬件modem通信的部分(后面统一称硬件), 通过RIL_Init函数完成。

3. 通过RIL_Init获取一组函数指针RIL_RadioFunctions, 并通过RIL_register完成注册,并打开接受上层命令的socket通道。

  首先看第一个任务,也就是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对象建立,在第三个任务中)。
接下来看第二个任务,这个任务的入口是RIL_Init, RIL_Init首先通过参数获取硬件接口的设备文件或模拟硬件接口的socket. 接下来便新开一个线程继续初始化, 即mainLoop。
mainLoop的主要任务是建立起与硬件的通信,然后通过read方法阻塞等待硬件的主动上报或响应。在注册一些基础回调(timeout,readerclose)后,mainLoop首先打开硬件设备文件,建立起与硬件的通信,s_device_path和s_port是前面获取的设备路径参数,将其打开(两者可以同时打开并拥有各自的reader,这里也很容易添加双卡双待等支持)。
接下来通过at_open函数建立起这一设备文件上的reader等待循环,这也是通过新建一个线程完成, ret = pthread_create(&s_tid_reader, &attr, readerLoop, &attr),入口点readerLoop。
AT命令都是以\r\n或\n\r的换行符来作为分隔符的,所以readerLoop是line驱动的,除非出错,超时等,否则会读到一行完整的响应或主动上报,才会返回。这个循环跑起来以后,我们基本的AT响应机制已经建立了起来。它的具体分析,包括at_open中挂接的ATUnsolHandler, 我们都放到后面分析response的连载文章里去。
有了响应的机制(当然,能与硬件通信也已经可以发请求了),通过RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0),跑到initializeCallback中,执行一些Modem的初始化命令,主要都是AT命令的方式。发AT命令的流程,我们放到后面分析request的连载文章里。这里可以看到,主要是一些参数配置,以及网络状态的检查等。至此第二个任务分析完毕,硬件已经可以访问了。
最后是第三个任务。第三个任务是由RIL_Init的返回值开始的,这是一个RIL_RadioFunctions结构的指针。
typedef struct {   int version;        /* set to RIL_VERSION */   RIL_RequestFunc onRequest;   RIL_RadioStateRequest onStateRequest;   RIL_Supports supports;   RIL_Cancel onCancel;   RIL_GetVersion getVersion;} RIL_RadioFunctions;
其中最重要的是onRequest域,上层来的请求都由这个函数进行映射后转换成对应的AT命令发给硬件。
rild通过RIL_register注册这一指针。
  RIL_register中要完成的另外一个任务,就是打开前面提到的跟上层通信的socket接口(s_fdListen是主接口,s_fdDebug供调试时使用)。
  然后将这两个socket接口使用任务一中实现的机制进行注册(仅列出s_fdListen)
ril_event_set (&s_listen_event, s_fdListen, false, listenCallback, NULL);rilEventAddWakeup (&s_listen_event);
这样将两个socket加到任务一中建立起来多路复用I/O的检查句柄集合中,一旦有上层来的(调试)请求,event机制便能响应处理了。到这里启动流程已经分析完毕。

 

 

为什么JavaScript有能力成为未来企业级编程语言? Red Hat CEO:拥抱开源 拥抱克隆 小米手机-HAXLR8on硬件黑客马拉松 开团了! 移动周报:雷军做红米的N个理由 Pangea Software CEO:08年App Store游戏降价大战的真相 揭秘MongoDB最新Java驱动:更好的JVM支持,指日可期的异步 不仅只有IE Mozilla将于发布Win8平台Metro版Firefox 360搜索发布新产品“我的搜索” 引入网民评价和网站名片功能 AppScale:Google App Engine的开源实现 近期十大优秀jQuery插件推荐 通过语音识别来编程 速度远超键盘 BrowserStack:多系统跨浏览器兼容性测试工具API发布 更加开放?Path向13家应用开发商开放API 重金力邀开发者 联想智能桌面应用开发大赛开幕 SDCC 2013大会讲师名单议题出炉 8月20日五折票价最后一天 程序员困境:底层编码能力正逐步丧失 寓教于乐 给代码审查者的几点建议 裁员4千、总裁员人数超过7.5万,难掩思科锋芒 物联网离普罗大众还有多远? 悼念斯诺登使用的加密电邮服务——Lavabit架构解析 运营商上阵OTT “一笑泯恩仇”后路在何方 [企业开源系列]后起之秀Facebook凭什么挑战互联网霸主Google? 谷歌推出免费标签管理应用Tag Manager McAfee CTO Phyllis Schneck被任命为NPPD副部长 Bootstrap 3.0发布 更好地支持移动端和响应式开发 国内创业公司QingCloud的魄力:做一个世界级的IaaS服务 从毫秒到微妙,纯硬的闪存阵列IBM Flash System来了! 中科创达邹鹏程:黑客精神逐渐被人遗忘 有点让人感伤 通过讲故事的方式来设计优秀网站 “肮脏的”IT工作排行榜 Clank:带有SCSS的高效率移动应用原型框架 请问关于QT的站点有哪些?还有就是我如何给新装的卡装驱动呢? 超简单问题:如何换行? 有誰用過ppReport6.0?請問那里可以下載 怎样恢复WIN2000SERVER的目录服务? 又在深圳的Delphi程序员吗?-->请进 CString的对象该怎么释放啊? 有没有记录DBGrid的当前位置的,我说的不是用bookmark,因为我的DataSet是动态建立的,在刷新时好象Bookmark用不了。 情大家关注这个问题呀!!! 为什么我的程序对鼠标反应慢? 关于 mssql_close()函数的问题。 考过SCJP的朋友,请问考试卷可以转让吗?那上面有没有购买人的信息? 用什么软件可以把 .rm格式的多个文件进行合并? 请问如何得到早上0点到现在所过的秒数?我记得好象有个函数行的,可忘了 急急急。。。请问高手。window窗口的问题。。。 PB中继承关系能不能改? 请问有关用DELPHI开发WEB应用程序的经验、书和网站 String用法释疑 在sql server2000中如何制作大批量的数据并把它倒入数据库? 寻<<C语言常用算法>>第二版配套软盘 打印机的问题! 请问:一台w2k server的服务器安装了exchang sever w2k 如何实现用户自行更改PW。(次服务器在internet上)... 我的程序debug完以后,说strcore.cpp中有内存泄漏?咋回事? 用JAVA操作数据库居然出现这种现象 怎样将第三方控件打包? 请各位帮助,找增强型编辑控件!!! 窗体导航的问题??????????????? 客户端socket连接时间长了之后,客户端锁死.请大家帮帮忙 创建设备相关的函数CreateDIBitmap的为什么需要HDC参数 关于DataSet的讨论.......... 如何用系统参数 关于条形码 怎么加入member variable我是新手 我在我的程序上作了一个exit按钮,用来关闭程序,用哪个函数好啊? 怎么样实现EDIT的从右到左的输出 小弟我最近用C++编程遇到了一个棘手的问题,就是图像的旋转和对比度调整,恳请各位大虾救我! 请问:一台w2k server的服务器安装了exchang sever w2k 如何实现用户自行更改PW。(次服务器在internet上)... 加载位图的问题 DB2 里用SQL建立一个数据库怎么写? 关天条形码 救命啊,我的.net怎么安装不上去啊? IP地址怎么倒着显示? 如何制作象微软网页那样的下拉菜单? 如何给表增加外键? 想下面我声明的pbr该怎么释放? 请问我下载的扩展名为".001"的文件怎样浏览 我的机子上可能出现了病毒,怎么办 如何在apache 中用perl 关于Service Application 程序的调试 有关rs.absolutepage的问题,急! int 如何转换为TCHAR? 8分钟又一首 正方体的各个顶点的都在球体上,球体的直径为2√3,那么正方体的体积为多少?我急用正方体的各个顶点的都在球体上,球体的直径为2√3,那么正方体的体积为多少? 小明家有A,B两个长方体金鱼缸,底面积的比是5:4,A鱼缸的水深是10厘米,B鱼缸里水深8厘米.小明在两个鱼缸里加了同样的一桶水后,奇怪地发现,现在两个金鱼缸里的水深恰好一样,问现在两个鱼缸 一个正方体,它的体积是棱长为3厘米的正方体体积的8倍,这个正方体的棱长是多少? 一个正方体的顶点都在球面上,它的棱长为a,那么球体的体积为多少?我急用, 玻璃由天然材料构成吗?玻璃为什么不是由天然材料制成的吗?石英不是玻璃原料吗?陶瓷,灯管和毛玻璃呢? 为什么黑色内裤上有白色的东西不是遗精,不知道是不是…勃起时有点粘的东西的原因,洗过一次还见有,请问是正常的吗? 铁杯子好还是玻璃杯子好 玻璃的杯子好还是其他材料的好? 基本不等式等号条件不成立y=(x^+5)/根号(x^+4) 最小值 关于消防安全名言警句 初中阶段化学中有哪些需要掌握的沉淀物?比如CaCO3. holder不等式等号成立条件是不是和柯西不等式类似? 一个长方体水桶,高60cm,底面积是边长为30cm的正方形,桶内水高50cm,桶内有水( )mL. 张东以每分钟80米的速度从学校走到家,在家中取出自行车又以每分钟210米的速度起到图书馆,全部行程用去10分钟.张东骑车的路程比走路的路程多215米,两段路程各用了多少分钟? 卡尔松不等式等号成立条件 1、一只水桶底面直径是60cm,高70cm.如果每次在桶内盛50cm深的水,几桶可将一口容积为0.5立方米的水缸盛满? NaOH里有CaCO3如何去掉沉淀物要求是去掉CaCO3沉淀物来检验NaOH 请问这个绝对值三角不等式等号成立的条件是什么? 线性代数,特征值,这里第一步代入 |入E-A|我能看懂,可后面的(入-3)(入-2)(入-1)是怎么来的?另外,入1=1时,把它代入|入E-A|,可怎么就得到了[1 1 1]T?代入λ=1到λE-A=2 -4 20 -2 23 -1 -2第一列第二 高中化学所学的沉淀物都有哪些?..具体说说.我只知到有碳酸钙,硫酸钡. 卡尔松不等式 等号成立条件是什么 设三阶矩阵A 的三个特征值为1,1,2,且α1,α2,α3分别为对应的特征向量,则(A) α1-α2必为矩阵2E-A的特征向量;(B) α1-α3必为矩阵2E-A的特征向量;(C) α1,α2,α3必为矩阵2E-A的特征向量;(D) α1,α2必为 朗迪碳酸钙D3颗粒为什么有白色沉淀?那小孩子吃了不会有事吧?我崽才三个月。 线性相关,无关的几何意义 线性代数 特征值与特征向量问题知特征值与特征向量,求此矩阵A?如何求? 一个正方体,棱长为2cm,增加棱长后,是它原来体积的8倍,求增加了多少的棱长. 这在几何中表示什么意思 棱长2厘米的正方体是棱长1厘米的正方体的体积的8倍.我认为是对的耶, 正方体的每条棱都增加1cm,它的体积扩大为原来的8倍,求它的棱长 特征值不同,其所对的特征向量线性无关,有什么几何意义特征值可以理解为向量拉伸的倍数,特征向量理解为只改变长度,不改变向量方向的向量.而线性无关是不共线,那是否可以说拉伸倍数不 哪里要玻璃杯子 玻璃刷杯子怎么才能刷得干净?是玻璃杯子,打错了,玻璃杯子怎么才能刷的干净? 使不等式成立的值可以有多少个是无数个么? 我想问一下多元函数偏导数的空间几何意义?请举个例子跟我说说好么?我在高数书上没见到有介绍! 关于线性空间的基本概念……线性代数,第一个为什么错 是不等式X-1>0与不等式X-3<0同时成立的X值是( ) 解析函数积分的几何意义是什么啊~连解析函数的导数都有几何意义,可积分有何几何意义啊?请各位强人指教!注:复变函数的积分! 关于线性代数的几个问题1.什么叫实对称矩阵?2.何时需要正交化?3.同一个特征值的特征向量是否线性相关? 使不等式成立的{ }的值,叫做不等式的解,成立的X的{ } ,叫做不等式的解的集合,简称{ } 已知函数f(x)=sin5x+1,根据函数的性质和积分的几何意义,探求∫-π/2π/2f(x)dx具体回答 [线代]线性代数的几个问题1,a1T=(1,1,1) 非零向量a2,a3使a1,a2,a3两两正交,即x1+x2+x3=0得出基础解系 ξ1T=(1,0,-1) ξ2T=(0,1,-1)这个是怎么得出的?请详细点.2,求基础解系时,得出x1=-x3,x2=0 有基础解 X取什么值时,不等式X 啊姨把糖果给小军小玲小刚3人,小军比小玲多50/100,小刚和小军所得的比是17:10,小刚比小玲多31颗,他们个分到多少颗? [线代]几个线性代数的问题1,2次型标准化的时候,要求变换矩阵.这个变换矩阵C是什么?x=Cy,C=x/y?2,矩阵1/9 -8/9 -4/9-8/9 1/9 -4/9-4/9 -4/9 7/9为什么是正交阵啊?行和列都不是单位向量啊,一初等行变就第 母亲大声对那个女人说:“我挺高兴他爱看书的!”(改为第三人称转述) 小军.小宁.小刚分糖果,小军比小宁多分50/100,小刚和小军所分的比为17:10,小刚比小宁多分31,各分多少 几个线性代数问题请问刘老师这几道题怎么解? 可食用植物油含有高级脂肪酸甘油酯是人体的营养物质为什么错? 这个微波炉的长是60cm,宽是50cm,高是30cm.他打算买一台微波炉放到橱柜里.李老师看中一台微波炉,长宽高之比为3:2:1,长宽高之和为132cm,如果买这台微波炉合适吗?为什么? 有一对水果糖要分给小刚/小军/消化和小红.小刚和小军要求共分这对糖的5/8,消化和小红要求各分这对堂的1/5,他们的要求能满足吗?为什么? 一个正方体,它的体积是棱长为3厘米的正方体体积的8倍,这个正方体的棱长是多少? 把一个棱长是八厘米的正方体钢坯,锻造成一个长是16厘米,宽是8厘米的长方体,长 若正方形的体积扩大为原来的8倍,棱长扩大为原来的k倍,求 立方根下13.5k+平方根下60+k的平方 的值.立方根下13.5k+平方根下60+k的平方 的值哦谢谢`(*∩_∩*)′. 已知一个正方体的棱长是3厘米,再制作另一个正方体,使它的体积是原正方体的体积的8倍,则所做正方体的棱长是多少厘米? 把一个棱长是8厘米的正方体钢坯,锻造成一个长是16厘米,宽8是厘米的长方体,长方体的高是多少厘米? 同样的玻璃茶杯內...同样的玻璃茶杯內装水量不同,敲击时发出的音调不同.小华想亲手做实验,验证一下,他的做法是:取一只玻璃杯,装入半杯水后敲击;再稍加些水敲击.结果,他感觉两次听到 一个正方体,他的体积是棱长3厘米的正方体体积的8倍,这个正方体的棱长是多少厘米?我知道是6厘米,式子是什么,怎么也算不对呢? 一个正方体的顶点都在球面上,它的棱长是a cm,求球的体积.) 小强家新买了一个长方体金鱼缸,从里面量长是8厘米,宽和高都是6厘米,这个鱼缸的容积是多少?小强往里面倒了些水,水的高度约是浴缸高度的三分之二,浴缸内大约有多少升水 (1)一个正方体,他的体积是棱长3厘米的正方体体积的8倍,这个正方体的棱长是多少厘米?(2)又(1)计算得知,正方体的体积变为原来的8倍,它的棱长变为原来的( )倍.依次类推,正方体的体积变为
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘