版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
5.1.1LiteOS-A內(nèi)核簡(jiǎn)介通過(guò)本節(jié)學(xué)習(xí),您可以:了解LiteOS-A內(nèi)核簡(jiǎn)介L(zhǎng)iteOS-A內(nèi)核簡(jiǎn)介L(zhǎng)iteOS-A適配的系統(tǒng)及設(shè)備類型:小型系統(tǒng)(smallsystem)面向應(yīng)用處理器例如ArmCortex-A的設(shè)備,支持的設(shè)備最小內(nèi)存為1MB,可以提供更高的安全能力、標(biāo)準(zhǔn)的圖形框架、視頻編解碼的多媒體能力??芍蔚漠a(chǎn)品如智能家居領(lǐng)域的IPCamera、電子貓眼、路由器以及智慧出行域的行車記錄儀等。LiteOS-A要求設(shè)備具備一定的處理能力,對(duì)比LiteOS-M,LiteOS-A支持以下特性:(1)MMU支持:通過(guò)MMU支持內(nèi)核態(tài)和用戶態(tài)分離,支持虛擬單元;(2)支持獨(dú)立進(jìn)程:調(diào)度對(duì)象分別為進(jìn)程、線程;(3)支持文件系統(tǒng):包括虛擬文件和塊設(shè)備等;(4)支持更復(fù)雜的IPC:包括LiteIPC等;(5)支持多核調(diào)度:支持雙核MCU,支持雙核調(diào)度;(6)支持POSIX3接口:為APP開發(fā)提供更多幫助。LiteOS-A內(nèi)核簡(jiǎn)介L(zhǎng)iteOS-A的源碼目錄:關(guān)鍵目錄:arch:存放了arm架構(gòu)相關(guān)的代碼,以及中斷管理相關(guān)代碼compat:POSIX標(biāo)準(zhǔn)目的是為了提供源碼級(jí)的軟件可移植性。一個(gè)系統(tǒng)提供了POSIX接口,則任何其它的系統(tǒng)可以通過(guò)POSIX調(diào)用該系統(tǒng)drivers:內(nèi)核驅(qū)動(dòng)代碼,分別對(duì)應(yīng)塊設(shè)備驅(qū)動(dòng)、字符設(shè)備驅(qū)動(dòng)、內(nèi)存設(shè)備驅(qū)動(dòng)LiteOS-A內(nèi)核簡(jiǎn)介關(guān)鍵目錄:kernel:base:基礎(chǔ)內(nèi)核,進(jìn)程管理、內(nèi)存管理、內(nèi)核通信機(jī)制、時(shí)間管理、軟件定時(shí)器等模塊。include:內(nèi)核相關(guān)模塊頭文件。LiteOS-A的源碼目錄:謝謝5.1.2LiteOS-A內(nèi)核架構(gòu)通過(guò)本節(jié)學(xué)習(xí),您可以:了解LiteOS-A內(nèi)核架構(gòu)LiteOS-A內(nèi)核架構(gòu)LiteOS-A內(nèi)核分為內(nèi)核空間和用戶空間,如圖所示。LiteOS-A內(nèi)核架構(gòu)(1)基礎(chǔ)內(nèi)核:進(jìn)程管理:支持進(jìn)程和線程,采用了高優(yōu)先級(jí)優(yōu)先加同優(yōu)先級(jí)時(shí)間片輪轉(zhuǎn)的搶占式調(diào)度機(jī)制。內(nèi)存管理:對(duì)物理內(nèi)存和虛擬內(nèi)存分別進(jìn)行管理。中斷異常:對(duì)中斷的異常處理。時(shí)間管理:對(duì)操作系統(tǒng)時(shí)間進(jìn)行管理,提供給應(yīng)用程序所有和時(shí)間有關(guān)的服務(wù)。通信機(jī)制:包括事件、信號(hào)量、互斥鎖、消息隊(duì)列、信號(hào)等。1.
內(nèi)核空間LiteOS-A內(nèi)核架構(gòu)(2)擴(kuò)展組件:主要包括文件系統(tǒng)、網(wǎng)絡(luò)協(xié)議、權(quán)限管理、動(dòng)態(tài)加載、調(diào)測(cè)工具等。文件系統(tǒng):輕量級(jí)內(nèi)核支持FAT,JFFS2,NFS,ramfs,procfs等眾多文件系統(tǒng),并對(duì)外提供完整的POSIX標(biāo)準(zhǔn)的操作接口;內(nèi)部使用VFS(VirtualFileSystems,虛擬文件系統(tǒng))層作為統(tǒng)一的適配層框架,方便移植新的文件系統(tǒng),各個(gè)文件系統(tǒng)也能自動(dòng)利用VFS層提供的豐富的功能。LiteOS-A內(nèi)核架構(gòu)網(wǎng)絡(luò)協(xié)議:網(wǎng)絡(luò)協(xié)議基于開源LWIP(LightWeightIP協(xié)議)構(gòu)建。支持多種協(xié)議:IP、ICMP、ND、MLD、UDP、TCP、IGMP、ARP、PPP支持的API:socketAPI網(wǎng)絡(luò)協(xié)議的擴(kuò)展特性:多網(wǎng)絡(luò)接口IP轉(zhuǎn)發(fā)、TCP擁塞控制、RTT估計(jì)和快速恢復(fù)、快速重傳。支持多種應(yīng)用程序LiteOS-A內(nèi)核架構(gòu)支持的協(xié)議:IP協(xié)議:包括IPV4和IPV6,支持IP分片于重裝,支持多網(wǎng)絡(luò)接口下數(shù)據(jù)包轉(zhuǎn)發(fā)。ICMP協(xié)議:用于網(wǎng)絡(luò)調(diào)試維護(hù)。ND(NeighborDiscovery)協(xié)議:IP6鄰居發(fā)現(xiàn)協(xié)議。MLD協(xié)議:組播偵聽發(fā)現(xiàn)協(xié)議,于IPv6組播中組成員管理。UDP協(xié)議:用戶數(shù)據(jù)包協(xié)議。TCP:支持TCP擁塞控制,RTT估計(jì),快恢復(fù)和重傳等。IGMP:用于網(wǎng)絡(luò)組管理,可以實(shí)現(xiàn)多播數(shù)據(jù)的接收。ARP協(xié)議:地址解析協(xié)議。PPP協(xié)議:包括PPPoS(串口點(diǎn)對(duì)點(diǎn)協(xié)議)、PPPoE(以太網(wǎng)上的點(diǎn)對(duì)點(diǎn)協(xié)議)。LiteOS-A內(nèi)核架構(gòu)適用的應(yīng)用程序:HTTP(S)服務(wù)SNTP客戶端SMTP(S)客戶端ping工具NetBIOS名稱服務(wù)mDNS響應(yīng)程序MQTT客戶端TFTP服務(wù)DHCP客戶端DNS客戶端AutoIP/APIPA(零配置)SNMP代理LiteOS-A內(nèi)核架構(gòu)(3)HDF框架HDF框架是外設(shè)驅(qū)動(dòng)統(tǒng)一標(biāo)準(zhǔn)框架,提供了GPIO、SDIO、I2C、USB、WLAN等各種外設(shè)接口方式。HDF框架特性:支持多內(nèi)核平臺(tái)。支持用戶態(tài)驅(qū)動(dòng)??膳渲媒M件化驅(qū)動(dòng)模型?;谙⒌尿?qū)動(dòng)接口模型。基于對(duì)象的驅(qū)動(dòng)、設(shè)備管理。HDI(HardwareDriverInterface)統(tǒng)一硬件接口。支持電源管理、PnP(Plug-and-Play,即插即用)。LiteOS-A內(nèi)核架構(gòu)LiteOS-A內(nèi)核架構(gòu)的頂部是用戶空間,用戶空間主要是用戶進(jìn)程和POSIX接口組成。OpenHarmony內(nèi)核使用musllibc庫(kù),支持標(biāo)準(zhǔn)POSIX接口,開發(fā)者可基于POSIX標(biāo)準(zhǔn)接口開發(fā)內(nèi)核之上的組件及應(yīng)用。2.用戶空間謝謝5.1.3LiteOS-A內(nèi)核態(tài)啟動(dòng)流程通過(guò)本節(jié)學(xué)習(xí),您可以:了解LiteOS-A內(nèi)核態(tài)啟動(dòng)流程LiteOS-A內(nèi)核態(tài)啟動(dòng)流程內(nèi)核啟動(dòng)流程如圖所示。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程內(nèi)核啟動(dòng)流程包含匯編啟動(dòng)階段和C語(yǔ)言啟動(dòng)階段兩部分。匯編啟動(dòng)階段完成CPU初始設(shè)置,關(guān)閉dcache/icache與MMU,使能FPU及neon,設(shè)置MMU建立虛實(shí)地址映射,設(shè)置系統(tǒng)棧,清理bss段,調(diào)用C語(yǔ)言main函數(shù)等。C語(yǔ)言啟動(dòng)階段包含OsMain函數(shù)及開始調(diào)度等。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程OsMain函數(shù)用于內(nèi)核基礎(chǔ)初始化和架構(gòu)、板級(jí)初始化等,其整體由內(nèi)核啟動(dòng)框架主導(dǎo)初始化流程,如圖所示。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程①LOS_INIT_LEVEL_EARLIEST:最早期初始化。不依賴架構(gòu),單板以及后續(xù)模塊會(huì)對(duì)其有依賴的純軟件模塊初始,例如:內(nèi)核Trace模塊初始化。②LOS_INIT_LEVEL_ARCH_EARLY:架構(gòu)早期初始化。與架構(gòu)相關(guān),后續(xù)模塊會(huì)對(duì)其有依賴的模塊初始化,如啟動(dòng)過(guò)程中非必需的功能,建議放到⑥LOS_INIT_LEVEL_ARCH層。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程③LOS_INIT_LEVEL_PLATFORM_EARLY:平臺(tái)早期初始化。與單板平臺(tái)、驅(qū)動(dòng)相關(guān),后續(xù)模塊會(huì)對(duì)其有依賴的模塊初始化,如啟動(dòng)過(guò)程中必需的功能,建議放到⑦LOS_INIT_LEVEL_PLATFORM層。④LOS_INIT_LEVEL_KMOD_PREVM:內(nèi)存初始化前的內(nèi)核模塊初始化。在內(nèi)存初始化之前需要使能的模塊初始化。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程⑤LOS_INIT_LEVEL_VM_COMPLETE:基礎(chǔ)內(nèi)存就緒后的初始化。此時(shí)內(nèi)存初始化完畢,需要進(jìn)行使能且不依賴進(jìn)程間通訊機(jī)制與系統(tǒng)進(jìn)程的模塊初始化。⑥LOS_INIT_LEVEL_ARCH:架構(gòu)后期初始化。與架構(gòu)拓展功能相關(guān),后續(xù)模塊會(huì)對(duì)其有依賴的模塊初始化。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程⑦LOS_INIT_LEVEL_PLATFORM:平臺(tái)后期初始化。單板平臺(tái)、驅(qū)動(dòng)相關(guān),后續(xù)模塊會(huì)對(duì)其有依賴的模塊初始化,例如:驅(qū)動(dòng)內(nèi)核抽象層初始化(mmc、mtd)。⑧LOS_INIT_LEVEL_KMOD_BASIC:內(nèi)核基礎(chǔ)模塊初始化。內(nèi)核可拆卸的基礎(chǔ)模塊初始化。例如:VFS初始化。LiteOS-A內(nèi)核態(tài)啟動(dòng)流程⑨LOS_INIT_LEVEL_KMOD_EXTENDED:內(nèi)核擴(kuò)展模塊初始化。內(nèi)核可拆卸的擴(kuò)展模塊初始化。例如:系統(tǒng)調(diào)用初始化、ProcFS初始化、Futex初始化、HiLog初始化、LiteIPC初始化。⑩LOS_INIT_LEVEL_KMOD_TASK:內(nèi)核任務(wù)創(chuàng)建。進(jìn)行內(nèi)核任務(wù)的創(chuàng)建(內(nèi)核任務(wù),軟件定時(shí)器任務(wù))。例如:資源回收系統(tǒng)常駐任務(wù)的創(chuàng)建、SystemInit任務(wù)創(chuàng)建、CPU占用率統(tǒng)計(jì)任務(wù)創(chuàng)建等。謝謝5.1.4LiteOS-A用戶態(tài)啟動(dòng)流程通過(guò)本節(jié)學(xué)習(xí),您可以:了解LiteOS-A用戶態(tài)啟動(dòng)流程LiteOS-A用戶態(tài)啟動(dòng)流程用戶態(tài)啟動(dòng)是從根進(jìn)程開始的。根進(jìn)程是系統(tǒng)的第一個(gè)用戶態(tài)進(jìn)程,進(jìn)程ID為1。用戶態(tài)啟動(dòng)進(jìn)程樹如圖所示。1號(hào)進(jìn)程接下來(lái)會(huì)創(chuàng)建和啟動(dòng)其他的用戶態(tài)進(jìn)程例如/bin/shell。LiteOS-A用戶態(tài)啟動(dòng)流程鴻蒙中的init進(jìn)程作用類似于Linux中的init進(jìn)程,主要作用是完成系統(tǒng)啟動(dòng)后,用戶可以操作前的一些初始化操作,例如孵化一些用戶的服務(wù),創(chuàng)建一些必要的文件目錄結(jié)構(gòu)等。Init進(jìn)程是由SysemInit()函數(shù)來(lái)啟動(dòng)的,SystemInit()函數(shù)代碼如下所示:
SystemInit()
ProcFsInit();
mem_dev_register();
imx6ull_driver_init();
imx6ull_mount_rootfs();
DeviceManagerStart();//HDF,加載驅(qū)動(dòng),使外設(shè)可以正常工作。
uart_dev_init();
......
OsUserInitProcess();LiteOS-A用戶態(tài)啟動(dòng)流程在SystemInit()函數(shù)中,通過(guò)OsUserInitProcess()啟動(dòng)init進(jìn)程,具體是通過(guò)OsUserInitProcessStart()函數(shù)來(lái)實(shí)現(xiàn)的。OsUserInitProcessStart()函數(shù)的代碼如下:
STATICUINT32OsUserInitProcessStart(UINT32processID,TSK_INIT_PARAM_S*param)
{
UINT32intSave;
INT32taskID;
INT32ret;
taskID=OsCreateUserTask(processID,param);
if(taskID<0){
returnLOS_NOK;
}
ret=LOS_SetTaskScheduler(taskID,LOS_SCHED_RR,OS_TASK_PRIORITY_LOWEST);
if(ret<0){
PRINT_ERR("Userinitprocesssetschedulerfailed!ERROR:%d\n",ret);
SCHEDULER_LOCK(intSave);
(VOID)OsTaskDeleteUnsafe(OS_TCB_FROM_TID(taskID),OS_PRO_EXIT_OK,intSave);
return-ret;
}
returnLOS_OK;
}謝謝5.2.1中斷與異常處理的概念和機(jī)制通過(guò)本節(jié)學(xué)習(xí),您可以:了解中斷與異常處理的概念和機(jī)制中斷與異常處理的概念中斷異常處理是操作系統(tǒng)對(duì)運(yùn)行期間發(fā)生的異常情況(芯片硬件異常)進(jìn)行處理的一系列動(dòng)作,例如虛擬內(nèi)存缺頁(yè)異常、打印異常發(fā)生時(shí)函數(shù)的調(diào)用棧信息、CPU現(xiàn)場(chǎng)信息、任務(wù)的堆棧情況等。異常指可以打斷CPU正常運(yùn)行流程的一些事情,如未定義指令異常、試圖修改只讀的數(shù)據(jù)異常、不對(duì)齊的地址訪問(wèn)異常等。中斷與異常處理機(jī)制LiteOS-A的中斷異常處理流程:外設(shè)可以在沒(méi)有CPU介入的情況下完成一定的工作,但某些情況下也需要CPU為其執(zhí)行一定的工作。當(dāng)外設(shè)需要CPU時(shí),將產(chǎn)生一個(gè)中斷信號(hào),該信號(hào)連接至中斷控制器。中斷控制器是一方面接收其它外設(shè)中斷引腳的輸入,另一方面它會(huì)發(fā)出中斷信號(hào)給CPU??梢酝ㄟ^(guò)對(duì)中斷控制器編程來(lái)打開和關(guān)閉中斷源、設(shè)置中斷源的優(yōu)先級(jí)和觸發(fā)方式。CPU收到中斷控制器發(fā)送的中斷信號(hào)后,中斷當(dāng)前任務(wù)來(lái)響應(yīng)中斷請(qǐng)求。當(dāng)異常發(fā)生時(shí),CPU暫停當(dāng)前的程序,先處理異常事件,然后再繼續(xù)執(zhí)行被異常打斷的程序。中斷與異常處理機(jī)制常用的中斷控制器有VIC(VectorInterruptController,向量中斷控制器)和GIC(GeneralInterruptController,通用中斷控制器)。LiteOS-A內(nèi)核支持的是ARM公司的Cortex-A/R系列的芯片,GIC是ARM公司給Cortex-A/R系列芯片提供的一個(gè)中斷控制器,類似Cortex-M中的NVIC。GIC控制器有4個(gè)版本V1-V4,V2版本是給ARMv7-A架構(gòu)使用的,比如Cortex-A5,Cortex-A7、Cortex-A9、Cortex-A15等。中斷與異常處理機(jī)制當(dāng)GIC控制器接收到外部中斷信號(hào)以后匯報(bào)給ARM內(nèi)核,ARM內(nèi)核提供了四個(gè)信號(hào)給GIC來(lái)匯報(bào)中斷情況:VFIQ、VIRQ、FIQ和IRQ,如圖所示。中斷與異常處理機(jī)制4個(gè)信號(hào)含義如下:VFIQ:虛擬快速FIQVIRQ:虛擬外部IRQFIQ:快速中斷IRQIRQ:外部中斷IRQGIC控制器接收眾多的外部中斷,并對(duì)其進(jìn)行處理,最終通過(guò)四個(gè)信號(hào)報(bào)給ARM內(nèi)核。中斷與異常處理的概念和機(jī)制LiteOS-A當(dāng)前支持ARMv7-a指令集架構(gòu),以ARMv7-a架構(gòu)為例,中斷和異常處理的入口為中斷向量表,中斷向量表包含各個(gè)中斷和異常處理的中斷向量,如表所示。中斷向量異常中斷名稱_exception_handlersresetvector復(fù)位osExceptUndeflnstrHd未定義的指令osExceptSwiHdl軟件中斷osExceptPrefetchAbortHdl預(yù)取指令中止osExceptDataAbortHdl數(shù)據(jù)訪問(wèn)中止osExceptAddrAbortHd地址異常中止OslrqHandler外部中斷請(qǐng)求osExceptFiqHd快速中斷請(qǐng)求謝謝5.2.2中斷與異常處理接口與應(yīng)用通過(guò)本節(jié)學(xué)習(xí),您可以:了解中斷與異常處理接口說(shuō)明與應(yīng)用中斷與異常處理接口與應(yīng)用OpenHarmonyLiteOS-A內(nèi)核的中斷模塊提供的接口跟LiteOS-M基本相同,包括創(chuàng)建中斷、刪除中斷、打開和關(guān)閉中斷等接口,如表所示。1.
中斷與異常處理管理接口功能分類接口名描述創(chuàng)建中斷LOS_HwiCreate中斷創(chuàng)建,注冊(cè)中斷號(hào)、中斷觸發(fā)模式、中斷優(yōu)先級(jí)、中斷處理程序。中斷被觸發(fā)時(shí),會(huì)調(diào)用該中斷處理程序刪除中斷LOS_HwiDelete根據(jù)指定的中斷號(hào),刪除中斷打開中斷LOS_IntUnLock打開當(dāng)前處理器所有中斷響應(yīng)關(guān)閉中斷LOS_IntLock關(guān)閉當(dāng)前處理器所有中斷響應(yīng)恢復(fù)中斷LOS_IntRestore與LOS_IntLock配套使用,恢復(fù)到使用LOS_IntLock關(guān)閉所有中斷之前的狀態(tài)中斷與異常處理接口與應(yīng)用中斷管理的一般開發(fā)流程如下:(1)調(diào)用中斷創(chuàng)建接口LOS_HwiCreate創(chuàng)建中斷。(2)調(diào)用LOS_HwiDelete接口刪除指定中斷,此接口根據(jù)實(shí)際情況使用,判斷是否需要?jiǎng)h除中斷。2.中斷管理應(yīng)用謝謝5.3.1進(jìn)程管理通過(guò)本節(jié)學(xué)習(xí),您可以:了解進(jìn)程管理進(jìn)程管理進(jìn)程是系統(tǒng)資源管理的基本單元。OpenHarmonyLiteOS-A內(nèi)核提供的進(jìn)程模塊主要用于實(shí)現(xiàn)用戶態(tài)進(jìn)程的隔離,不涉及內(nèi)核態(tài)進(jìn)程。進(jìn)程模塊主要為用戶提供多個(gè)進(jìn)程,實(shí)現(xiàn)了進(jìn)程之間的切換和通信,幫助用戶管理業(yè)務(wù)程序流程。進(jìn)程采用搶占式調(diào)度機(jī)制,采用高優(yōu)先級(jí)優(yōu)先加同優(yōu)先級(jí)時(shí)間片輪轉(zhuǎn)的調(diào)度算法。進(jìn)程一共有32個(gè)優(yōu)先級(jí)(0-31),用戶進(jìn)程可配置的優(yōu)先級(jí)有22個(gè)(10-31),最高優(yōu)先級(jí)為10,最低優(yōu)先級(jí)為31。高優(yōu)先級(jí)的進(jìn)程可搶占低優(yōu)先級(jí)進(jìn)程,低優(yōu)先級(jí)進(jìn)程必須在高優(yōu)先級(jí)進(jìn)程阻塞或結(jié)束后才能得到調(diào)度。每一個(gè)用戶態(tài)進(jìn)程均擁有自己獨(dú)立的進(jìn)程空間,相互之間不可見,實(shí)現(xiàn)進(jìn)程間隔離。用戶態(tài)根進(jìn)程init由內(nèi)核態(tài)創(chuàng)建,其它用戶態(tài)子進(jìn)程均由init進(jìn)程創(chuàng)建而來(lái)。1.
進(jìn)程的概念進(jìn)程管理進(jìn)程有多種狀態(tài),各狀態(tài)之間的關(guān)系如圖所示:2.進(jìn)程狀態(tài)初始化(Init):進(jìn)程正在被創(chuàng)建。就緒態(tài)(Ready):進(jìn)程在就緒列表中,等待CPU調(diào)度。運(yùn)行態(tài)(Running):進(jìn)程正在運(yùn)行。阻塞態(tài)(Pending):進(jìn)程被阻塞掛起。本進(jìn)程內(nèi)所有的線程均被阻塞時(shí),進(jìn)程被阻塞掛起。僵尸態(tài)(Zombies):進(jìn)程運(yùn)行結(jié)束,等待父進(jìn)程回收其控制塊資源。進(jìn)程管理初始化→就緒態(tài):進(jìn)程創(chuàng)建或fork時(shí),拿到對(duì)應(yīng)進(jìn)程控制塊后進(jìn)入Init狀態(tài),即進(jìn)程初始化階段,當(dāng)該階段完成后進(jìn)程將被插入調(diào)度隊(duì)列,此時(shí)進(jìn)程進(jìn)入就緒狀態(tài)。就緒態(tài)→運(yùn)行態(tài):發(fā)生進(jìn)程切換時(shí),就緒列表中優(yōu)先級(jí)最高且獲得時(shí)間片的進(jìn)程被執(zhí)行,從而進(jìn)入運(yùn)行態(tài)。若此時(shí)該進(jìn)程中已無(wú)其它線程處于就緒態(tài),則進(jìn)程從就緒列表刪除,只處于運(yùn)行態(tài);若此時(shí)該進(jìn)程中還有其它線程處于就緒態(tài),則該進(jìn)程依舊在就緒隊(duì)列,此時(shí)進(jìn)程的就緒態(tài)和運(yùn)行態(tài)共存,但對(duì)外呈現(xiàn)的進(jìn)程狀態(tài)為運(yùn)行態(tài)。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)僵尸態(tài)進(jìn)程管理運(yùn)行態(tài)→阻塞態(tài):進(jìn)程在最后一個(gè)線程轉(zhuǎn)為阻塞態(tài)時(shí),進(jìn)程內(nèi)所有的線程均處于阻塞態(tài),此時(shí)進(jìn)程同步進(jìn)入阻塞態(tài),然后發(fā)生進(jìn)程切換。阻塞態(tài)→就緒態(tài):阻塞進(jìn)程內(nèi)的任意線程恢復(fù)就緒態(tài)時(shí),進(jìn)程被加入到就緒隊(duì)列,同步轉(zhuǎn)為就緒態(tài)。就緒態(tài)→阻塞態(tài):進(jìn)程內(nèi)的最后一個(gè)就緒態(tài)線程轉(zhuǎn)為阻塞態(tài)時(shí),進(jìn)程從就緒列表中刪除,進(jìn)程由就緒態(tài)轉(zhuǎn)為阻塞態(tài)。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)僵尸態(tài)進(jìn)程管理運(yùn)行態(tài)→就緒態(tài):有更高優(yōu)先級(jí)的進(jìn)程創(chuàng)建或者恢復(fù)后,會(huì)發(fā)生進(jìn)程調(diào)度,此刻就緒列表中最高優(yōu)先級(jí)進(jìn)程變?yōu)檫\(yùn)行態(tài),那么原先運(yùn)行的進(jìn)程由運(yùn)行態(tài)變?yōu)榫途w態(tài)。若進(jìn)程的調(diào)度策略為L(zhǎng)OS_SCHED_RR(時(shí)間片輪轉(zhuǎn)),且存在同一優(yōu)先級(jí)的另一個(gè)進(jìn)程處于就緒態(tài),則該進(jìn)程的時(shí)間片消耗光之后,該進(jìn)程由運(yùn)行態(tài)轉(zhuǎn)為就緒態(tài),另一個(gè)同優(yōu)先級(jí)的進(jìn)程由就緒態(tài)轉(zhuǎn)為運(yùn)行態(tài)。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)僵尸態(tài)進(jìn)程管理運(yùn)行態(tài)→僵尸態(tài):當(dāng)進(jìn)程的主線程或所有線程運(yùn)行結(jié)束后,進(jìn)程由運(yùn)行態(tài)轉(zhuǎn)為僵尸態(tài),等待父進(jìn)程回收資源。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)僵尸態(tài)進(jìn)程管理進(jìn)程管理主要是合理的分配各個(gè)進(jìn)程使用CPU的時(shí)間。用戶態(tài)進(jìn)程由Init進(jìn)程分解而來(lái),如圖所示。fork進(jìn)程時(shí)會(huì)將父進(jìn)程的進(jìn)程虛擬內(nèi)存空間克隆到子進(jìn)程,子進(jìn)程實(shí)際運(yùn)行時(shí)通過(guò)寫時(shí)復(fù)制機(jī)制將父進(jìn)程的內(nèi)容按需復(fù)制到子進(jìn)程的虛擬內(nèi)存空間。3.進(jìn)程運(yùn)行機(jī)制用戶態(tài)進(jìn)程
多線程用戶態(tài)進(jìn)程
多線程Init進(jìn)程
多線程進(jìn)程管理OpenHarmonyLiteOS-A內(nèi)核的進(jìn)程管理模塊提供了進(jìn)程組、用戶組、進(jìn)程創(chuàng)建等接口。4.進(jìn)程接口功能分類接口名接口描述獲取進(jìn)程IDLOS_GetCurrProcessID獲取當(dāng)前進(jìn)程的進(jìn)程ID進(jìn)程組LOS_GetProcessGroupID獲取指定進(jìn)程的進(jìn)程組IDLOS_GetCurrProcessGroupID獲取當(dāng)前進(jìn)程的進(jìn)程組ID用戶及用戶組LOS_GetUserID獲取當(dāng)前進(jìn)程的用戶IDLOS_GetGroupID獲取當(dāng)前進(jìn)程的用戶組IDLOS_CheckInGroups檢查指定用戶組ID是否在當(dāng)前進(jìn)程的用戶組內(nèi)進(jìn)程管理功能分類接口名接口描述進(jìn)度調(diào)度參數(shù)控制LOS_GetProcessScheduler獲取指定進(jìn)程的調(diào)度策略LOS_SetProcessScheduler設(shè)置指定進(jìn)程的調(diào)度參數(shù),包括優(yōu)先級(jí)和調(diào)度策略LOS_SetProcessPriority設(shè)置進(jìn)程優(yōu)先級(jí)LOS_GetProcessPriority獲取進(jìn)程優(yōu)先級(jí)系統(tǒng)支持的最大進(jìn)程數(shù)LOS_GetSystemProcessMaximum獲取系統(tǒng)支持的最大進(jìn)程數(shù)目LOS_GetUsedPIDList獲得已使用的進(jìn)程ID列表進(jìn)程管理功能分類接口名接口描述創(chuàng)建進(jìn)程LOS_Fork創(chuàng)建子進(jìn)程等待進(jìn)程LOS_Wait等待子進(jìn)程結(jié)束并回收子進(jìn)程LOS_Waitid等待相應(yīng)ID的進(jìn)程結(jié)束退出進(jìn)程LOS_Exit退出進(jìn)程謝謝5.3.2任務(wù)管理通過(guò)本節(jié)學(xué)習(xí),您可以:了解任務(wù)管理任務(wù)管理從系統(tǒng)的角度看,任務(wù)Task是競(jìng)爭(zhēng)系統(tǒng)資源的最小運(yùn)行單元。任務(wù)可以使用或等待CPU、使用內(nèi)存空間等系統(tǒng)資源,并獨(dú)立于其它任務(wù)運(yùn)行。OpenHarmony內(nèi)核中使用一個(gè)任務(wù)表示一個(gè)線程。OpenHarmony內(nèi)核中同優(yōu)先級(jí)進(jìn)程內(nèi)的任務(wù)統(tǒng)一調(diào)度、運(yùn)行。OpenHarmony內(nèi)核中的任務(wù)采用搶占式調(diào)度機(jī)制,同時(shí)支持時(shí)間片輪轉(zhuǎn)調(diào)度和FIFO調(diào)度方式。內(nèi)核的任務(wù)一共有32個(gè)優(yōu)先級(jí)(0-31),最高優(yōu)先級(jí)為0,最低優(yōu)先級(jí)為31。當(dāng)前進(jìn)程內(nèi),高優(yōu)先級(jí)的任務(wù)可搶占低優(yōu)先級(jí)任務(wù),低優(yōu)先級(jí)任務(wù)必須在高優(yōu)先級(jí)任務(wù)阻塞或結(jié)束后才能得到調(diào)度。1.
任務(wù)管理概念任務(wù)管理任務(wù)的各狀態(tài)如圖所示:
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)退出初始化(Init):任務(wù)正在被創(chuàng)建。就緒態(tài)(Ready):任務(wù)在就緒隊(duì)列中,等待CPU調(diào)度。運(yùn)行態(tài)(Running):任務(wù)正在運(yùn)行。阻塞態(tài)(Blocked):任務(wù)被阻塞掛起。Blocked狀態(tài)包括:pending(因?yàn)殒i、事件、信號(hào)量等阻塞)、suspended(主動(dòng)pend)、delay(延時(shí)阻塞)、pendtime(因?yàn)殒i、事件、信號(hào)量時(shí)間等超時(shí)等待)。退出態(tài)(Exit):任務(wù)運(yùn)行結(jié)束,等待父任務(wù)回收其控制塊資源。任務(wù)管理初始化→就緒態(tài):任務(wù)創(chuàng)建拿到控制塊后為初始化階段(Init狀態(tài)),當(dāng)任務(wù)初始化完成將任務(wù)插入調(diào)度隊(duì)列,此時(shí)任務(wù)進(jìn)入就緒狀態(tài)。就緒態(tài)→運(yùn)行態(tài):任務(wù)創(chuàng)建后進(jìn)入就緒態(tài),發(fā)生任務(wù)切換時(shí),就緒隊(duì)列中最高優(yōu)先級(jí)的任務(wù)被執(zhí)行,從而進(jìn)入運(yùn)行態(tài),此刻該任務(wù)從就緒隊(duì)列中刪除。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)退出任務(wù)管理運(yùn)行態(tài)→阻塞態(tài):正在運(yùn)行的任務(wù)發(fā)生阻塞(掛起、延時(shí)、讀信號(hào)量等)時(shí),任務(wù)狀態(tài)由運(yùn)行態(tài)變成阻塞態(tài),然后發(fā)生任務(wù)切換,運(yùn)行就緒隊(duì)列中剩余最高優(yōu)先級(jí)任務(wù)。阻塞態(tài)→就緒態(tài):阻塞的任務(wù)被恢復(fù)后(任務(wù)恢復(fù)、延時(shí)時(shí)間超時(shí)、讀信號(hào)量超時(shí)或讀到信號(hào)量等),此時(shí)被恢復(fù)的任務(wù)會(huì)被加入就緒隊(duì)列,從而由阻塞態(tài)變成就緒態(tài)。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)退出任務(wù)管理就緒態(tài)→阻塞態(tài):任務(wù)也有可能在就緒態(tài)時(shí)被阻塞(掛起),此時(shí)任務(wù)狀態(tài)會(huì)由就緒態(tài)轉(zhuǎn)變?yōu)樽枞麘B(tài),該任務(wù)從就緒隊(duì)列中刪除,不會(huì)參與任務(wù)調(diào)度,直到該任務(wù)被恢復(fù)。運(yùn)行態(tài)→就緒態(tài):有更高優(yōu)先級(jí)任務(wù)創(chuàng)建或者恢復(fù)后,會(huì)發(fā)生任務(wù)調(diào)度,此刻就緒隊(duì)列中最高優(yōu)先級(jí)任務(wù)變?yōu)檫\(yùn)行態(tài),那么原先運(yùn)行的任務(wù)由運(yùn)行態(tài)變?yōu)榫途w態(tài),并加入就緒隊(duì)列中。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)退出任務(wù)管理運(yùn)行態(tài)→退出態(tài):運(yùn)行中的任務(wù)運(yùn)行結(jié)束,任務(wù)狀態(tài)由運(yùn)行態(tài)變?yōu)橥顺鰬B(tài)。
初始化就緒態(tài)阻塞態(tài)運(yùn)行態(tài)退出任務(wù)管理OpenHarmonyLiteOS-A內(nèi)核的任務(wù)管理模塊提供了創(chuàng)建任務(wù)、刪除任務(wù)、控制任務(wù)狀態(tài)、獲取任務(wù)信息等幾種功能,具體如表所示。2.任務(wù)管理接口功能分類接口名接口描述任務(wù)的創(chuàng)建和刪除
LOS_TaskCreate創(chuàng)建任務(wù),若所創(chuàng)建任務(wù)的優(yōu)先級(jí)比當(dāng)前的運(yùn)行的任務(wù)優(yōu)先級(jí)高且任務(wù)調(diào)度沒(méi)有鎖定,則該任務(wù)將被調(diào)度進(jìn)入運(yùn)行態(tài)LOS_TaskCreateOnly創(chuàng)建任務(wù)并阻塞,任務(wù)恢復(fù)前不會(huì)將其加入就緒隊(duì)列中LOS_TaskDelete刪除指定的任務(wù),回收其任務(wù)控制塊和任務(wù)棧所消耗的資源任務(wù)的狀態(tài)控制
LOS_TaskResume恢復(fù)掛起的任務(wù)LOS_TaskSuspend掛起指定的任務(wù),該任務(wù)將從就緒任務(wù)隊(duì)列中移除LOS_TaskJoin阻塞當(dāng)前任務(wù),等待指定任務(wù)運(yùn)行結(jié)束并回收其資源LOS_TaskDetach修改任務(wù)的joinable屬性為detach屬性,detach屬性的任務(wù)運(yùn)行結(jié)束會(huì)自動(dòng)回收任務(wù)控制塊資源LOS_TaskDelay延遲當(dāng)前任務(wù)的執(zhí)行,在延后指定的時(shí)間(tick數(shù))后可以被調(diào)度LOS_TaskYield將當(dāng)前任務(wù)從具有相同優(yōu)先級(jí)的任務(wù)隊(duì)列,移動(dòng)到就緒任務(wù)隊(duì)列的末尾任務(wù)管理功能分類接口名接口描述任務(wù)調(diào)度
LOS_TaskLock鎖定任務(wù)調(diào)度,阻止任務(wù)切換LOS_TaskUnlock解鎖任務(wù)調(diào)度。通過(guò)該接口可以使任務(wù)鎖數(shù)量減1,若任務(wù)多次加鎖,那么任務(wù)調(diào)度在鎖數(shù)量減為0時(shí)才會(huì)完全解鎖LOS_GetTaskScheduler獲取指定任務(wù)的調(diào)度策略LOS_SetTaskScheduler設(shè)置指定任務(wù)的調(diào)度參數(shù),包括優(yōu)先級(jí)和調(diào)度策略LOS_Schedule觸發(fā)主動(dòng)的任務(wù)調(diào)度任務(wù)信息獲取
LOS_CurTaskIDGet獲取當(dāng)前任務(wù)的IDLOS_TaskInfoGet獲取指定任務(wù)的信息LOS_GetSystemTaskMaximum獲取系統(tǒng)支持的最大任務(wù)數(shù)任務(wù)優(yōu)先級(jí)
LOS_CurTaskPriSet設(shè)置當(dāng)前正在運(yùn)行的任務(wù)的優(yōu)先級(jí)LOS_TaskPriSet設(shè)置指定任務(wù)的優(yōu)先級(jí)LOS_TaskPriGet獲取指定任務(wù)的優(yōu)先級(jí)任務(wù)綁核操作
LOS_TaskCpuAffiSet綁定指定任務(wù)到指定CPU上運(yùn)行,僅在多核下使用LOS_TaskCpuAffiGet獲取指定任務(wù)的綁核信息,僅在多核下使用任務(wù)管理任務(wù)管理的一般開發(fā)流程如下:(1)通過(guò)LOS_TaskCreate創(chuàng)建一個(gè)任務(wù)。指定任務(wù)的執(zhí)行入口函數(shù)指定任務(wù)名指定任務(wù)的棧大小指定任務(wù)的優(yōu)先級(jí)(2)任務(wù)參與調(diào)度運(yùn)行,執(zhí)行用戶指定的業(yè)務(wù)代碼。(3)任務(wù)執(zhí)行結(jié)束。3.任務(wù)管理應(yīng)用謝謝5.3.3調(diào)度器通過(guò)本節(jié)學(xué)習(xí),您可以:了解調(diào)度器調(diào)度器調(diào)度器(scheduler)是一個(gè)操作系統(tǒng)的核心部分,是CPU時(shí)間的管理員,負(fù)責(zé)選擇最適合的就緒進(jìn)程來(lái)執(zhí)行。1.
調(diào)度器概念周期性調(diào)度器CPU上下文切換主調(diào)度器選擇進(jìn)程調(diào)度器類進(jìn)程調(diào)度器主要完成兩件事:選擇某些就緒進(jìn)程來(lái)執(zhí)行。打斷某些執(zhí)行的進(jìn)程讓他們變?yōu)榫途w態(tài)調(diào)度器主調(diào)度器:通過(guò)調(diào)用schedule()函數(shù)來(lái)完成進(jìn)程的選擇和切換。周期性調(diào)度器:根據(jù)頻率自動(dòng)調(diào)用scheduler_tick函數(shù),根據(jù)進(jìn)程運(yùn)行時(shí)間觸發(fā)調(diào)度。上下文切換:主要做兩個(gè)事情,切換地址空間、切換寄存器和??臻g。調(diào)度器類:每個(gè)調(diào)度器都有一個(gè)優(yōu)先級(jí),它會(huì)按照優(yōu)先級(jí)順序遍歷調(diào)度類,擁有一個(gè)可執(zhí)行進(jìn)程的最高優(yōu)先級(jí)的調(diào)度器類勝出,去選擇下面要執(zhí)行的那一個(gè)程序。周期性調(diào)度器CPU上下文切換主調(diào)度器選擇進(jìn)程調(diào)度器類進(jìn)程調(diào)度器2.調(diào)度器運(yùn)行機(jī)制OpenHarmony在系統(tǒng)啟動(dòng)內(nèi)核初始化之后開始調(diào)度。系統(tǒng)根據(jù)進(jìn)程和線程的優(yōu)先級(jí)及線程的時(shí)間片消耗情況選擇最優(yōu)的線程進(jìn)行調(diào)度運(yùn)行。線程一旦調(diào)度到就會(huì)從調(diào)度隊(duì)列上刪除,線程在運(yùn)行過(guò)程中發(fā)生阻塞,會(huì)被加入到對(duì)應(yīng)的阻塞隊(duì)列中并觸發(fā)一次調(diào)度,調(diào)度其它線程運(yùn)行。如果調(diào)度隊(duì)列上沒(méi)有可以調(diào)度的線程,則系統(tǒng)就會(huì)選擇KIdle進(jìn)程的線程進(jìn)行調(diào)度運(yùn)行。調(diào)度器OpenHarmonyLiteOS-A內(nèi)核的調(diào)度器模塊提供了調(diào)度相關(guān)的接口。3.調(diào)度器接口功能分類接口名稱描述觸發(fā)系統(tǒng)調(diào)度LOS_Schedule觸發(fā)系統(tǒng)調(diào)度LOS_GetTaskScheduler獲取指定任務(wù)的調(diào)度策略LOS_SetTaskScheduler設(shè)置指定任務(wù)的調(diào)度策略LOS_GetProcessScheduler獲取指定進(jìn)程的調(diào)度策略LOS_SetProcessScheduler設(shè)置指定進(jìn)程的調(diào)度參數(shù),包括優(yōu)先級(jí)和調(diào)度策略調(diào)度器進(jìn)程管理的應(yīng)用,具體代碼如下:
#include<stdio.h>
#include"osal_thread.h"
/**
*@brief輸出“helloohos”函數(shù)
*@paramvoid
*@retvalvoid
*/
voidTask_hello_ohos(void)
{
while(1)
{
printf("Helloohos!!!\r\n");
}
}
/**
*@brief任務(wù)創(chuàng)建函數(shù)
*@paramvoid
*@retvalvoid
*/
調(diào)度器
intmain(intargc,char**argv)
{
structOsalThreadtask_ohos;//ohos任務(wù)ID
structOsalThreadParamtaskoh;//定義ohos任務(wù)結(jié)構(gòu)體
taskoh.stackSize=1028;//任務(wù)堆棧
="Task_hello_ohos";//任務(wù)名稱
taskoh.priority=OSAL_THREAD_PRI_LOW;//任務(wù)優(yōu)先級(jí)
/**創(chuàng)建任務(wù)**/
if(OsalThreadCreate(&task_ohos,Task_hello_ohos,NULL)!=HDF_SUCCESS)
{
printf("task_ohoscreateFailed!\r\n");
}
printf("task_ohoscreatesuccessful!\r\n");
if(OsalThreadStart(&task_ohos,&taskoh)!=HDF_SUCCESS)
{
printf("task_ohosstartFailed!\r\n");
}
printf("task_ohosstartsuccessful!\r\n");}調(diào)度器運(yùn)行結(jié)果如下:謝謝6.1.1
HDF驅(qū)動(dòng)框架介紹通過(guò)本節(jié)學(xué)習(xí),您可以:了解HDF驅(qū)動(dòng)框架HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架介紹:HDF驅(qū)動(dòng)架構(gòu)采用C語(yǔ)言面向?qū)ο缶幊棠P蜆?gòu)建,通過(guò)平臺(tái)解耦、內(nèi)核解耦,來(lái)達(dá)到兼容不同內(nèi)核,統(tǒng)一平臺(tái)底座的目的,從而幫助開發(fā)者實(shí)現(xiàn)驅(qū)動(dòng)一次開發(fā),多系統(tǒng)部署的效果。HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架架構(gòu)組成:OSAL:操作系統(tǒng)抽象層(OperatingSystemAbstractionLayer),提供統(tǒng)一封裝的內(nèi)核操作相關(guān)接口,屏蔽不同系統(tǒng)操作差異,包含內(nèi)存、鎖、線程、信號(hào)量等接口。HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架架構(gòu)組成:1.HDF驅(qū)動(dòng)基礎(chǔ)框架:提供統(tǒng)一的硬件資源管理,驅(qū)動(dòng)加載管理以及設(shè)備節(jié)點(diǎn)管理等功能。驅(qū)動(dòng)框架采用的是主從模式設(shè)計(jì),由DeviceManager和DeviceHost組成。HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架架構(gòu)組成:2.驅(qū)動(dòng)程序:實(shí)現(xiàn)驅(qū)動(dòng)具體的功能,每個(gè)驅(qū)動(dòng)由一個(gè)或者多個(gè)驅(qū)動(dòng)程序組成,每個(gè)驅(qū)動(dòng)程序都對(duì)應(yīng)著一個(gè)DriverEntry。HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架架構(gòu)組成:3.驅(qū)動(dòng)配置文件.hcs:主要由設(shè)備信息(DeviceInformation)和設(shè)備資源(DeviceResource)組成。HDF驅(qū)動(dòng)框架介紹HDF驅(qū)動(dòng)框架架構(gòu)組成:4.驅(qū)動(dòng)接口:HDI(HardwareDriverinterface,硬件設(shè)備接口)提供標(biāo)準(zhǔn)化的接口定義和實(shí)現(xiàn),驅(qū)動(dòng)框架提供IOService和IODispatcher機(jī)制,使得不同部署形態(tài)下驅(qū)動(dòng)接口趨于形式一致。謝謝6.1.2HDF驅(qū)動(dòng)模型介紹通過(guò)本節(jié)學(xué)習(xí),您可以:了解HDF驅(qū)動(dòng)模型HDF驅(qū)動(dòng)模型介紹HDF設(shè)備驅(qū)動(dòng)模型的組成:Host(設(shè)備容器)、Device(設(shè)備)、DeviceNode(設(shè)備節(jié)點(diǎn))、Driver(驅(qū)動(dòng)程序)。HDF框架將一類設(shè)備驅(qū)動(dòng)放在同一個(gè)Host里面,用于管理一組設(shè)備的啟動(dòng)加載等過(guò)程。Device對(duì)應(yīng)一個(gè)真實(shí)的物理設(shè)備。DeviceNode是設(shè)備的一個(gè)部件,Device至少有一個(gè)DeviceNode。每個(gè)DeviceNode可以發(fā)布一個(gè)設(shè)備服務(wù)。每個(gè)DevicdNode唯一對(duì)應(yīng)一個(gè)驅(qū)動(dòng),實(shí)現(xiàn)和硬件的功能交互。HDF驅(qū)動(dòng)模型介紹在劃分Host時(shí),驅(qū)動(dòng)程序是部署在一個(gè)Host還是部署在不同的Host,主要考慮驅(qū)動(dòng)程序之間是否存在耦合性,如果兩個(gè)驅(qū)動(dòng)程序之間存在依賴,可以考慮將這部分驅(qū)動(dòng)程序部署在一個(gè)Host里面。Host有兩種屬性:hostName,priority屬性取值描述hostName字符串設(shè)備集合的名稱。Priority整數(shù),0-200設(shè)備集合的優(yōu)先級(jí)。數(shù)值越大,優(yōu)先級(jí)越低;如果優(yōu)先級(jí)相同,則不能保證加載順序。HDF驅(qū)動(dòng)模型介紹HDF驅(qū)動(dòng)框架給DeviceNode設(shè)備節(jié)點(diǎn)定義的屬性:屬性取值描述moduleName字符串每個(gè)設(shè)備節(jié)點(diǎn)所對(duì)應(yīng)的驅(qū)動(dòng)程序被稱為一個(gè)module,每一個(gè)module都有一個(gè)moduleName。preload整數(shù)驅(qū)動(dòng)被HDF加載的方式Priority整數(shù),0-200驅(qū)動(dòng)的優(yōu)先級(jí)。數(shù)值越大,優(yōu)先級(jí)越低;如果優(yōu)先級(jí)相同,則不能保證加載順序。serviceNamen字符串驅(qū)動(dòng)對(duì)外發(fā)布的服務(wù)的名稱,必須唯一。policy整數(shù)驅(qū)動(dòng)對(duì)外發(fā)布服務(wù)的策略。permission整數(shù)設(shè)備節(jié)點(diǎn)的讀寫權(quán)限,一般采用以0為前綴的8進(jìn)制整數(shù),類似于linux的文件權(quán)限的概念。deviceMatchAttr字符串用于匹配設(shè)備節(jié)點(diǎn)的自定義屬性。HDF驅(qū)動(dòng)模型介紹驅(qū)動(dòng)的加載方式如下:
typedef
enum{
DEVICE_PRELOAD_ENABLE=0,
DEVICE_PRELOAD_ENABLE_STEP2,
DEVICE_PRELOAD_DISABLE,
DEVICE_PRELOAD_INVALID
}DevicePreload;preload字段配置為0(DEVICE_PRELOAD_ENABLE),則系統(tǒng)啟動(dòng)過(guò)程中默認(rèn)加載。preload字段配置為1(DEVICE_PRELOAD_ENABLE_STEP2),當(dāng)系統(tǒng)支持快速啟動(dòng)的時(shí)候,則在系統(tǒng)完成之后再加載這一類驅(qū)動(dòng)。preload字段配置為2(DEVICE_PRELOAD_DISABLE),則系統(tǒng)啟動(dòng)過(guò)程中默認(rèn)不加載。謝謝6.1.3HDF驅(qū)動(dòng)開發(fā)步驟通過(guò)本節(jié)學(xué)習(xí),您可以:了解HDF驅(qū)動(dòng)開發(fā)步驟HDF驅(qū)動(dòng)開發(fā)步驟HDF框架的驅(qū)動(dòng)開發(fā)的組成部分:驅(qū)動(dòng)實(shí)現(xiàn)、驅(qū)動(dòng)編譯腳本編寫和驅(qū)動(dòng)配置。1.驅(qū)動(dòng)實(shí)現(xiàn):驅(qū)動(dòng)實(shí)現(xiàn)包含驅(qū)動(dòng)業(yè)務(wù)代碼實(shí)現(xiàn)和驅(qū)動(dòng)入口注冊(cè),具體寫法如下:(1)驅(qū)動(dòng)業(yè)務(wù)代碼模板
#include"hdf_device_desc.h"http://HDF框架對(duì)驅(qū)動(dòng)開發(fā)相關(guān)能力接口的頭文件
#include"hdf_log.h"http://HDF框架提供的日志接口頭文件
#defineHDF_LOG_TAGtest_driver//打印日志所包含的標(biāo)簽,如果不定義則用默認(rèn)定義的HDF_TAG標(biāo)簽。
//將驅(qū)動(dòng)對(duì)外提供的服務(wù)能力接口綁定到HDF框架。
int32_tHdfTestDriverBind(structHdfDeviceObject*deviceObject){
HDF_LOGD("Testdriverbindsuccess");
returnHDF_SUCCESS;
}
//驅(qū)動(dòng)自身業(yè)務(wù)初始化的接口
int32_tHdfTestDriverInit(structHdfDeviceObject*deviceObject){
HDF_LOGD("TestdriverInitsuccess");
returnHDF_SUCCESS;
}
//驅(qū)動(dòng)資源釋放的接口
voidHdfTestDriverRelease(structHdfDeviceObject*deviceObject){
HDF_LOGD("Testdriverreleasesuccess");
return;
}HDF驅(qū)動(dòng)開發(fā)步驟(2)驅(qū)動(dòng)入口注冊(cè)到HDF框架
structHdfDriverEntryg_testDriverEntry={
.moduleVersion=1,
.moduleName="test_driver",
.Bind=HdfTestDriverBind,
.Init=HdfTestDriverInit,
.Release=HdfTestDriverRelease,
};
//調(diào)用HDF_INIT將驅(qū)動(dòng)入口注冊(cè)到HDF框架中。在加載驅(qū)動(dòng)時(shí)HDF框架會(huì)先調(diào)用Bind函數(shù),再調(diào)用Init函數(shù)加載該驅(qū)動(dòng);當(dāng)Init調(diào)用異常時(shí),HDF框架會(huì)調(diào)用Release釋放驅(qū)動(dòng)資源并退出。
HDF_INIT(g_testDriverEntry);驅(qū)動(dòng)注冊(cè),就是實(shí)例化驅(qū)動(dòng)入口,驅(qū)動(dòng)入口必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量,且moduleName要和device_info.hcs中保持一致。HDF框架會(huì)將所有加載的驅(qū)動(dòng)的HdfDriverEntry對(duì)象首地址匯總,形成一個(gè)類似數(shù)組的段地址空間,方便上層調(diào)用。HDF驅(qū)動(dòng)開發(fā)步驟2.驅(qū)動(dòng)編譯腳本編寫添加模塊BUILD.gn把新增模塊的BUILD.gn所在的目錄添加到上一級(jí)BUILD.gn文件中
import("http://drivers/adapter/khdf/liteos/hdf.gni")
hdf_driver("hdf_led"){
sources=[
"led.c",#此處為點(diǎn)燈實(shí)驗(yàn),根據(jù)實(shí)驗(yàn)進(jìn)行修改
]
include_dirs=[
"http://device/st/drivers/module_driver/Module_Common/inc/",
]}
group("drivers"){
deps=[
"led",#新增模塊BUILD.gn的名稱,根據(jù)實(shí)驗(yàn)進(jìn)行修改
]
}HDF驅(qū)動(dòng)開發(fā)步驟3.驅(qū)動(dòng)配置驅(qū)動(dòng)配置包含兩部分:HDF框架定義的驅(qū)動(dòng)設(shè)備描述和驅(qū)動(dòng)的私有配置信息。(1)驅(qū)動(dòng)設(shè)備描述HDF框架加載驅(qū)動(dòng)所需要的信息來(lái)源于HDF框架定義的驅(qū)動(dòng)設(shè)備描述,因此基于HDF框架開發(fā)的驅(qū)動(dòng)必須要在HDF框架定義的device_info.hcs配置文件中添加對(duì)應(yīng)的設(shè)備描述。
root{
device_info{
match_attr="hdf_manager";HDF驅(qū)動(dòng)開發(fā)步驟
templatehost{//host模板,繼承該模板的節(jié)點(diǎn)(如下test_host)如果使用模板中的默認(rèn)值,則節(jié)點(diǎn)字段可以缺省。
hostName="";
priority=100;
templatedevice{
templatedeviceNode{
policy=0;
priority=100;
preload=0;
permission=0664;
moduleName="";
serviceName="";
deviceMatchAttr="";
}
}
}HDF驅(qū)動(dòng)開發(fā)步驟
platform::host{
hostName="platform_host";//host名稱,host節(jié)點(diǎn)是用來(lái)存放某一類驅(qū)動(dòng)的容器。
priority=50;//host啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證host的加載順序。
device_led::device{//led設(shè)備節(jié)點(diǎn)
device0::deviceNode{//led驅(qū)動(dòng)的DeviceNode節(jié)點(diǎn)
policy=2;//policy字段是驅(qū)動(dòng)服務(wù)發(fā)布的策略
priority=200;//驅(qū)動(dòng)啟動(dòng)優(yōu)先級(jí)(0-200),值越大優(yōu)先級(jí)越低,建議默認(rèn)配100,優(yōu)先級(jí)相同則不保證device的加載順序
preload=0;//驅(qū)動(dòng)按需加載字段
permission=0777;//驅(qū)動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)權(quán)限
moduleName="HDF_LED";//驅(qū)動(dòng)名稱,該字段的值必須和驅(qū)動(dòng)入口結(jié)構(gòu)的moduleName值一致
serviceName="hdf_led";//驅(qū)動(dòng)對(duì)外發(fā)布服務(wù)的名稱,必須唯一
deviceMatchAttr="st_stm32mp157_led";//驅(qū)動(dòng)私有數(shù)據(jù)匹配的關(guān)鍵字,必須和驅(qū)動(dòng)私有數(shù)據(jù)配置表中的match_attr值相等
}
}
}
}}HDF驅(qū)動(dòng)開發(fā)步驟(2)驅(qū)動(dòng)私有配置信息如果驅(qū)動(dòng)有私有配置,則可以添加一個(gè)驅(qū)動(dòng)的配置文件,用來(lái)填寫一些驅(qū)動(dòng)的默認(rèn)配置信息。HDF框架在加載驅(qū)動(dòng)的時(shí)候,會(huì)將對(duì)應(yīng)的配置信息獲取并保存在HdfDeviceObject中的property里面,通過(guò)Bind和Init傳遞給驅(qū)動(dòng)。驅(qū)動(dòng)的配置信息示例如下:配置信息定義之后,需要將該配置文件添加到板級(jí)配置入口文件hdf.hcs,示例如下:
root{
LedDriverConfig{
led_gpio_num=13;
match_attr="st_stm32mp157_led";//該字段的值必須和device_info.hcs中的deviceMatchAttr值一致
}
}
#include"device_info/device_info.hcs"
#include"led/led_config.hcs"
謝謝6.2.1驅(qū)動(dòng)服務(wù)介紹通過(guò)本節(jié)學(xué)習(xí),您可以:了解驅(qū)動(dòng)服務(wù)介紹驅(qū)動(dòng)服務(wù)介紹當(dāng)驅(qū)動(dòng)需要以接口的形式對(duì)外提供能力時(shí),可以使用HDF框架的驅(qū)動(dòng)服務(wù)管理能力。驅(qū)動(dòng)服務(wù)是HDF驅(qū)動(dòng)設(shè)備對(duì)外提供能力的對(duì)象,由HDF框架統(tǒng)一管理。驅(qū)動(dòng)服務(wù)管理主要包含驅(qū)動(dòng)服務(wù)的發(fā)布和獲取。1.驅(qū)動(dòng)服務(wù)的發(fā)布:HDF框架定義了驅(qū)動(dòng)對(duì)外發(fā)布服務(wù)的策略,由配置文件中的policy字段來(lái)控制,policy字段的取值范圍以及含義如下:
typedef
enum{
SERVICE_POLICY_NONE=0,//驅(qū)動(dòng)不提供服務(wù)
SERVICE_POLICY_PUBLIC=1,//驅(qū)動(dòng)對(duì)內(nèi)核態(tài)發(fā)布服務(wù)
SERVICE_POLICY_CAPACITY=2,//驅(qū)動(dòng)對(duì)內(nèi)核態(tài)和用戶態(tài)都發(fā)布服務(wù)
SERVICE_POLICY_FRIENDLY=3,//驅(qū)動(dòng)服務(wù)不對(duì)外發(fā)布服務(wù),但可以被訂閱
SERVICE_POLICY_PRIVATE=4,//驅(qū)動(dòng)私有服務(wù)不對(duì)外發(fā)布服務(wù),也不能被訂閱
SERVICE_POLICY_INVALID//錯(cuò)誤的服務(wù)策略
}ServicePolicy;驅(qū)動(dòng)服務(wù)介紹2.驅(qū)動(dòng)服務(wù)的獲取:驅(qū)動(dòng)服務(wù)的獲取有兩種方式:通過(guò)HDF接口直接獲?。寒?dāng)明確驅(qū)動(dòng)已經(jīng)加載完成時(shí),獲取該驅(qū)動(dòng)的服務(wù)可以通過(guò)HDF框架提供的能力接口直接獲取。通過(guò)HDF提供的訂閱機(jī)制獲?。寒?dāng)內(nèi)核態(tài)對(duì)驅(qū)動(dòng)(同一個(gè)host)加載的時(shí)機(jī)不感知時(shí),可以通過(guò)HDF框架提供的閱機(jī)
制來(lái)訂閱該驅(qū)動(dòng),當(dāng)該驅(qū)動(dòng)加載完成時(shí),HDF框架會(huì)將被訂閱的驅(qū)動(dòng)服務(wù)發(fā)布給訂閱者。謝謝6.2.2驅(qū)動(dòng)服務(wù)管理開發(fā)通過(guò)本節(jié)學(xué)習(xí),您可以:了解驅(qū)動(dòng)服務(wù)管理開發(fā)驅(qū)動(dòng)服務(wù)管理開發(fā)1.驅(qū)動(dòng)服務(wù)管理接口針對(duì)驅(qū)動(dòng)服務(wù)管理功能,HDF框架開放了部分接口給開發(fā)者調(diào)用。方法描述int32_t(*Bind)(structHdfDeviceObject*deviceObject);需要驅(qū)動(dòng)開發(fā)者實(shí)現(xiàn)Bind函數(shù),將自己的服務(wù)接口綁定到HDF框架中conststructHdfObject*DevSvcManagerClntGetService(constchar*svcName);獲取驅(qū)動(dòng)的服務(wù)intHdfDeviceSubscribeService(structHdfDeviceObject*deviceObject,constchar*serviceName,structSubscriberCallbackcallback);訂閱驅(qū)動(dòng)的服務(wù)驅(qū)動(dòng)服務(wù)管理開發(fā)2.驅(qū)動(dòng)服務(wù)管理開發(fā)步驟(1)驅(qū)動(dòng)服務(wù)的編寫驅(qū)動(dòng)服務(wù)管理開發(fā)的第一步是定義驅(qū)動(dòng)的服務(wù)接口。
//驅(qū)動(dòng)服務(wù)結(jié)構(gòu)的定義
structITestDriverService{
structIDeviceIoServiceioService;//服務(wù)結(jié)構(gòu)的首個(gè)成員必須是IDeviceIoService類型的成員
int32_t(*ServiceA)(void);//驅(qū)動(dòng)的第一個(gè)服務(wù)接口
int32_t(*ServiceB)(uint32_tinputCode);//驅(qū)動(dòng)的第二個(gè)服務(wù)接口,有多個(gè)可以依次往下累加
};
驅(qū)動(dòng)服務(wù)接口的實(shí)現(xiàn)
int32_tTestDriverServiceA(void)
{
//驅(qū)動(dòng)開發(fā)者實(shí)現(xiàn)業(yè)務(wù)邏輯
returnHDF_SUCCESS;
}
int32_tTestDriverServiceB(uint32_tinputCode)
{
//驅(qū)動(dòng)開發(fā)者實(shí)現(xiàn)業(yè)務(wù)邏輯
returnHDF_SUCCESS;
}驅(qū)動(dòng)服務(wù)管理開發(fā)(2)驅(qū)動(dòng)服務(wù)綁定驅(qū)動(dòng)服務(wù)綁定到HDF框架中,實(shí)現(xiàn)HdfDriverEntry中的Bind指針函數(shù)。
int32_tTestDriverBind(structHdfDeviceObject*deviceObject)
{
//deviceObject為HDF框架給每一個(gè)驅(qū)動(dòng)創(chuàng)建的設(shè)備對(duì)象,用來(lái)保存設(shè)備相關(guān)的私有數(shù)據(jù)和服務(wù)接口
if(deviceObject==NULL){
HDF_LOGE("Testdeviceobjectisnull!");
returnHDF_FAILURE;
}
static
structITestDriverServicetestDriverA={
.ServiceA=TestDriverServiceA,
.ServiceB=TestDriverServiceB,
};
deviceObject->service=&testDriverA.ioService;
returnHDF_SUCCESS;
}驅(qū)動(dòng)服務(wù)管理開發(fā)(3)驅(qū)動(dòng)服務(wù)獲取通過(guò)HDF接口直接獲?。?/p>
const
structITestDriverService*testService=
(const
structITestDriverService*)DevSvcManagerClntGetService("test_driver");
if(testService==NULL){
returnHDF_FAILURE;
}
testService->ServiceA();testService->ServiceB(5);驅(qū)動(dòng)服務(wù)管理開發(fā)
//object為訂閱者的私有數(shù)據(jù),service為被訂閱的服務(wù)對(duì)象
int32_tTestDriverSubCallBack(structHdfDeviceObject*deviceObject,const
structHdfObject*service)
{
const
structITestDriverService*testService=
(const
structITestDriverService*)service;
if(testService==NULL){
returnHDF_FAILURE;
}
testService->ServiceA();
testService->ServiceB(5);
}通過(guò)HDF提供的訂閱機(jī)制獲?。盒枰帉懹嗛喕卣{(diào)函數(shù),當(dāng)被訂閱的驅(qū)動(dòng)加載完成后,HDF框架會(huì)將被訂閱驅(qū)動(dòng)的服務(wù)發(fā)布給訂閱者,通過(guò)這個(gè)回調(diào)函數(shù)給訂閱者使用。驅(qū)動(dòng)服務(wù)管理開發(fā)
//訂閱過(guò)程的實(shí)現(xiàn)
int32_tTestDriverInit(structHdfDeviceObject*deviceObject)
{
if(deviceObject==NULL){
HDF_LOGE("Testdriverinitfailed,deviceObjectisnull!");
returnHDF_FAILURE;
}
structSubscriberCallbackcallBack;
callBack.deviceObject=deviceObject;
callBack.OnServiceConnected=TestDriverSubCallBack;
int32_tret=HdfDeviceSubscribeService(deviceObject,"test_driver",callBack);
if(ret!=HDF_SUCCESS){
HDF_LOGE("Testdriversubscribetestdriverfailed!");
}
returnret;}謝謝6.3.1驅(qū)動(dòng)消息機(jī)制管理通過(guò)本節(jié)學(xué)習(xí),您可以:了解驅(qū)動(dòng)消息機(jī)制管理驅(qū)動(dòng)消息機(jī)制管理鴻蒙系統(tǒng)的的HDF框架提供了統(tǒng)一的驅(qū)動(dòng)消息機(jī)制。當(dāng)用戶態(tài)應(yīng)用和內(nèi)核態(tài)驅(qū)動(dòng)需要交互時(shí),可以使用HDF框架的消息機(jī)制來(lái)實(shí)現(xiàn)。用戶態(tài):指應(yīng)用程序運(yùn)行的環(huán)境,應(yīng)用程序在用戶態(tài)下運(yùn)行,可以訪問(wèn)系統(tǒng)資源,如文件、網(wǎng)絡(luò)等。用戶態(tài)下的應(yīng)用程序運(yùn)行在受限的環(huán)境中,不能直接訪問(wèn)系統(tǒng)硬件資源,必須通過(guò)系統(tǒng)調(diào)用來(lái)請(qǐng)求內(nèi)核提供服務(wù)。內(nèi)核態(tài):指操作系統(tǒng)內(nèi)核運(yùn)行的環(huán)境,在操作系統(tǒng)啟動(dòng)時(shí),內(nèi)核被加載到內(nèi)存中,并開始執(zhí)行。消息機(jī)制的功能有以下兩種:用戶態(tài)應(yīng)用發(fā)送消息到驅(qū)動(dòng)。用戶態(tài)應(yīng)用接收驅(qū)動(dòng)主動(dòng)上報(bào)事件。驅(qū)動(dòng)消息機(jī)制管理消息機(jī)制的接口:接口描述structHdfIoService*HdfIoServiceBind(constchar*serviceName)用戶態(tài)獲取驅(qū)動(dòng)的服務(wù),獲取該服務(wù)之后通過(guò)服務(wù)中的Dispatch方法向驅(qū)動(dòng)發(fā)送消息voidHdfIoServiceRecycle(structHdfIoService*service);獲取驅(qū)動(dòng)的服務(wù)intHdfDeviceRegisterEventListener(structHdfIoService*target,structHdfDevEventlistener*listener);用戶態(tài)程序注冊(cè)接收驅(qū)動(dòng)上報(bào)事件的操作方法intHdfDeviceSendEvent(structHdfDeviceObject*deviceObject,uint32_tid,structHdfSBuf*data);驅(qū)動(dòng)主動(dòng)上報(bào)事件接口謝謝6.3.2驅(qū)動(dòng)消息機(jī)制開發(fā)通過(guò)本節(jié)學(xué)習(xí),您可以:了解驅(qū)動(dòng)消息機(jī)制開發(fā)驅(qū)動(dòng)消息機(jī)制開發(fā)驅(qū)動(dòng)消息機(jī)制的開發(fā)步驟:1.修改服務(wù)策略policy字段將驅(qū)動(dòng)配置信息中服務(wù)策略policy字段設(shè)置為2。
device_test::Device{
policy=2;
...
}2.配置驅(qū)動(dòng)信息中的服務(wù)設(shè)備節(jié)點(diǎn)權(quán)限配置驅(qū)動(dòng)信息中的服務(wù)設(shè)備節(jié)點(diǎn)權(quán)限(permission字段)是框架給驅(qū)動(dòng)創(chuàng)建設(shè)備節(jié)點(diǎn)的權(quán)限,默認(rèn)是0666,驅(qū)動(dòng)開發(fā)者根據(jù)驅(qū)動(dòng)的實(shí)際使用場(chǎng)景配置驅(qū)動(dòng)設(shè)備節(jié)點(diǎn)的權(quán)限。驅(qū)動(dòng)消息機(jī)制開發(fā)3.實(shí)現(xiàn)Dispatch方法在服務(wù)實(shí)現(xiàn)過(guò)程中,實(shí)現(xiàn)服務(wù)基類成員IDeviceIoService中的Dispatch方法。
//Dispatch是用來(lái)處理用戶態(tài)發(fā)下來(lái)的消息
int32_tTestDriverDispatch(structHdfDeviceIoClient*device,intcmdCode,structHdfSBuf*data,structHdfSBuf*reply){
HDF_LOGE("testdriverliteAdispatch");
returnHDF_SUCCESS;
}
int32_tTestDriverBind(structHdfDeviceObject*device){
HDF_LOGE("testforliteostestdriverAOpen!");
if(device==NULL){
HDF_LOGE("testforliteostestdriverAOpenfailed!");
returnHDF_FAILURE;
}
static
structITestDriverServicetestDriverA={
.ioService.Dispatch=TestDriverDispatch,
.ServiceA=TestDriverServiceA,
.ServiceB=TestDriverServiceB,
};
device->service=(structIDeviceIoService*)(&testDriverA);
returnHDF_SUCCESS;}驅(qū)動(dòng)消息機(jī)制開發(fā)4.定義cmd類型驅(qū)動(dòng)定義消息處理函數(shù)中的cmd類型。5.獲取服務(wù)接口并發(fā)送消息用戶態(tài)獲取服務(wù)接口并發(fā)送消息到驅(qū)動(dòng)。#defineTEST_WRITE_READ1//讀寫操作碼1
intSendMsg(const
char*testMsg)
{
if(testMsg==NULL){
HDF_LOGE("testmsgisnull");
returnHDF_FAILURE;
}
structHdfIoService*serv=HdfIoServiceBind("test_driver");
if(serv==NULL){
HDF_LOGE("failtogetservice");
returnHDF_FAILURE;}驅(qū)動(dòng)消息機(jī)制開發(fā)
structHdfSBuf*data=HdfSBufObtainDefaultSize();
if(data==NULL){HDF_LOGE("failtoobtainsbufdata");
returnHDF_FAILURE;
}
structHdfSBuf*reply=HdfSBufObtainDefaultSize();
if(reply==NULL){HDF_LOGE("failtoobtainsbufreply");
ret=HDF_DEV_ERR_NO_MEMORY;
gotoout;
}
if(!HdfSbufWriteString(data,testMsg)){HDF_LOGE("failtowritesbuf");
ret=HDF_FAILURE;
gotoout;
}
intret=serv->dispatcher->Dispatch(&serv->object,TEST_WRITE_READ,data,reply);
if(ret!=HDF_SUCCESS){HDF_LOGE("failtosendservicecall");
gotoout;
}
out:
HdfSBufRecycle(data);
HdfSBufRecycle(reply);
HdfIoServiceRecycle(serv);
returnret;}驅(qū)動(dòng)消息機(jī)制開發(fā)6.用戶態(tài)接收驅(qū)動(dòng)上報(bào)的消息用戶態(tài)編寫驅(qū)動(dòng)上報(bào)消息的處理函數(shù)。
static
intOnDevEventReceived(void*priv,uint32_tid,structHdfSBuf*data)
{
OsalTimespectime;
OsalGetTime(&time);
HDF_LOGE("%sreceivedeventat%llu.%llu",(char*)priv,time.sec,time.usec);
const
char*string=HdfSbufReadString(data);
if(string==NULL){
HDF_LOGE("failtoreadstringineve
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 項(xiàng)目托管合同范例
- 飯店引流合同范例簡(jiǎn)短
- app推廣服務(wù)合同范例
- 購(gòu)銅合同范例
- 合同范例神器
- 化妝培訓(xùn)員工合同范例
- 裝修材料合同合同范例
- 學(xué)校托管采購(gòu)合同范例
- 銷售合同范例建陶
- 員工入職檔案合同范例
- 珠寶店應(yīng)急預(yù)案范本
- 有限空間作業(yè)安全管理協(xié)議
- 勞務(wù)派遣方案
- 介紹河南的英文課件演講
- 道路綠化養(yǎng)護(hù)投標(biāo)方案(技術(shù)方案)
- 跨省戶口網(wǎng)上遷移告知單
- 屋面工程質(zhì)量控制
- 高中英語(yǔ)校本教材《英語(yǔ)美文閱讀與欣賞》
- 【高中語(yǔ)文】《鄉(xiāng)土中國(guó)-家族》課件19張+統(tǒng)編版必修上冊(cè)
- 二年級(jí)上冊(cè)英語(yǔ)說(shuō)課稿-Module 4 Unit 2 He doesn't like these trousers|外研社(一起)
- 重型燃?xì)廨啓C(jī)
評(píng)論
0/150
提交評(píng)論