国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Android GSM驅(qū)動(dòng)模塊詳細(xì)分析

Android GSM驅(qū)動(dòng)模塊詳細(xì)分析

作者:IT168 熊貓哥哥  2009-03-24  

  Android的RIL驅(qū)動(dòng)模塊,在hardware/ril目錄下,一共分rild,libril.so以及l(fā)ibrefrence_ril.so三個(gè)部分,另有一radiooptions可供自動(dòng)或手動(dòng)調(diào)試使用。都依賴于include目錄中ril.h頭文件。目前cupcake分支上帶的是gsm的支持,另有一cdma分支,這里分析的是gsm驅(qū)動(dòng)。

  GSM模塊,由于Modem的歷史原因,AP一直是通過基于串口的AT命令與BB交互。包括到了目前的一些edge或3g模塊,或像omap這類ap,bp集成的芯片,已經(jīng)使用了USB或其他等高速總線通信,但大多仍然使用模擬串口機(jī)制來使用AT命令。這里的RIL(Radio InterfaceLayer)層,主要也就是基于AT命令的操作,如發(fā)命令,response解析等。(gprs等傳輸會(huì)用到的MUX協(xié)議等在這里并沒有包含,也暫不作介紹。)

  以下是詳細(xì)分析,本文主要涉及基本架構(gòu)和初始化的內(nèi)容:

  首先介紹一下rild與libril.so以及l(fā)ibrefrence_ril.so的關(guān)系:

1. rild:
僅實(shí)現(xiàn)一main函數(shù)作為整個(gè)ril層的入口點(diǎn),負(fù)責(zé)完成初始化。
2.libril.so:
與rild結(jié)合相當(dāng)緊密,是其共享庫,編譯時(shí)就已經(jīng)建立了這一關(guān)系。組成部分為ril.cpp,ril_event.cpp。libril.so駐留在rild這一守護(hù)進(jìn)程中,主要完成同上層通信的工作,接受ril請求并傳遞給librefrence_ril.so, 同時(shí)把來自librefrence_ril.so的反饋回傳給調(diào)用進(jìn)程。
3.librefrence_ril.so:
rild通過手動(dòng)的dlopen方式加載,結(jié)合稍微松散,這也是因?yàn)閘ibrefrence.so主要負(fù)責(zé)跟Modem硬件通信的緣故。這樣做更方便替換或修改以適配更多的Modem種類。它轉(zhuǎn)換來自libril.so的請求為AT命令,同時(shí)監(jiān)控Modem的反饋信息,并傳遞回libril.so。在初始化時(shí), rild通過符號RIL_Init獲取一組函數(shù)指針并以此與之建立聯(lián)系。
4.radiooptions:
radiooptiongs通過獲取啟動(dòng)參數(shù), 利用socket與rild通信,可供調(diào)試時(shí)配置Modem參數(shù)。

接下來分析初始化流程,主入口是rild.c中的main函數(shù),主要完成三個(gè)任務(wù):
1. 開啟libril.so中的event機(jī)制,在RIL_startEventLoop中,是最核心的由多路I/O驅(qū)動(dòng)的消息循環(huán)。
2.初始化librefrence_ril.so,也就是跟硬件或模擬硬件modem通信的部分(后面統(tǒng)一稱硬件), 通過RIL_Init函數(shù)完成。
3.通過RIL_Init獲取一組函數(shù)指針RIL_RadioFunctions,并通過RIL_register完成注冊,并打開接受上層命令的socket通道。

  首先看第一個(gè)任務(wù),也就是RIL_startEventLoop函數(shù)。RIL_startEventLoop在ril.cpp中實(shí)現(xiàn),它的主要目的是通過pthread_create(&s_tid_dispatch, &attr, eventLoop,NULL)建立一個(gè)dispatch線程,入口點(diǎn)在eventLoop.而eventLoop中,會(huì)調(diào)ril_event.cpp中的ril_event_loop()函數(shù),建立起消息(event)隊(duì)列機(jī)制。

