當前位置:首頁 > 嵌入式 > 嵌入式軟件

Android平臺是基于Linxu內(nèi)核搭建的,Linux內(nèi)核的優(yōu)勢在于大內(nèi)存管理、進程管理、基于權(quán)限的安全模型、統(tǒng)一的驅(qū)動模型、共享庫支持、代碼開源等。

Android平臺在設(shè)計過程中,針對移動終端資源有限的特點,對Linux進行了一定程度的裁剪:砍掉了原生的窗口系統(tǒng)、去除了對GNU Libc的支持(引入了更高效、針對優(yōu)化過的Bionic)、裁剪掉了一些標準Linux工具的部分特性等。

另外Android針對移動終端的特點還對Linux內(nèi)核在鬧鐘(Alarm)、Low Memory Killer、Ashmem、內(nèi)核調(diào)試(Kernel Debugger)、進程間通信(Binder)、日志(Logger)、電源管理(Power Management)等方面做了大量的優(yōu)化。

其中Low Memory Killer相對于Linux標準OOM(Out Of Memory)機制更加靈活,它可以根據(jù)需要殺死進程來釋放需要的內(nèi)存。Low Memory Killer的實現(xiàn)主要位于auroramsmmsm drivers/staging/android/lowmemorykiller.c文件中。

Ashmem為進程間提供大塊共享內(nèi)存,同時為內(nèi)核提供回收和管理這個內(nèi)存的機制。 Ashmem的實現(xiàn)位于systemcorelibcutilsashmem-dev.c文件中。

下面重點介紹進程間通信和電源管理的內(nèi)容。

1.進程間通信

在多進程環(huán)境下,應用程序和后臺服務間通常會運行在不同的進程中,彼此有著獨立的地址空間,但是因為需要相互協(xié)作,彼此間又必須進行通信和數(shù)據(jù)共享,而傳統(tǒng)的進程間通信(IPC,Internet Process Connection)卻有著進程過載和安全漏洞等方面的風險。在Android中,引入了Binder的進程間通信機制,Binder的好處在于在驅(qū)動層面就對進程間通信提供了支持、通過SMD共享內(nèi)存機制提高了進程間通信的性能、采用線程池的方式來處理進程請求、針對系統(tǒng)中的對象引入了引用計數(shù)機制和跨進程的對象引用映射機制、在進程間的同步調(diào)用。圖1顯示了Android的進程間通信過程。


圖1 Android的進程間通信過程

為了進行進程間通信,Binder采用AIDL(Android Interface Definition Lanaguage)來描述進程間的接口。
在實際的實現(xiàn)中,Binder是作為一個特殊的字符型設(shè)備來存在的,其實現(xiàn)遵循Linux設(shè)備驅(qū)動模型,相關(guān)的主要代碼位于auroramsmmsmdriversstagingandroid binder.c文件中。

在Binder驅(qū)動中,binder_thread_write()函數(shù)通過binder_transaction()函數(shù)來發(fā)送請求或返回結(jié)果,而binder_thread_read()函數(shù)用于讀取結(jié)果,Binder主要通過binder_ioctl()函數(shù)與用戶空間的進程交換數(shù)據(jù)。

Binder的私有數(shù)據(jù)結(jié)構(gòu)binder_proc則被用來記錄當前進程、進程ID、內(nèi)存映射信息、Binder的統(tǒng)計信息和線程信息等。

如果收到請求,binder_transaction()函數(shù)會通過對象的句柄找到對象所在的進程,如果句柄為空就認為對象是 context_mgr,把請求發(fā)給context_mgr所在的進程。所有的Binder對象會全部放到一個RB樹中。最后context_mgr把請求放到目標進程的事件隊列中,等待目標進程讀取。數(shù)據(jù)的解析工作放在binder_parse()中實現(xiàn)。

下面是Binder驅(qū)動中最重要的binder_ioctl()函數(shù)的實現(xiàn):

