www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

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

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

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

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

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

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

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

1.進程間通信

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


圖1 Android的進程間通信過程

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

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

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

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

下面是Binder驅動中最重要的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ù)
if (copy_from_user(&proc->max_threads, ubuf, sizeof(proc->max_threads))) {
ret=-EINVAL;
goto err;
}
break;
case BINDER_SET_CONTEXT_MGR: //設為上下文管理器
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的設計越來越華麗,但這都不可避免地增加了系統(tǒng)的功耗,導致目前的智能移動終端普遍待機時間較短。在目前電池技術尚無法有大的突破情況下,電源管理顯得尤為重要,需要在滿足用戶需求的前提下,盡可能地減少功耗。電源管理策略是一個系統(tǒng)工程,應用程序、內核框架、設備驅動、硬件設備都涉及其中。

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

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

休眠模式、動態(tài)電壓和調頻調節(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)絡吞吐量)。供驅動、子系統(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ù)在內核里可以增加新的參數(shù)。在系統(tǒng)中,PM QoS主要用來管理CPU空閑管理、WiFi應用等。

在內核空間,通過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]設備,默認的PM QoS請求名為“process_<PID>”。其中PID值在系統(tǒng)調用中獲得。

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.驅動

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

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



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

LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅動性能的關鍵。

關鍵字: 工業(yè)電機 驅動電源

LED 驅動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅動電源 照明系統(tǒng) 散熱

根據(jù)LED驅動電源的公式,電感內電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質量和效率直接關系到城市的公共安全、居民生活質量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅動電源

關鍵字: LED 驅動電源 開關電源

LED驅動電源是把電源供應轉換為特定的電壓電流以驅動LED發(fā)光的電壓轉換器,通常情況下:LED驅動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅動電源
關閉
關閉