`
Beyon_javaeye
  • 浏览: 66870 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

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协议等在这里并没有包含,也暂不作介绍。)

以下是详细分析,因为篇幅原因,会以连载形式发布出来(大概3篇),本文主要涉及基本架构和初始化的内容:

首先介绍一下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机制便能响应处理了。
到这里启动流程已经分析完毕。
分享到:
评论

相关推荐

    Android_GSM驱动模块(rild)详细分析(全)

    ### Android GSM驱动模块(rild)详细分析 #### 1. 基本架构及初始化 Android的RIL(Radio Interface Layer)驱动模块是Android系统中非常重要的组成部分之一,主要用于处理移动设备与网络之间的通信功能。它位于...

    Android的RIL驱动模块启动流程

    Android的RIL(Radio ...上述流程体现了Android RIL驱动模块启动的基本架构和初始化机制,为无线通信模块的启动和运行奠定了基础。理解这个流程有助于深入研究Android系统中无线电通信的工作原理和调试通信模块。

    Android底层架构研究

    通过分析AndroidApplication,可以了解应用程序如何初始化、如何响应系统事件以及如何与其他组件交互。 ### **21. Android应用框架之Activity** Activity是Android应用程序中最基本的组件之一,它代表了一个屏幕上...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...

    Android平台通信模块设计

    - **库层**:RILD(Radio Interface Layer Daemon)作为独立的后台守护进程存在,负责初始化调制解调器、将通讯指令转换为AT指令序列发送至调制解调器,同时处理来自调制解调器的反馈。 - **内核层**:包含与基带...

    android__display框架分析

    这里展示了如何创建和初始化一个 `copybit_context_t` 结构体实例,以便于后续进行显示相关的操作。 综上所述,Android 的 Display 框架涵盖了从硬件层面到软件层面的完整解决方案,旨在提供高性能和灵活的显示...

    android的核心分析

    - **Kernel**:初始化硬件驱动,加载必要的模块,并启动Zygote进程。 - **Zygote**:Android的初始进程,负责创建应用程序进程。 #### ZygoteService Zygote是Android系统中的一个关键进程,负责为每个应用程序...

    QCRIL_RIL_架构分析.pdf

    RIL抽象了不同的无线网络技术(如GSM、CDMA、LTE、5G等),使得Android系统能够独立于具体的无线通信技术进行开发。 **RIL架构** 1. **Android RIL简介** - Android RIL是Android操作系统的一部分,它作为上层...

    Android RIL详解

    ### Android RIL详解 ...通过对RIL各组件的理解及其初始化流程的深入分析,我们可以更好地理解Android中无线通信的基本原理和技术细节。这种深入的技术洞察对于优化移动设备上的网络通信性能至关重要。

    Android核心分析(pdf)

    - **系统启动流程:** 从硬件初始化、内核加载、Zygote进程启动到最终用户界面呈现的全过程。 - **关键组件的作用:** 如init.rc脚本、SystemServer进程等在启动过程中扮演的角色。 #### 四、图形用户界面(GUI) ...

    android gps源码 HAL部分 msm7627a

    驱动程序会处理与GPS芯片的通信,包括初始化、配置、接收卫星信号、解码定位信息等。这部分源码通常包含在内核模块或者作为单独的库文件,由HAL调用相应的函数来执行具体操作。 4. **位置信息处理**:在Android系统...

    MT6572_ov2655(MIPI)_Fullsize_Driver_20181110.rar

    MT6572是MediaTek推出的一款面向入门级智能手机和平板电脑的双核处理器,它采用了Cortex-A7架构,集成了2Gbps的Mali-400 MP图形处理单元,支持WCDMA和GSM网络制式,以及Wi-Fi、蓝牙等多种无线连接功能。这个名为"MT...

    嵌入式linux知识要点

    - **SPI接口的设备驱动开发**: 介绍如何编写SPI接口的驱动程序,包括初始化配置、数据传输等操作。 3. **IO操作与显示技术**:探讨GPIO(通用输入/输出端口)、OLED显示模块等设备的控制方法及其驱动开发技巧。 -...

    智能手机维修技术培训教材(MTK6573方案原理)

    - **启动模块**:包括中断向量表、复位处理程序等,负责初始化硬件环境并启动操作系统。 - **操作系统**:虽然在手机软件中占比不大,但提供关键的服务,如多任务管理和通信机制。 - **协议栈**:与基带处理芯片...

    cpmgrif通信lib查找

    `cpmgrif` 的存在意味着它可能是系统初始化的一部分,或者是服务启动时调用的组件,以确保通信功能的正确配置和操作。 通信库(lib)在软件开发中,通常是指包含特定功能的动态链接库(Dynamic Link Library)或...

    usim_drv.rar_MTK US_usim

    USIM驱动主要处理SIM卡的读写操作,包括初始化、数据传输、错误处理等功能。 2. **MTK芯片平台**:联发科的芯片平台广泛应用于各种移动设备,它们提供了丰富的硬件接口和软件支持,包括对双卡双待功能的支持。USIM...

    JAVA上百实例源码以及开源项目源代码

    Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个...

Global site tag (gtag.js) - Google Analytics