代碼1-1 binder_ioctl()函數(shù)的實現(xiàn)

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
int ret;
struct binder_proc *proc=filp->private_data;
struct binder_thread *thread;
unsigned int size=_IOC_SIZE(cmd);
void __user *ubuf=(void __user *)arg;
/*printk(KERN_INFO "binder_ioctl: %d:%d %x %lxn", proc->pid, current->pid, cmd, arg);*/
ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret)
return ret;
mutex_lock(&binder_lock);
thread=binder_get_thread(proc); //獲取一個Binder線程
if (thread==NULL) {
ret=-ENOMEM;
goto err;
}
switch (cmd) {
case BINDER_WRITE_READ: {
struct binder_write_read bwr;
if (size!=sizeof(struct binder_write_read)) {
ret=-EINVAL;
goto err;
}
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) { //從用戶空間緩沖復制數(shù)據(jù)
ret=-EFAULT;
goto err;
}
if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
printk(KERN_INFO "binder: %d:%d write %ld at %08lx, read %ld at %08lxn",
proc->pid, thread->pid, bwr.write_size, bwr.write_buffer, bwr.read_size, bwr.read_buffer);
if (bwr.write_size > 0) {
ret=binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed); //傳遞數(shù)據(jù)
if (ret < 0) {
bwr.read_consumed=0;
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) //將數(shù)據(jù)寫回用戶空間
ret=-EFAULT;
goto err;
}
}
if (bwr.read_size>0) {
ret=binder_thread_read(proc, thread, (void __user *)bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); //讀取數(shù)據(jù)
if (!list_empty(&proc->todo))
wake_up_interruptible(&proc->wait); //喚醒掛起的線程
if (ret<0) {
if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
ret = -EFAULT;
goto err;
}
}
if (binder_debug_mask & BINDER_DEBUG_READ_WRITE)
printk(KERN_INFO "binder: %d:%d wrote %ld of %ld, read return %ld of %ldn",
proc->pid, thread->pid, bwr.write_consumed, bwr.write_size, bwr.read_consumed, bwr.read_size);
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret=-EFAULT;
goto err;
}
break;
}
case BINDER_SET_MAX_THREADS: 設(shè)置最大線程數(shù)
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret=-EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR: //設(shè)為上下文管理器
if (binder_context_mgr_node!=NULL) {
printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already setn");
ret=-EBUSY;
goto err;
}
if (binder_context_mgr_uid!=-1) {
if (binder_context_mgr_uid!=current->cred->euid) {
printk(KERN_ERR "binder:BINDER_SET_"
"CONTEXT_MGR bad uid %d!= %dn",
current->cred->euid,
binder_context_mgr_uid);
ret=-EPERM;
goto err;
}
} else
binder_context_mgr_uid=current->cred->euid;
binder_context_mgr_node=binder_new_node(proc, NULL, NULL);//新的RB樹節(jié)點
if (binder_context_mgr_node==NULL) {
ret=-ENOMEM;
goto err;
}
binder_context_mgr_node->local_weak_refs++;
binder_context_mgr_node->local_strong_refs++;
binder_context_mgr_node->has_strong_ref = 1;
binder_context_mgr_node->has_weak_ref = 1;
break;
case BINDER_THREAD_EXIT: //銷毀消除
if (binder_debug_mask & BINDER_DEBUG_THREADS)
printk(KERN_INFO "binder: %d:%d exitn",
proc->pid, thread->pid);
binder_free_thread(proc, thread); //釋放線程
thread=NULL;
break;
case BINDER_VERSION: //獲取Binder版本信息
if (size!=sizeof(struct binder_version)) {
ret=-EINVAL;
goto err;
}
if (put_user(BINDER_CURRENT_PROTOCOL_VERSION, &((struct binder_version *)ubuf)->protocol_version)) {
ret=-EINVAL;
goto err;
}
break;
default:
ret=-EINVAL;
goto err;
}
ret=0;
err:
if (thread)
thread->looper&=~BINDER_LOOPER_STATE_NEED_RETURN;
mutex_unlock(&binder_lock);
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret !=-ERESTARTSYS)
printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %dn", proc->pid, current->pid, cmd, arg, ret);
return ret;
}

2.電源管理

在目前的移動終端中,系統(tǒng)承載的功能越來越多,同時為了獲得更好的用戶體驗,GUI的設(shè)計越來越華麗,但這都不可避免地增加了系統(tǒng)的功耗,導致目前的智能移動終端普遍待機時間較短。在目前電池技術(shù)尚無法有大的突破情況下,電源管理顯得尤為重要,需要在滿足用戶需求的前提下,盡可能地減少功耗。電源管理策略是一個系統(tǒng)工程,應用程序、內(nèi)核框架、設(shè)備驅(qū)動、硬件設(shè)備都涉及其中。

對半導體器件而言,功耗分為靜態(tài)功耗、動態(tài)功耗。靜態(tài)功耗主要是指待機狀態(tài)下的泄漏電流,動態(tài)功耗才是電源管理要解決的主要問題。

