必威体育Betway必威体育官网
当前位置:首页 > IT技术

RIL 机制---开篇

时间:2019-10-05 08:43:20来源:IT技术作者:seo实验室小编阅读:54次「手机版」
 

ril

1, 概念

本文基于Android 6.0。RIL(Radio Interface Layer,无线通信接口层)主要相关的结构如下,

为了便于论述,将RIL分为三个部分,

1, Framework层中的相关java程序。运行与phone进程,简称RILJ。

封装phone进程的消息,然后发送给RIL;

读取RIL中的消息然后解析并进行处理。

2,hardware中的ril部分,运行于rild守护进程,简称RIL。

读取RILJ中的消息,发送到reference-ril库。

读取reference-ril库中的消息,发送到RILJ。

3, hardware中的reference-ril库, 运行于rild守护进程,简称reference-ril,由各大厂商自己定制,因为厂商自己的Modem也不一样。

读取RIL中的消息,发送到Modem。

读取Modem中的消息,发送到RIL。

主要包括代码如下,

frameworks\opt\telephony\src\java\com\android\internal\telephony

RIL.java

hardware\ril\rild 目录下的所有文件

hardware\ril\libril目录下的所有文件

hardware\ril\reference-ril目录下的所有文件

RILJ属于系统Phone进程的一部分,随Phone进程启动而加载;而RILD守护进程是通过Android的Init进程进行加载的。接下来首先用2个章节来论述phone进程和rild守护进程有关ril部分。

2, RILJ

所有上层对RIL层的请求,最终都需要在RILJ中转换为RIL层可识别的命令,然后通过socket通道传输下去;同时,RIL层数据的上报,也要通过RILJ进行解码,还原为上层容易识别的格式。因此,RILJ是framework与RIL层交互的通道。

RILJ有两个主要特点:

  1、开启了两个独立线程分别负责发送数据和接收数据

  2、数据的发送和接收是异步的。

2.1 RIL构造方法

RIL.java的构造方法主要代码如下,

public RIL(context context, int preferredNetworkType,
            int cdmaSubscription, integer instanceId) {
      super(context);
       •••
//发送子线程
      mSenderThread = new handlerthread("RILSender" + mInstanceId); 
      mSenderThread.start();
Looper looper = mSenderThread.getLooper();
//mSender是发送子线程的Handler,通过他可以发送数据
      mSender = new RILSender(looper);
       •••
        //接收子线程
      mReceiver = new RILReceiver();
      mReceiverThread = new Thread(mReceiver, "RILReceiver" + mInstanceId);
      mReceiverThread.start();
      •••

可以看到,在构造函数中开启了两个独立的子线程:

1,mSenderThread用于给RILC发送数据;

2,mReceiverThread用于接收RILC上报的数据。

另外,RILJ数据的发送和接收是异步的, 既然是异步的消息机制,也就是说发送者在发送完数据后就可以返回,

那么当得到回应后,就要有一种方法去找到当初的请求者,并把结果返回给他。那么这个方法是什么呢?是RILrequest类。

2.2,RILRequest

RILRequest是RIL.java中的外部类,定义如下,

class RILRequest {

主要变量如下,

//这个变量就是一个令牌,每生成(obtain)一个新的请求,都将产生一个递增的、唯一的mSerial,当从RILC得到
//一个数据后,将通过mSerial找到当初发送这个请求的对象。这也就是异步通信最关键的联系点。
//相当于消息的标志,系列号。
int mSerial;
int mRequest; //请求码,需要和RILC层中的ril_commands.h文件内定义的请求码一致。
message mResult;//消息
Parcel mParcel;//消息中的数据
RILRequest mNext;// 链表结构,代表下一个RILRequest(请求)

Release方法如下,

void release() {
        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {// MAX_POOL_SIZE值为4
                mNext = sPool;
                sPool = this;
                sPoolSize++;
                mResult = null;
            }
        }
    }

把当前的RILRequest对象保存在sPool中, 等下次需要申请RILRequest时就去sPool中取出用即可,

而无需重复的申请(new)RILRequest。同时sPool的最大个数为4(MAX_POOL_SIZE)。

obtain方法如下,

static RILRequest obtain(int request, Message result) {
        RILRequest rr = null;

        synchronized(sPoolSync) {
            if (sPool != null) {
                rr = sPool;
                sPool = rr.mNext;
                rr.mNext = null;
                sPoolSize--;
            }
        }

        if (rr == null) {
            rr = new RILRequest();//new对象
        }

        rr.mSerial = sNextSerial.getAndIncrement();//获取系列号, 得到一个绝对递增的整数

        rr.mRequest = request;//请求码
        rr.mResult = result;//消息
        rr.mParcel = Parcel.obtain();

        if (result != null && result.getTarget() == null) {
            throw new NullPointerException("Message target must not be null");
        }

        // first elements in any RIL Parcel
        rr.mParcel.writeInt(request);//封装请求码
        rr.mParcel.writeInt(rr.mSerial);//封装系列号

        return rr;
    }

小结:

1,RIL中首先会对应phone进程的消息进行封装。

2,开启了2个子线程,一个往ril发送消息,一个读取ril的消息。

相关阅读

大话Verilog-Verilog入门(二)

文章转至我的公众号:https://mp.weixin.qq.com/s/8RDze85pKlU8V75TriNlLQ 笔者Elin Verilog与原图之间的联系 很多人学习Verilog

nginx 503 Service Temporarily Unavailable 方法

503 Service Temporarily Unavailable 最近网站刷新后经常出现503 Service Temporarily Unavailable错误,有时有可以,联想到最近在

移位寄存器专题(verilog HDL设计)

目录 移位寄存器简介 分类 4位右移位寄存器工作原理 1、 16位右移位寄存器 2、 16位左移寄存器 3、 串行输入并行输出寄存器 4

Verilog延时:specify的用法(转)

检查时序的方式之一是时序仿真,在仿真过程中计算与该模块相关的延迟值;之二是静态时序验证。(1)延迟类型分布延迟:在每个独立的元件基

RIL

对于熟悉Android O之前RIL的开发者来说,Android O上RIL最大的改变就是将socket通信换成了binder通信,只不过是/dev/hwbinder,而不是/

分享到:

栏目导航

推荐阅读

热门阅读