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

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机制便能响应处理了。到这里启动流程已经分析完毕。

 

 

辉煌不再 Encanto超级计算机可能被拆分“出售” 知己知彼 企业应用移足云端必须清楚的10大方面 NVIDIA推Android掌机:七年孕育可否成就野心? 人民日报:2013关于新媒体的8个猜想 互联网大时代成就创新小企业 移动互联网创新论坛报道 Mobile Detect:判断移动设备类型的开源PHP类 我是如何Hack Facebook Employees Secure Files Transfer服务的 投资可再生能源:Google 2亿美元投资风力农场 构筑商业生态系统 阿里巴巴集团全面变革组织架构和管理体系 美国众多银行网站遭DDoS攻击 疑似伊朗所为 构建高可扩Web架构和分布式系统实战 CES2013 AMD发布移动处理器路线图和环绕计算概念 对话Linus Torvalds:大多黑客甚至连指针都未理解 PaaS玩家们,怎么演好自己的角色? Apple高管表态:低端机绝不是iPhone的未来 Web开发人员应该知道的IE 10兼容性问题 一周消息树:CES2013揭幕 科技巨头纷纷发力 2012专利排行榜 IBM位列第一、Google增长最快! 微软赞黑客并称Windows RT越狱非安全漏洞所致 周报第46期:GitHub历史上最糟糕宕机事故回放及反省 著名计算机黑客Aaron Swartz自杀身亡 移动周报:移动互联网行业技术趋势前瞻 旁门左道:让移动游戏下载量暴涨的邪门功夫 可植入身体:“可穿戴计算”时代来临 Web服务器份额:Apache仍居首,Nginx将超IIS 防税务欺诈:挪威财政部将开源收银机代码 响应式设计实战:3人+1.5个月 IE10优化版cnBeta诞生记 不听乔布斯劝告:“不专心”的Google照样干得好 躲过一劫!苹果不锁杂志类APP介绍截图 Oracle发布软件更新修复Java漏洞 设计师将吞噬工程师吗? 向CList模板类的对象追加节点时出现异常,谁惹的祸??? 为什么我的VB运行时会清空剪贴板? 大侠求救!我的考试题!20分的!急急急急急急急急! 目前asp中使用的主要加密算法有哪些? 怎样设置tab! 关于vb的问题,谢谢大家了。 计算机操作者的食谱(想想大家每天都对着电脑,看看这个食谱吧,或许有好处,人还是要学会爱护自己) 如何将png文件格式转换成bmp文件格式,小弟急需这方面的资料,尤其是关于压缩方面的 关于在存储过程中调用链接服务器权限的问题 用vb打包程序打包后安装出错,运行不了? 我要独自去广州发展,请大家看看我的情况,给我一些帮助,如何在广州找工作? 求助!请问谁有源代码?(画一个线段、图形区域填充、图形区域截剪) 物价飞涨,福建省软考提价!!! 在数据表里,我保存了图片存放的路径,现在我想让他显示出来,怎么做啊?有几个方法啊,请指点 阿沐进来看看,你要的东西 VC++ ADO用SELECT FOR UPDATE锁定Oracle数据库的记录,为什么无效? 关于CGI连接关系数据库? 关于动态链接库一问,释放时的异常 阿沐进来看看2 怎样才能不添加OCX和DLL做出反色效果? 好奇怪的问题,大家帮忙来分析一下 阿沐进来看看3 !!再次求解,关于ADO!! 高分求解!高手请进!疑难杂诊? 在LINUX下,如何修改屏幕分辨率 请教如何将图片插入到sqlserver 7/2000里? 急急急!UDP的问题 有关ISA SERVER 昨晚做了个大梦,哈哈!! 疑问 JINI究竟是什么东东呀?去SUN看了半天也没能明白,谁能解释一下? vb.net的一个问题!!是关于在form1上写字的东西! 关于如何输入的问题*******vb高手请进***************(在线等候,我只有这么多分了) 简单的问题,textbox取不到值。 关于DIALOG对话框的继承问题 。 Response->SetCookieField()可以将用户登陆信息保存在cookie内,可是... 为什么我用AddString()无法为Combo Box添加上新项? 请问程序员中有多少是喜欢打《帝国时代》的,我是一个,请报名,谈谈感受。 文件读写:前一部分是文肩头,含几个概括性数据;后一部分是数量不定的大量整形数据。该怎么办?我想用块读写的方式,不知可否?解决了保 请版本进来帮忙解决一下!!! 我的机子怎么拉? find a bbs(asp and xml) 学好c 请版主进来帮忙解释一下!!! asp.net中怎样才能把图片存贮在Sql server 的Images字段中? 请问在Delphi中如何防止(或提示)用户输入在文本框中的不能为字母?????? 急:exe调用DLL里面方法,运行exe,从dll方法里面出错,弹出“内存不能read”对话框 谁能给我一段代码,将查询结果用EXCEL导出! 请版主进来帮忙解决一下!!!!! find a bbs(xml and asp) 请教高手,关于VB的报表问题. 吃菠菜要注意什么?做菠菜前 先去草酸 H2与S化合热化学方程式S是什么态 人类在各种活动中,常常通过对地表的改造,影响地球上水循环的过程.说出一两个你所知道的改造工程 煮菠菜汤时怎样去除菠菜的草酸 热化学方程式中的△S是什么意思? 西欧国家的著名旅游景点一些冇名旳国家旳主要旳旅游景点、.比如什么巴黎圣母院、埃菲尔铁塔、 博兰登堡门……不要太多、一个国家提供一两个、要有标志性的、. 把我网走吧 一个渔夫去打鱼,一条鱼游过来对渔夫说"快把我网走吧"!看了怎样写? 刚刚量体温 不小心把水银温度计打碎了 大部分的 水银珠子 大部分已清理 已经通风了 2个小时 不知道是否还可以住人 还有危险不? 如何去除蔬菜中的草酸 根据碘与氢气反应的热化学方程式(i) I2(g)+H2(g) \2HI(g)+9.48kJ (ii) I2(S)+H2(g)2HI(g)-26.48kJ下列判断正确的是(  )A.254gI2(g)中通入2gH2(g),反应放热9.48kJB.1mol固态碘与 量体温时水银温度计头里面的水银会进去,充满温度计后还剩多少? 1、填关联词:桑那觉得( )看见西蒙孩子饿死,( )自己多受些苦,把他们抱回家来.形容小夜曲优美的四1、填关联词:桑那觉得( )看见西蒙孩子饿死,( )自己多受些苦,把他们抱回家来.2 【标题】怎样处理菠菜中的草酸 10.地球上水的主体是( )A.湖泊水 B.冰川水 C.地下水 D.海洋水11.地球上淡水的主体是( )A.湖泊水 B.冰川水 C.地下水 D.河流水12.形成洋流的主要动力是( )A.地转偏向力 B.盛行风 C.陆地形状 家用增压泵给水电工做了压力测试,现在泵体漏水,还能维修吗? 往锌粉和碘粉的混合物中加水,为什么反应速率会加快?它们的反应是怎样的?若大的世界,求真相! 地球上水的现状水的危险程度 一个玻璃杯装满水,用薄硬纸板盖住杯口,把杯子倒置,杯中水不会流出来.它的结论是什么? 小学四年级语文园地七作文(成长中的一件事)怎写不要写别人写过八百遍的,选材要新颖.能得一类文的.分数25以上就行,500字. 猪骨头汤应该怎么熬才好喝?如题老婆怀孕了,有点缺钙,所以想熬汤给老婆喝补补. 油炸方便面是怎么炸出来的?是不是真的放到油锅里炸? 四年级下语文园地七作文! 带引号的句子 仿写 各写一句话 如何对付蔬菜中的草酸 炖猪骨头汤都放什么调料味道比较好?怎么操作?20 分呦. 四年级下册人教版语文园地七范文有急用!1 那些蔬菜属于草酸类蔬菜? 如何炖猪骨头汤更好喝 .雄心壮志 坚定不移 2.坚忍不拔 自强不息 3.聚沙成塔 集腋成裘 4.持之以恒 全力以赴 5.知难而进 无坚不摧 8.知难而退 碌碌无为 7.一暴十寒 寸进尺退 9.有始无终 半途而废 铝镁合金粉 铝镁合金粉 混合请问有没有可以混合Al粉、Si粉、Al-Mg合金粉的混料机,这些东西搅拌时容易引起爆炸.混料机的搅拌翅和内衬应该是非金属材料的比较好. 怎么炖牛骨头汤 为什么地球上水最多? 桑娜和渔夫收养了西蒙的孩子.改为反问句 咏柳 把对柳树的赞美引向对____和_____的赞美我知道是对春天的赞美,但是是什么和春天的赞美.有哪位知道的. 四年级上册语文园地七作文怎样写 地球上水的面积占了多少 《咏柳》通过赞美柳树表达了诗人_______________________ ( )天气怎样,明天的活动照常进行 填上关联词 什么食物草酸含量高 温度计里面的水银进了宝宝的眼睛有没有事阿 ( )天气恶劣,同学们( )是按时上学.请填上关联词! 高锰酸钾是一种盐,可溶于水,溶液显紫红色.课本上有一个“估算高锰酸根离子的大小”的实验,某同学按课 温度计水银进入了眼睛里温度计不小心打破,而且弄到宝宝眼睛里去了,去医院医生说想办法弄哭宝宝,让他自己的眼泪把水银流出来,半天都没有流出来,后来还是护士用棉签弄出来了,眼睛里是 平常人用的水银温度计能给狗狗用么? 请你从生物圈水循环的角度,谈谈热带雨林的破坏对全球气候的影响. 屋檐每隔一滴时间地下一滴水,当第5滴水正欲滴下时,第1滴水正好落地,这时第4滴和第5滴相隔1m,屋檐高? 水银温度计打碎了怎么办,对宠物狗有危害吗 全球水循环过程对天气和气候变化的作用? 55g硝酸铅和碘化钾反应生成34g硝酸钾和多少g碘化铅? 一长一短两根蜡烛点燃,用一个玻璃杯同时罩住.问哪根蜡烛先熄灭,为什么 青菜含草酸吗?如果含草酸不就不能豆腐一起煮了吗?青菜豆腐多好吃啊?怎么吃西要这么讲究.做人真没意思. 碘化溴和碘化钾反应最好标出电子转移和数目 猪骨头汤里放什么好?我已烧了一锅猪骨汤,里面还放了几片家乡咸肉.接下来烧什么好? 什么蔬菜含草酸多 骨头汤要什么做呢 骨头汤的营养价值有哪些呢! 写迈克尔杰克逊的作文(五年级下册语文园地七的习作)不少于350字 把锌粉放到高锰酸钾溶液中,高锰酸钾溶液的颜色变化 煮沸菠菜为什么可以除草酸吗? 热化学方程式怎么自发反应 △H与△S之间有什么关系 还有△S怎么判断 列举影响地球水循环过程的人类行为
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