Android的電源管理機制是建立在標準的Linux電源管理機制ACPI (Advanced Configuration and Power Interface)之上的,同時針對移動終端的特點采取了更積極的電源管理策略,支持休眠模式、動態(tài)電壓和調(diào)頻調(diào)節(jié)、電源管理質(zhì)量服務(PM QoS)、喚醒鎖等。

休眠模式、動態(tài)電壓和調(diào)頻調(diào)節(jié)等策略這里就不再多做介紹了。下面簡要介紹PM QoS和喚醒鎖的實現(xiàn)。

1)PM QoS

在初始化階段,Android定義的PM QoS參數(shù)有3個:cpu_dma_latency(CPU DMA延遲)、network_latency(網(wǎng)絡延遲)、 network_throughput(網(wǎng)絡吞吐量)。供驅(qū)動、子系統(tǒng)、用戶空間應用等注冊PM QoS請求。默認的參數(shù)級別有延遲、超時(Aurora中暫時不用)、吞吐量等。

在Aurora(auroramsmmsmkernelpm_qos_params.c)中, PM QoS有4個參數(shù):PM_QOS_CPU_DMA_LATENCY、PM_QOS_NETWORK_LATENCY、PM_QOS_NETWORK_ THROUGHPUT和PM_QOS_SYSTEM_BUS_FREQ等,分別針對CPU DMA延遲、網(wǎng)絡延遲、網(wǎng)絡吞吐量、系統(tǒng)總線頻率等性能指標。參數(shù)集的實現(xiàn)在pm_qos_power_init()函數(shù)中進行,使用pm_qos_init()函數(shù)在內(nèi)核里可以增加新的參數(shù)。在系統(tǒng)中,PM QoS主要用來管理CPU空閑管理、WiFi應用等。

在內(nèi)核空間,通過pm_qos_add_requirement()函數(shù)可以注冊PM QoS請求;通過pm_qos_update_requirement()函數(shù)可以更新已注冊的PM QoS請求;通過pm_qos_remove_requirement()函數(shù)可以刪除已注冊的PM QoS請求。圖2顯示了注冊PM QoS請求的過程。


圖2 注冊PM QoS請求的過程

在用戶空間,僅進程可以注冊PM QoS請求,為了注冊PM QoS請求,進程必須打開/dev/[cpu_dma_latency, network_latency, network_throughput]設(shè)備,默認的PM QoS請求名為“process_<PID>”。其中PID值在系統(tǒng)調(diào)用中獲得。

2)喚醒鎖

通過支持多種類型的喚醒鎖(wake locks),Android支持組件在電源管理方面的請求。需要注意的是,在使用喚醒鎖時需要相當小心。圖3顯示了創(chuàng)建喚醒鎖的過程。


圖3 創(chuàng)建喚醒鎖的過程

在實際的開發(fā)過程中,為了測試各應用電量消耗的情況,電量分析軟件powerTop不可或缺,它可以分析出每個具體的應用對電量的消耗情況。

Android電源管理的實現(xiàn)主要位于auroramsmmsmkernelpower目錄下,主要的文件包括earlysuspend.c、consoleearlysuspend.c、fbearlysuspend.c、wakelock.c、userwakelock.c等。

在Java層,Android封裝了一個PowerManager類來進行電源的管理。

3.驅(qū)動

驅(qū)動的實現(xiàn)與硬件平臺密切相關(guān),由于在Linux Kernel 2.6中引入了Linux設(shè)備驅(qū)動模型,Linux的驅(qū)動開發(fā)變得十分簡單。在auroramsmmsmdrivers目錄中,Qualcomm提供了非常多的硬件驅(qū)動,如BT、i2C、USB、FM、音頻、視頻等。下面簡要介紹部分驅(qū)動的情況。

●顯示驅(qū)動(Display Driver):常用基于Linux的幀緩沖( Buffer)驅(qū)動。
●照相機驅(qū)動(Camera):常用基于Linux的V4L2驅(qū)動。
●音頻驅(qū)動:常用基于ALSA(高級Linux音頻架構(gòu),Advanced Linux Sound Architecture)驅(qū)動。
●WIFI驅(qū)動:基于IEEE 802.11標準的驅(qū)動程序。Aurora支持的WIFI標準為802.11 bgn。對WAPI的支持則需要硬件平臺廠商的支持。
●Binder IPC驅(qū)動:Android的一個特殊的驅(qū)動程序,具有單獨的設(shè)備節(jié)點,實現(xiàn)進程間通信的功能。



本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