我們來仔細(xì)看看這一消息隊(duì)列的機(jī)制,這些代碼都在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);
voidril_event_add(struct ril_event * ev);
voidril_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;
};

  每個(gè)ril_event結(jié)構(gòu),與一個(gè)fd句柄綁定(可以是文件,socket,管道等),并且?guī)б粋€(gè)func指針去執(zhí)行指定的操作。

  具體流程是:ril_event_init完成后,通過ril_event_set來配置一新ril_event,并通過ril_event_add加入隊(duì)列之中(實(shí)際通常用rilEventAddWakeup來添加),add會(huì)把隊(duì)列里所有ril_event的fd,放入一個(gè)fd集合readFds中。這樣ril_event_loop能通過一個(gè)多路復(fù)用I/O的機(jī)制(select)來等待這些fd,如果任何一個(gè)fd有數(shù)據(jù)寫入,則進(jìn)入分析流程processTimeouts(),processReadReadies(&rfds,n),firePending()。 后文會(huì)詳細(xì)分析這些流程。

  另外我們可以看到, 在進(jìn)入ril_event_loop之前,已經(jīng)掛入了一s_wakeupfd_event, 通過pipe的機(jī)制實(shí)現(xiàn)的,這個(gè)event的目的是可以在一些情況下,能內(nèi)部喚醒ril_event_loop的多路復(fù)用阻塞,比如一些帶timeout的命令timeout到期的時(shí)候。

  至此第一個(gè)任務(wù)分析完畢,這樣便建立起了基于event隊(duì)列的消息循環(huán),稍后便可以接受上層發(fā)來的的請求了(上層請求的event對象建立,在第三個(gè)任務(wù)中)。

  接下來看第二個(gè)任務(wù),這個(gè)任務(wù)的入口是RIL_Init,RIL_Init首先通過參數(shù)獲取硬件接口的設(shè)備文件或模擬硬件接口的socket. 接下來便新開一個(gè)線程繼續(xù)初始化, 即mainLoop。

mainLoop的主要任務(wù)是建立起與硬件的通信,然后通過read方法阻塞等待硬件的主動(dòng)上報(bào)或響應(yīng)。在注冊一些基礎(chǔ)回調(diào)(timeout,readerclose)后,mainLoop首先打開硬件設(shè)備文件,建立起與硬件的通信,s_device_path和s_port是前面獲取的設(shè)備路徑參數(shù),將其打開(兩者可以同時(shí)打開并擁有各自的reader,這里也很容易添加雙卡雙待等支持)。

  接下來通過at_open函數(shù)建立起這一設(shè)備文件上的reader等待循環(huán),這也是通過新建一個(gè)線程完成, ret =pthread_create(&s_tid_reader, &attr, readerLoop,&attr),入口點(diǎn)readerLoop。

  AT命令都是以\r\n或\n\r的換行符來作為分隔符的,所以readerLoop是line驅(qū)動(dòng)的,除非出錯(cuò),超時(shí)等,否則會(huì)讀到一行完整的響應(yīng)或主動(dòng)上報(bào),才會(huì)返回。這個(gè)循環(huán)跑起來以后,我們基本的AT響應(yīng)機(jī)制已經(jīng)建立了起來。它的具體分析,包括at_open中掛接的ATUnsolHandler, 我們都放到后面分析response的連載文章里去。

有了響應(yīng)的機(jī)制(當(dāng)然,能與硬件通信也已經(jīng)可以發(fā)請求了),通過RIL_requestTimedCallback(initializeCallback, NULL,&TIMEVAL_0),跑到initializeCallback中,執(zhí)行一些Modem的初始化命令,主要都是AT命令的方式。發(fā)AT命令的流程,我們放到后面分析request的連載文章里。這里可以看到,主要是一些參數(shù)配置,以及網(wǎng)絡(luò)狀態(tài)的檢查等。至此第二個(gè)任務(wù)分析完畢,硬件已經(jīng)可以訪問了。

  最后是第三個(gè)任務(wù)。第三個(gè)任務(wù)是由RIL_Init的返回值開始的,這是一個(gè)RIL_RadioFunctions結(jié)構(gòu)的指針。

typedef struct {
  
int version;        /* set to RIL_VERSION */
   RIL_RequestFunc onRequest;
   RIL_RadioStateRequestonStateRequest;
   RIL_Supports supports;
   RIL_Cancel onCancel;
  RIL_GetVersion getVersion;
} RIL_RadioFunctions;


其中最重要的是onRequest域,上層來的請求都由這個(gè)函數(shù)進(jìn)行映射后轉(zhuǎn)換成對應(yīng)的AT命令發(fā)給硬件。
rild通過RIL_register注冊這一指針。

  RIL_register中要完成的另外一個(gè)任務(wù),就是打開前面提到的跟上層通信的socket接口(s_fdListen是主接口,s_fdDebug供調(diào)試時(shí)使用)。

  然后將這兩個(gè)socket接口使用任務(wù)一中實(shí)現(xiàn)的機(jī)制進(jìn)行注冊(僅列出s_fdListen)

ril_event_set (&s_listen_event,s_fdListen, false,
               listenCallback, NULL);
rilEventAddWakeup(
&s_listen_event);

 

這樣將兩個(gè)socket加到任務(wù)一中建立起來多路復(fù)用I/O的檢查句柄集合中,一旦有上層來的(調(diào)試)請求,event機(jī)制便能響應(yīng)處理了。到這里啟動(dòng)流程已經(jīng)分析完畢。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android RIL結(jié)構(gòu)分析與移植
淺析Android的RILD服務(wù)進(jìn)程的消息循環(huán)
Android的電話功能介紹
Android電話系統(tǒng)rild
Radio Layer Interface(來自:http://www.netmite.com/android/mydroid/development/pdk/docs/telephony.html)
android phone 模塊分析
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服