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