Linux + RIL.pdf
android 的 ril位于應(yīng)用程序框架與內(nèi)核之間,分成了兩個(gè)部分,一個(gè)部分是rild,它負(fù)責(zé)socket與應(yīng)用程序框架進(jìn)行通信。另外一個(gè)部分是Vendor RIL,這個(gè)部分負(fù)責(zé)向下通過(guò)兩種方式與radio進(jìn)行通信,它們是直接與radio通信的AT指令通道和用于傳輸包數(shù)據(jù)的通道,數(shù)據(jù)通道用于手機(jī)的上網(wǎng)功能。
啟動(dòng)過(guò)程:http://www.cnblogs.com/jimwind/archive/2012/12/26/2833467.html
對(duì)于RIL的java框架部分,也被分成了兩個(gè)部分,一個(gè)是RIL模塊,這個(gè)模塊主要用于與下層的rild進(jìn)行通信,另外一個(gè)是Phone模塊,這個(gè)模塊直接暴露電話功能接口給應(yīng)用開發(fā)用戶,供他們調(diào)用以進(jìn)行電話功能的實(shí)現(xiàn)。
[rild文件夾]
[LOCAL_MODULE:= rild_c]
RIL守護(hù)進(jìn)程,開機(jī)是被init守護(hù)進(jìn)程調(diào)用啟動(dòng),里面的main函數(shù)作為入口點(diǎn),負(fù)責(zé)完成RIL初始化工作。
在rild.c文件中,將完成ril的加載過(guò)程,它會(huì)執(zhí)行如下操作:
1、動(dòng)態(tài)加載Vendor RIL的.so文件;--- dlHandle = dlopen("/system/lib/libreference-ril_c.so",RTLD_NOW);
2、執(zhí)行RIL_startEventLoop()開啟消息隊(duì)列以進(jìn)行事件監(jiān)聽;RIL_startEventLoop();
3、通過(guò)執(zhí)行VendorRIL的rilInit()方法來(lái)進(jìn)行VendorRIL與libril的關(guān)系建立。dlsym(dlHandle, "RILCore_Init");? //reference-ril/reference-core.c RILCore_Init()
[libril文件夾]
[LOCAL_MODULE:= libril_c]
在編譯時(shí)libril被鏈入rild,它為rild提供了event處理功能,還提供了在rild與VendorRIL之間傳遞請(qǐng)求和響應(yīng)消息的能力。
libril提供的主要功能分布在兩個(gè)主要方法內(nèi),一個(gè)是RIL_startEventLoop()方法,另一個(gè)是RIL_register()方法。
RIL_startEventLoop()方法所提供的功能就是啟用eventLoop線程,開始執(zhí)行RIL消息隊(duì)列。
RIL_register()方法的主要功能就是啟動(dòng)名為rild的監(jiān)聽端口,等待java端通過(guò)socket進(jìn)行連接。
[reference-ril文件夾]
[LOCAL_MODULE:= libreference-ril_c]
Android自帶的VendorRIL的參考實(shí)現(xiàn)。被編譯成.so文件,由于本部分是廠商定制的重點(diǎn)所在,所以被設(shè)計(jì)為松散耦合,且可靈活配置的。在rild中通過(guò)opendl()方式加載。
libreference.so負(fù)責(zé)直接與radio通信,這包括將來(lái)自libril的指令轉(zhuǎn)換為AT指令,并且將AT指令寫入radio中。
reference-ril會(huì)接收調(diào)用者傳來(lái)的參數(shù),參數(shù)內(nèi)容為與radio的通信方式。如通過(guò)串口連接radio,那么參數(shù)為這個(gè)形式:-d /dev/ttySx
?
Android RIL 中的消息(event)隊(duì)列機(jī)制:
在Android RIL中,為了達(dá)到等待多路輸入并且不出現(xiàn)阻塞的目的,使用了IO多路復(fù)用機(jī)制。
如果使用阻塞I/O進(jìn)行網(wǎng)絡(luò)的讀取寫入,這意味著假如需要同時(shí)從兩個(gè)網(wǎng)絡(luò)文件描述符中讀內(nèi)容,那么如果讀取操作在等待網(wǎng)絡(luò)數(shù)據(jù)到來(lái),這將可能很稱時(shí)間阻塞在一個(gè)描述符上,另一個(gè)網(wǎng)絡(luò)文件描述符不管有沒(méi)有數(shù)據(jù)到來(lái)都無(wú)法被讀取。
I/O多路轉(zhuǎn)接技術(shù)在這里提供了另一種比較好的解決方案:
它會(huì)先構(gòu)造一張有關(guān)I/O描述符的列表,然后調(diào)用select函數(shù),當(dāng)IO描述符列表中的一個(gè)描述符準(zhǔn)備好進(jìn)行I/O時(shí),該函數(shù)返回,并告知可以讀或?qū)懩膫€(gè)描述符。
Android RIL中消息隊(duì)列的核心實(shí)現(xiàn)思想就是這種I/O多路轉(zhuǎn)接技術(shù)。
消息隊(duì)列機(jī)制的實(shí)現(xiàn)在ril_event.cpp中,其中被定義的ril_event結(jié)構(gòu)是消息的主體
每個(gè)ril_event結(jié)構(gòu),與一個(gè)fd句柄綁定(可以是文件,socket,管道等),并且?guī)б粋€(gè)func指針,這個(gè)func指針?biāo)傅暮瘮?shù)是個(gè)回調(diào)函數(shù),它指定了當(dāng)所綁定的fd準(zhǔn)備好進(jìn)行讀取時(shí)所要進(jìn)行的操作。
消息隊(duì)列的開始點(diǎn)為RIL_startEventLoop函數(shù),RIL_startEventLoop在ril.cpp中實(shí)現(xiàn),它的主要目的是通過(guò)pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL)建立一個(gè)dispatch線程,線程入口點(diǎn)在eventLoop。而在eventLoop中,會(huì)調(diào)ril_event.cpp中的ril_event_loop()函數(shù),建立起消息隊(duì)列機(jī)制
ril_event是一個(gè)帶有鏈表行為的struct,它最主要的成員一個(gè)是fd,一個(gè)是func
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的操作是通過(guò)ril_event_set()來(lái)完成的,并通過(guò)ril_event_add()加入到消息隊(duì)列中,add會(huì)把隊(duì)列里所有ril_event的fd,放入一個(gè)fd集合readFds。這樣ril_event_loop能通過(guò)一個(gè)多路復(fù)用I/O的機(jī)制(select)來(lái)等待這些fd。
在進(jìn)入ril_event_loop()之前,在eventLoop中已經(jīng)創(chuàng)建和掛入了s_wakeupfd_event,它是通過(guò)pipe的機(jī)制實(shí)現(xiàn)的,這個(gè)管道fd的回調(diào)函數(shù)并沒(méi)有實(shí)現(xiàn)什么功能,它的目的只是為了讓select方法能返回一次,這樣select()方法就能重新跟蹤新加入事件隊(duì)列的fd和timeout設(shè)置。
所以在添加新fd到eventLoop時(shí),往往不是直接調(diào)用ril_event_add,實(shí)際通常用rilEventAddWakeup來(lái)添加,這個(gè)方法除了會(huì)間接調(diào)用ril_event_add外,還會(huì)調(diào)用triggerEvLoop()函數(shù)來(lái)向s_fdWakeupWrite中寫入一個(gè)空字符,這樣select()函數(shù)會(huì)返回并重新執(zhí)行,新加入的文件描述符便得以被select()加載并跟蹤。
如果在ril_event隊(duì)列中任何一個(gè)fd已經(jīng)準(zhǔn)備好,則進(jìn)入分析流程:
processTimeouts(),processReadReadies(&rfds, n),firePending()
其中firePending()方法執(zhí)行這個(gè)event的func,也就是回調(diào)函數(shù)。
在Android RIL初始化完成后,將有幾個(gè)event被掛入到eventLoop中:
1.s_listen_event: 名為rild的socket,主要request & response通道。
2.s_debug_event:名為rild-debug的socket,調(diào)試用request & response通道。
3.s_wakeupfd_event: 無(wú)名管道,用于隊(duì)列主動(dòng)喚醒
這其中最為重要的event就是s_listen_event,它作為request與response的通道實(shí)現(xiàn)
在ril_event.cpp中還持有一個(gè)watch_table數(shù)組,一個(gè)timer_list鏈表和一個(gè)pending_list鏈表。
watch_table數(shù)組的目的目的很單純,存放當(dāng)前被eventLoop等待的ril_event(非timer event),供eventLoop喚醒時(shí)使用。
timer_list是存放timer event的鏈表,在eventLoop喚醒時(shí)要對(duì)這些timer event單獨(dú)進(jìn)行處理
pending_list:待處理(對(duì)其回調(diào)函數(shù)進(jìn)行調(diào)用)的所有ril_event的鏈表
?
Android RIL編譯結(jié)構(gòu)
rild: 被編譯成可執(zhí)行文件,rild以守護(hù)進(jìn)程的形式執(zhí)行
libril:將被編譯為共享庫(kù),并被鏈入rild
d
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/jimwind/p/2832976.html
總結(jié)
以上是生活随笔為你收集整理的Linux + RIL.pdf的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 跨平台移动开发_PhoneGap 使用A
- 下一篇: display与visibility区别