第11章 任務(wù)管理_第1頁
第11章 任務(wù)管理_第2頁
第11章 任務(wù)管理_第3頁
第11章 任務(wù)管理_第4頁
第11章 任務(wù)管理_第5頁
已閱讀5頁,還剩81頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、溫州大學(xué)物理與電子信息工程學(xué)院 楊衛(wèi)波嵌入式系統(tǒng)原理與應(yīng)用第11章 任務(wù)管理11.1 單任務(wù)系統(tǒng)p裸機(jī)編程主要是采用超級循環(huán)(super-loops)系統(tǒng),又稱前后臺系統(tǒng)。p應(yīng)用程序是一個(gè)無限的循環(huán),循環(huán)中調(diào)用相應(yīng)的函數(shù)完成相應(yīng)的操作,這部分可以看做后臺行為,中斷服務(wù)程序處理異步事件,這部分可以看做是前臺行為。11.1.1 查詢方式p處理器查詢數(shù)據(jù)或者消息是否就緒,就緒后進(jìn)行處理,然后再等待,如此循環(huán)下去。p處理簡單的應(yīng)用,效果比較好,但是隨著工程的復(fù)雜,采用查詢方式實(shí)現(xiàn)的工程就變的很難維護(hù),同時(shí)由于無法定義查詢?nèi)蝿?wù)的優(yōu)先級,這種查詢方式會使得重要的接口消息得不到及時(shí)響應(yīng)。11.1.2 中斷方

2、式p必須在中斷(ISR)內(nèi)處理時(shí)間關(guān)鍵運(yùn)算;p超級循環(huán)和ISR之間的數(shù)據(jù)交換是通過全局共享變量進(jìn)行的;p超級循環(huán)使得應(yīng)用程序變得非常復(fù)雜,因此難以擴(kuò)展。11.2 多任務(wù)系統(tǒng)p調(diào)度器的作用就是使用相關(guān)的調(diào)度算法調(diào)度算法來決定當(dāng)前需要執(zhí)行的任務(wù);p這里所說的多任務(wù)系統(tǒng)同一時(shí)刻只能有一個(gè)任務(wù)可以運(yùn)行,只是通過調(diào)度器的決策,看起來像所有任務(wù)同時(shí)運(yùn)行一樣。多任務(wù)系統(tǒng)運(yùn)行過程運(yùn)行條件如下: p使用搶占式調(diào)度器p1個(gè)空閑任務(wù),優(yōu)先級最低p2個(gè)應(yīng)用任務(wù),一個(gè)高優(yōu)先級和一個(gè)低優(yōu)先級,優(yōu)先級都比空閑任務(wù)優(yōu)先級高p中斷服務(wù)程序含USB 中斷、串口中斷和系統(tǒng)滴答定時(shí)器中斷11.3.1 任務(wù)設(shè)置RTX 操作系統(tǒng)的配置工

3、作是通過配置文件 RTX_Conf_CM.c 實(shí)現(xiàn)11.3.2 任務(wù)棧設(shè)置不管是裸機(jī)編程還是RTOS編程,局部變量、函數(shù)調(diào)時(shí)現(xiàn)場保護(hù)和返回地址、函數(shù)的形參、進(jìn)入中斷函數(shù)前和中斷嵌套等都需要棧空間,??臻g定義小了會造成系統(tǒng)崩潰。 裸機(jī)的情況下,用戶可以在這里配置棧大小:任務(wù)棧設(shè)置在RTOS下,每個(gè)任務(wù)都有自己的??臻g。任務(wù)的棧大小可以在配置向?qū)е型ㄟ^如下參數(shù)進(jìn)行配置:11.3.3 系統(tǒng)棧設(shè)置pRTOS下圖中設(shè)置的棧有一個(gè)新的名字叫系統(tǒng)??臻g系統(tǒng)??臻g,任務(wù)棧不使用這里的??臻g,使用這里的??臻g的是中斷函數(shù)和中斷嵌套。pCortex-M3內(nèi)核具有雙堆棧指針,在RTX操作系統(tǒng)中,主堆棧指針主堆棧指針

4、MSPMSP是給系統(tǒng)??臻g使用的,進(jìn)程堆棧指針進(jìn)程堆棧指針PSPPSP是給任務(wù)棧使用的。11.3.5 RTX初始化和啟動voidvoid os_sys_init_user( os_sys_init_user(voidvoid( (* *task)(task)(voidvoid),),/ /* * 任務(wù)函數(shù) */U8 priority, U8 priority, / /* * 任務(wù)優(yōu)先級 (1-254) */voidvoid* * stack, stack, / /* * 任務(wù)棧地址 */U16 size); U16 size); / /* * 任務(wù)棧大小,單位字節(jié)*/ 函數(shù)描述:實(shí)現(xiàn)RTX的初

5、始化和啟動任務(wù)的創(chuàng)建,并且使用這個(gè)函數(shù)做初始化還可以自定義任務(wù)棧的大小。 注意:1)優(yōu)先級0用于空閑任務(wù),如果將其設(shè)置為0,RTX會將其更改為1。優(yōu)先級255被保留用于最重要的任務(wù)。優(yōu)先級參數(shù)中數(shù)值越小優(yōu)先級越低,也就是說空閑任務(wù)的優(yōu)先級是最低的。 2)必須在main函數(shù)中調(diào)用os_sys_init_useros_sys_init_user; 3)任務(wù)棧空間必須 8 字節(jié)對齊。舉例staticstatic uint64_t uint64_t AppTaskStartStkAppTaskStartStk512/8; 512/8; / /* * 任務(wù)棧任務(wù)棧 * */ /intint main(

6、main(voidvoid) ) / /* * RTX RTX初始化并創(chuàng)建啟動任務(wù)初始化并創(chuàng)建啟動任務(wù) */os_sys_init_useros_sys_init_user( (AppTaskStartAppTaskStart, , / /* * 任務(wù)函數(shù)任務(wù)函數(shù) */ 4, 4, / /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */ & &AppTaskStartStkAppTaskStartStk, ,/ /* * 任務(wù)棧任務(wù)棧 */ sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); / /* * 任務(wù)棧大小,單位字節(jié)數(shù)任務(wù)棧大小,單位字節(jié)數(shù) */

7、while while (1); (1); 11.3.6 任務(wù)創(chuàng)建OS_TID os_tsk_create_user(OS_TID os_tsk_create_user(voidvoid( (* *task)(task)(voidvoid), ), / /* * 任務(wù)函數(shù) */U8 priority, U8 priority, / /* * 任務(wù)優(yōu)先級 (1-254) */voidvoid* * stk, stk, / /* * 任務(wù)棧*/U16 size); U16 size); / /* * 任務(wù)棧大小*/函數(shù)描述:實(shí)現(xiàn)RTX任務(wù)創(chuàng)建,還可以自定義任務(wù)棧的大小。 注意:1)如果新創(chuàng)建的任務(wù)

8、優(yōu)先級比當(dāng)前正在執(zhí)行任務(wù)的優(yōu)先級高,那么就會立即切換到高優(yōu)先級任務(wù)去執(zhí)行; 2)函數(shù)的返回值是任務(wù)的ID,使用ID號可以區(qū)分不同的任務(wù)。 3)任務(wù)??臻g必須8字節(jié)對齊,可將任務(wù)棧數(shù)組定義成uint64_tuint64_t類型即可。舉例staticstatic uint64_t AppTaskUserIFStk512 / 8; uint64_t AppTaskUserIFStk512 / 8; / /* * 任務(wù)棧 */OS_TID HandleTaskUserIF = NULL;OS_TID HandleTaskUserIF = NULL; / /* * 任務(wù)句柄 */staticstatic

9、 voidvoid AppTaskCreate( AppTaskCreate(voidvoid) ) HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, / /* * 任務(wù)函數(shù) */ 1, 1, / /* * 任務(wù)優(yōu)先級 */ &AppTaskUserIFStk, &AppTaskUserIFStk, / /* * 任務(wù)棧 */ sizeofsizeof(AppTaskUserIFStk); (AppTaskUserIFStk); ty

10、pedef unsigned int U32;typedef U32 OS_TID;11.3.7 任務(wù)刪除OS_RESULT os_tsk_delete (OS_TID task_id); OS_RESULT os_tsk_delete (OS_TID task_id); /* 任務(wù)ID */ 函數(shù)描述:實(shí)現(xiàn)RTX操作系統(tǒng)的任務(wù)刪除。如果任務(wù)刪除成功,函數(shù)返回OS_R_OKOS_R_OK,其余情況返回 OS_R_NOKOS_R_NOK,比如所寫的任務(wù)ID不存在。注意:如果用往此函數(shù)里面填的任務(wù)ID是 0 的話,那么刪除的就是當(dāng)前正在執(zhí)行的任務(wù),此任務(wù)被刪除后,RTX會切換到任務(wù)就緒列表里面下一

11、個(gè)要執(zhí)行的高優(yōu)先級任務(wù)。任務(wù)刪除例子staticstatic uint64_t uint64_t AppTaskUserIFStkAppTaskUserIFStk512 / 8; 512 / 8; / /* * 任務(wù)棧任務(wù)棧 */OS_TID OS_TID HandleTaskUserIFHandleTaskUserIF = NULL; = NULL;staticstatic voidvoid AppTaskDeleteAppTaskDelete( (voidvoid) ) HandleTaskUserIFHandleTaskUserIF = = os_tsk_create_useros_ts

12、k_create_user(AppTaskUserIF, (AppTaskUserIF, / /* * 任務(wù)函數(shù)任務(wù)函數(shù) */1, 1, / /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */& &AppTaskUserIFStkAppTaskUserIFStk, , / /* * 任務(wù)棧任務(wù)棧 */sizeofsizeof( (AppTaskUserIFStkAppTaskUserIFStk); ); / /* * 任務(wù)棧大小任務(wù)棧大小*/ifif ( (HandleTaskUserIFHandleTaskUserIF != NULL) != NULL) ifif ( (os_tsk_deleteos_t

13、sk_delete( (HandleTaskUserIFHandleTaskUserIF) = OS_R_OK) = OS_R_OK) HandleTaskUserIFHandleTaskUserIF = NULL; = NULL;printf(printf( 任務(wù)任務(wù)HandleTaskUserIF刪除成功刪除成功rn);); elseelse printfprintf( ( 任務(wù)任務(wù)HandleTaskUserIF刪除失敗刪除失敗rn); ); 11.3.8 空閑任務(wù)幾乎所有的小型RTOS中都有一個(gè)空閑任務(wù),空閑任務(wù)應(yīng)該屬于系統(tǒng)任務(wù),是必須要執(zhí)行的,用戶程序不能將其關(guān)閉。比如WIN7中有空

14、閑任務(wù),空閑任務(wù)主要有以下幾個(gè)作用作用: p不能讓系統(tǒng)一直在執(zhí)行各個(gè)應(yīng)用任務(wù),這樣系統(tǒng)利用率就是100%,系統(tǒng)就會一直的超負(fù)荷運(yùn)行,所以空閑任務(wù)很有必要。p為了更好的實(shí)現(xiàn)低功耗,用戶可以在空閑任務(wù)中實(shí)現(xiàn)睡眠,停機(jī)等低功耗措施??臻e任務(wù)RTX 的空閑任務(wù)在文件RTX_Conf_CM.c 里面,源代碼如下: / /* *- os_idle_demon - os_idle_demon -* */ /_task _task voidvoid os_idle_demon( os_idle_demon(voidvoid) ) / /* * The idle demon is a system task,

15、running when no other task is ready The idle demon is a system task, running when no other task is ready to run. The os_xxx function calls are not allowed from this task. to run. The os_xxx function calls are not allowed from this task. * */ /forfor (;) (;) / /* * HERE: include optional user code to

16、 be executed when no task HERE: include optional user code to be executed when no task runs. runs.* */ / 11.3.9 例程說明目的:目的: 學(xué)習(xí) RTX 的任務(wù)創(chuàng)建和刪除。內(nèi)容:內(nèi)容: 1. K1 按鍵按下,串口打印。 2. K2 按鍵按下,刪除任務(wù) AppTaskLED。 3. K3 按鍵按下,重新創(chuàng)建任務(wù) AppTaskLED。 4. 各個(gè)任務(wù)實(shí)現(xiàn)的功能如下: AppTaskUserIF 任務(wù) :按鍵消息處理。 AppTaskLED 任務(wù) :LED 閃爍。 AppTaskMsgPro

17、任務(wù) :消息處理,用作 LED 閃爍。 AppTaskStart 任務(wù):啟動任務(wù),最高優(yōu)先級最高優(yōu)先級任務(wù),實(shí)現(xiàn)按鍵掃描。 RTX 配置應(yīng)用實(shí)例RTX RTX 初始化:初始化:intint main( main(voidvoid) ) bsp_Initbsp_Init();(); / /* * 初始化外設(shè)初始化外設(shè) */ /* * 創(chuàng)建啟動任務(wù)創(chuàng)建啟動任務(wù) */os_sys_init_useros_sys_init_user( (AppTaskStartAppTaskStart, , / /* * 任務(wù)函數(shù)任務(wù)函數(shù) */ 4, 4, / /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */ & &AppTas

18、kStartStkAppTaskStartStk, , / /* * 任務(wù)棧 */ sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); / /* * 任務(wù)棧大小任務(wù)棧大小 */ whilewhile (1); (1); static uint64_t AppTaskUserIFStk512/8; static uint64_t AppTaskLEDStk256/8; static uint64_t AppTaskMsgProStk512/8; static uint64_t AppTaskStartStk512/8; 應(yīng)用實(shí)例RTX RTX 任

19、務(wù)創(chuàng)建:任務(wù)創(chuàng)建:staticstatic voidvoid AppTaskCreateAppTaskCreate( (voidvoid) ) HandleTaskUserIFHandleTaskUserIF = = os_tsk_create_useros_tsk_create_user(AppTaskUserIF,(AppTaskUserIF, 1, 1, / /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */ & &AppTaskUserIFStkAppTaskUserIFStk, , / /* * 任務(wù)棧任務(wù)棧 */ sizeofsizeof( (AppTaskUserIFStkAppTaskUse

20、rIFStk); ); HandleTaskLEDHandleTaskLED = = os_tsk_create_useros_tsk_create_user( (AppTaskLEDAppTaskLED, , 2, 2, / /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */ & &AppTaskLEDStkAppTaskLEDStk, , / /* * 任務(wù)棧任務(wù)棧 */ sizeofsizeof( (AppTaskLEDStkAppTaskLEDStk); ); HandleTaskMsgProHandleTaskMsgPro = = os_tsk_create_useros_tsk_create_u

21、ser( (AppTaskMsgProAppTaskMsgPro, , 3, 3,/ /* * 任務(wù)優(yōu)先級任務(wù)優(yōu)先級 */ & &AppTaskMsgProStkAppTaskMsgProStk, , / /* * 任務(wù)棧任務(wù)棧 */ sizeofsizeof( (AppTaskMsgProStkAppTaskMsgProStk); ); RTX 任務(wù)調(diào)試信息思考題1:30嵌入式系統(tǒng)原理與應(yīng)用24用用RTX實(shí)現(xiàn):實(shí)現(xiàn): 按下按下Key1時(shí),時(shí), LED每每1s閃爍閃爍5次,再次按下次,再次按下Key1時(shí),時(shí),LED停止閃爍;依次循環(huán)停止閃爍;依次循環(huán)。#include#include incl

22、udes.hincludes.h staticstatic uint64_t uint64_t AppTaskStartStkAppTaskStartStk512/8; 512/8; / /* * 任務(wù)棧任務(wù)棧 * */ /staticstatic uint64_t uint64_t AppTaskKEYStkAppTaskKEYStk256/8; 256/8; / /* * 任務(wù)棧任務(wù)棧 * */ /_task _task voidvoid AppTaskKEYAppTaskKEY( (voidvoid) ) whilewhile(1) (1) bsp_KeyScanbsp_KeyScan(

23、);();os_dly_waitos_dly_wait(10);(10); _task _task voidvoid AppTaskStartAppTaskStart( (voidvoid) ) uint8_t uint8_t ucKeyCodeucKeyCode, , bLedTogglebLedToggle = 1; = 1;os_tsk_create_useros_tsk_create_user( (AppTaskKEYAppTaskKEY, 2, &, 2, &AppTaskKEYStkAppTaskKEYStk, , sizeofsizeof( (AppTaskKEYStkAppTa

24、skKEYStk););whilewhile(1) (1) ucKeyCodeucKeyCode = = bsp_GetKeybsp_GetKey();();ifif ( (ucKeyCodeucKeyCode = KEY_DOWN_K1) = KEY_DOWN_K1)bLedTogglebLedToggle = 1 - = 1 - bLedTogglebLedToggle; ; ifif( (bLedTogglebLedToggle = 1) = 1)bsp_LedTogglebsp_LedToggle(1);(1); os_dly_waitos_dly_wait(100);(100); i

25、ntint main ( main (voidvoid) ) bsp_Initbsp_Init();();os_sys_init_useros_sys_init_user ( (AppTaskStartAppTaskStart, 4, &, 4, &AppTaskStartStk,AppTaskStartStk,sizeofsizeof( (AppTaskStartStkAppTaskStartStk); ); whilewhile(1);(1); RTX內(nèi)核分析p 進(jìn)程是對一個(gè)運(yùn)行單元的抽象,主要包括內(nèi)存(code,data,heap和stack),CPU狀態(tài)(PC,SP和寄存器值等)與其他

26、OS管理相關(guān)的內(nèi)容。進(jìn)程是一個(gè)運(yùn)行中的程序。在RTX中一個(gè)task就是一個(gè)進(jìn)程。p 一般有一個(gè)進(jìn)程控制塊(Process control block,PCB),用于記錄進(jìn)程的相關(guān)信息。RTX中這個(gè)控制塊叫做task control block(TCBTCB),是一個(gè)結(jié)構(gòu)體,其中的成員記錄了關(guān)于該task的信息,其定義在rt_TypeDef.h中。RTX任務(wù)控制塊typedeftypedef structstruct OS_TCB OS_TCB / /* * General part: identical for all implementations. General part: identi

27、cal for all implementations. * */ /U8 cb_type; U8 cb_type; / /* *內(nèi)存塊內(nèi)存塊IDID號,號,RTXRTX鏈表操作非常靈活性,傳遞參數(shù)時(shí)多用鏈表操作非常靈活性,傳遞參數(shù)時(shí)多用OS_XCBOS_XCB類型指針類型指針 * */ /U8 state; U8 state; / /* * 任務(wù)狀態(tài)任務(wù)狀態(tài)* */ /U8 prio; U8 prio; / /* * 優(yōu)先級,優(yōu)先級,RTXRTX的互斥量使用優(yōu)先級繼承,此為繼承后優(yōu)先級的互斥量使用優(yōu)先級繼承,此為繼承后優(yōu)先級 * */ /U8 task_id; U8 task_id; / /

28、* *通過通過TIDTID快速訪問快速訪問TCBTCB,所有激活任務(wù)都注冊到任務(wù)數(shù)組中,所有激活任務(wù)都注冊到任務(wù)數(shù)組中,TIDTID就是下標(biāo)就是下標(biāo) * */ /structstruct OS_TCBOS_TCB * *p_lnk; p_lnk; / /* * 互斥量、信號量、郵箱等待雙向鏈表下個(gè)節(jié)點(diǎn)指針;就緒任務(wù)單鏈表下個(gè)節(jié)點(diǎn)指針;互斥量、信號量、郵箱等待雙向鏈表下個(gè)節(jié)點(diǎn)指針;就緒任務(wù)單鏈表下個(gè)節(jié)點(diǎn)指針;* */ /structstruct OS_TCBOS_TCB * *p_rlnk; p_rlnk; / /* * 雙向鏈表中的上個(gè)節(jié)點(diǎn)指針雙向鏈表中的上個(gè)節(jié)點(diǎn)指針 * */ /struct

29、struct OS_TCBOS_TCB * *p_dlnk; p_dlnk; / /* * 延時(shí)任務(wù)雙向鏈表,下個(gè)節(jié)點(diǎn)指針延時(shí)任務(wù)雙向鏈表,下個(gè)節(jié)點(diǎn)指針 * */ / structstruct OS_TCBOS_TCB * *p_blnk; p_blnk; / /* * 上個(gè)節(jié)點(diǎn)指針上個(gè)節(jié)點(diǎn)指針 * */ / U16 delta_time; U16 delta_time; / /* * 任務(wù)延時(shí)時(shí),如任務(wù)延時(shí)時(shí),如4 4任務(wù)延時(shí)任務(wù)延時(shí)1010、9090、9090、120120后,各任務(wù)的后,各任務(wù)的delta_timedelta_time為:為:0 0,8080,0 0,3030* */ /

30、 U16 interval_time; U16 interval_time; / /* * 區(qū)間延時(shí),為周期性延時(shí)用區(qū)間延時(shí),為周期性延時(shí)用 * */ /U16 events; U16 events; / /* *TCBTCB的事件標(biāo)志,每個(gè)任務(wù)有的事件標(biāo)志,每個(gè)任務(wù)有1616個(gè)事件標(biāo)志個(gè)事件標(biāo)志 * */ /U16 waits; U16 waits; / /* * 等待事件被阻塞時(shí),暫存此處;事件或等待成功時(shí)保存實(shí)際等待到的事件等待事件被阻塞時(shí),暫存此處;事件或等待成功時(shí)保存實(shí)際等待到的事件 * */ /voidvoid * * *msg; msg; / /* *郵箱操作阻塞時(shí),暫存接收或發(fā)

31、送消息的地址郵箱操作阻塞時(shí),暫存接收或發(fā)送消息的地址 * */ / structstruct OS_MUCBOS_MUCB * *p_mlnk; p_mlnk; / /* * 任務(wù)擁有的互斥量鏈表頭節(jié)點(diǎn)任務(wù)擁有的互斥量鏈表頭節(jié)點(diǎn) * */ /U8 prio_base; U8 prio_base; / /* *基本優(yōu)先級,未繼承前的優(yōu)先級基本優(yōu)先級,未繼承前的優(yōu)先級 * */ / U8 ret_val; U8 ret_val; / /* *任務(wù)被同步量阻塞時(shí),同時(shí)進(jìn)入同步量等待鏈表和延時(shí)等待鏈表,此處指示應(yīng)用程序從哪個(gè)任務(wù)被同步量阻塞時(shí),同時(shí)進(jìn)入同步量等待鏈表和延時(shí)等待鏈表,此處指示應(yīng)用程序從哪

32、個(gè) 等待鏈表返回等待鏈表返回 * */ / /* * Hardware dependant part: specific for CM processor Hardware dependant part: specific for CM processor* */ /U8 ret_upd; U8 ret_upd; / /* * 返回值更新標(biāo)記,替換返回值更新標(biāo)記,替換R0R0值為值為ret_val ret_val * */ /U16 priv_stack; U16 priv_stack; / /* * 僅在任務(wù)初始化時(shí)指示是否使用自定義棧僅在任務(wù)初始化時(shí)指示是否使用自定義棧* */ / U32

33、 tsk_stack; U32 tsk_stack; / /* * (R13) (R13)任務(wù)任務(wù)SPSP保存在此處保存在此處* */ /U32 U32 * *stack; stack; / /* * 任務(wù)棧的基址任務(wù)棧的基址 * */ /FUNCP ptask; FUNCP ptask; / /* * 任務(wù)入口任務(wù)入口* */ / * *P_TCB;P_TCB;Task States in RTX Kernel1:30嵌入式系統(tǒng)原理與應(yīng)用29RTX中的各種鏈表1:30嵌入式系統(tǒng)原理與應(yīng)用30RTX系統(tǒng)服務(wù)實(shí)現(xiàn)RTX進(jìn)程創(chuàng)建的源代碼OS_TID rt_tsk_create (FUNCP OS_

34、TID rt_tsk_create (FUNCP tasktask, U32 , U32 prio_stkszprio_stksz, , voidvoid * *stkstk, , voidvoid * *argvargv) ) / /* * Start a new task declared with task. Start a new task declared with task. * */ / P_TCB task_context; P_TCB task_context; U32 i; U32 i; ifif ( (prio_stkszprio_stksz & 0 xFF) = 0)

35、& 0 xFF) = 0) / /* * Priority 0 is reserved for idle task! Priority 0 is reserved for idle task! * */ / prio_stkszprio_stksz += 1; += 1; task_context = rt_alloc_box (mp_tcb); task_context = rt_alloc_box (mp_tcb); ifif (task_context = NULL) (task_context = NULL) returnreturn (0); (0); / /* * If size

36、!= 0 use a private user provided stack. If size != 0 use a private user provided stack. * */ / task_context-stack = task_context-stack = stkstk; ; task_context-priv_stack = task_context-priv_stack = prio_stkszprio_stksz 8; 8; / /* * Pass parameter argv to rt_init_context Pass parameter argv to rt_in

37、it_context * */ / task_context-msg = task_context-msg = argvargv; ; / /* * For size = 0 system allocates the user stack from the memory pool. For size = 0 system allocates the user stack from the memory pool. * */ / rt_init_context (task_context, rt_init_context (task_context, prio_stkszprio_stksz &

38、 0 xFF, & 0 xFF, tasktask);); / /* * Find a free entry in os_active_TCB table. Find a free entry in os_active_TCB table. * */ / i = rt_get_TID (); i = rt_get_TID (); os_active_TCBi-1 = task_context; os_active_TCBi-1 = task_context; task_context-task_id = i; task_context-task_id = i; DBG_TASK_NOTIFY(

39、task_context, _TRUE); DBG_TASK_NOTIFY(task_context, _TRUE); rt_dispatch (task_context); rt_dispatch (task_context); os_tsk.run-ret_val = i; os_tsk.run-ret_val = i; returnreturn (OS_TID)i); (OS_TID)i); 基本就是填TCB,分配內(nèi)存空間,確定優(yōu)先級和排程相關(guān)設(shè)置等。11.4 任務(wù)優(yōu)先級修改RTX操作系統(tǒng)任務(wù)優(yōu)先級的設(shè)置要注意以下幾個(gè)問題: 1)設(shè)置任務(wù)的優(yōu)先級時(shí),數(shù)值越小優(yōu)先級越低。2)最低任務(wù)優(yōu)先級

40、是0,此優(yōu)先級被空閑任務(wù)使用,任何其它任務(wù)都不可以使用。3)用戶可設(shè)置的優(yōu)先級范圍是1-254,由于RTX支持時(shí)間片調(diào)度,也支持用戶任務(wù)設(shè)置為相同的優(yōu)先級。4)優(yōu)先級255被保留,用于最重要的任務(wù)。11.4.2 任務(wù)優(yōu)先級分配方案RTXRTX有一個(gè)任務(wù)優(yōu)先級推薦的設(shè)置標(biāo)準(zhǔn):有一個(gè)任務(wù)優(yōu)先級推薦的設(shè)置標(biāo)準(zhǔn):u IRQ任務(wù):通過中斷服務(wù)程序進(jìn)行觸發(fā)的任務(wù),應(yīng)設(shè)置為優(yōu)先級最高的。u 高優(yōu)先級后臺任務(wù):如按鍵檢測、USB消息處理、串口消息處理等。u 低優(yōu)先級的時(shí)間片調(diào)度任務(wù):如界面顯示、LED顯示等不需要實(shí)時(shí)執(zhí)行的都可以歸為這一類任務(wù)。u 空閑任務(wù):空閑任務(wù)是系統(tǒng)任務(wù)。u 特別注意:IRQ任務(wù)和高優(yōu)先

41、級任務(wù)必須設(shè)置為阻塞式(調(diào)用消息等待或者延遲等函數(shù)),只有這樣高優(yōu)先級任務(wù)才會釋放CPU的使用權(quán),低優(yōu)先級任務(wù)才有機(jī)會得到執(zhí)行。RTX的優(yōu)先度p RTX并不能處理快速中斷,相反地當(dāng)快速中斷發(fā)生時(shí),RTX內(nèi)核可能會被打斷。p 普通中斷并不是一個(gè)進(jìn)程,所以不需要設(shè)定優(yōu)先度,但普通中斷一定會打斷進(jìn)程。p 每一個(gè)優(yōu)先級都有一個(gè)先入先出的隊(duì)列結(jié)構(gòu);進(jìn)程會按照先入先出的順序運(yùn)行。低優(yōu)先度的進(jìn)程不能打斷高優(yōu)先度的進(jìn)程,但高優(yōu)先度的進(jìn)程會打斷低優(yōu)先度的進(jìn)程。如果當(dāng)前最高優(yōu)先度是x,但所有優(yōu)先度為x的進(jìn)程都處于等待狀態(tài),那么排程器就會考慮下一優(yōu)先度(x-1)的進(jìn)程,但一旦任一x進(jìn)程進(jìn)入就緒狀態(tài),排程器會打斷低優(yōu)

42、先度進(jìn)程。RTX的優(yōu)先度p 優(yōu)先度為0的進(jìn)程為空閑進(jìn)程。當(dāng)沒有進(jìn)程執(zhí)行時(shí),RTX會執(zhí)行它,并提升其優(yōu)先度到1;p 幾個(gè)特殊進(jìn)程的優(yōu)先度:os_idle_demon(void) 的優(yōu)先度永遠(yuǎn)為0,RTX實(shí)在沒進(jìn)程可跑才會運(yùn)行這個(gè)進(jìn)程;os_error (U32 err_code)的優(yōu)先度永遠(yuǎn)為255,用于處理錯(cuò)誤的。這兩個(gè)進(jìn)程原型都在RTX_CONFIG.C文件中。1:30嵌入式系統(tǒng)原理與應(yīng)用36RTX中斷處理下圖顯示了RTX中斷處理的過程,IRQ中斷函數(shù)可以發(fā)送信號或消息啟動一個(gè)更高優(yōu)先級的任務(wù)。11.4.3 任務(wù)優(yōu)先級設(shè)置OS_RESULT os_tsk_prio( OS_TID task_

43、id, /* 任務(wù)ID */ U8 new_prio); /* 新的任務(wù)優(yōu)先級 (1-254) */函數(shù)描述函數(shù)描述:用于修改任務(wù)的優(yōu)先級。 p 第1個(gè)參數(shù)如是0,那么設(shè)置就是當(dāng)前任務(wù)的優(yōu)先級。p 如果new_prio的數(shù)值比當(dāng)前執(zhí)行任務(wù)的優(yōu)先級大,將觸發(fā)一次任務(wù)切換,切換到任務(wù)ID為task_id的任務(wù)中。如果new_pro的數(shù)值比當(dāng)前執(zhí)行任務(wù)的優(yōu)先級小,當(dāng)前任務(wù)會繼續(xù)執(zhí)行。p 如果任務(wù)優(yōu)先級修改成功,函數(shù)返回 OS_R_OK,其余情況返回 OS_R_NOK,比如所寫的任務(wù)ID不存在或者任務(wù)還沒有啟動。p 被修改任務(wù)的新優(yōu)先級會一直保持有效直到用戶再次修改。使用舉例staticstatic

44、uint64_t AppTaskUserIFStk512 / 8; uint64_t AppTaskUserIFStk512 / 8; / /* * 任務(wù)棧 */OS_TID HandleTaskUserIF = NULL;OS_TID HandleTaskUserIF = NULL; / /* * 任務(wù)句柄 */staticstatic voidvoid AppTaskDelete( AppTaskDelete(voidvoid) ) HandleTaskUserIF = os_tsk_create_user(AppTaskUserIF, HandleTaskUserIF = os_tsk_

45、create_user(AppTaskUserIF, / /* * 任務(wù)函數(shù) */1, 1, / /* * 任務(wù)優(yōu)先級 */&AppTaskUserIFStk, &AppTaskUserIFStk, / /* * 任務(wù)棧 */sizeofsizeof(AppTaskUserIFStk); (AppTaskUserIFStk); / /* * 任務(wù)棧大小,單位字節(jié)數(shù) */ ifif (os_tsk_prio(HandleTaskLED, 3) = OS_R_OK) (os_tsk_prio(HandleTaskLED, 3) = OS_R_OK) printf(printf( 任務(wù)AppTask

46、LED優(yōu)先級修改成功rn);); elseelse printf(printf( 任務(wù)AppTaskLED優(yōu)先級修改失敗rn);); 11.4.4 例程說明內(nèi)容: 1. K1 按鍵按下,串口打印。2. K2 按鍵按下,將任務(wù) AppTaskLED 的優(yōu)先級由 2 修改為 3。3. k3 按鍵按下,將任務(wù) AppTaskLED 的優(yōu)先級由 3 修改為 2。4. 各個(gè)任務(wù)實(shí)現(xiàn)的功能如下: AppTaskUserIF 任務(wù):按鍵消息處理。 AppTaskLED 任務(wù):LED 閃爍。 AppTaskMsgPro 任務(wù):消息處理,用作 LED 閃爍。 AppTaskStart 任務(wù):啟動任務(wù),也是最高優(yōu)

47、先級任務(wù),這里實(shí)現(xiàn)按鍵掃描。 RTX 配置RTX 配置任務(wù)棧大小分配:static uint64_t AppTaskUserIFStk512/8; /* 任務(wù)棧 */ static uint64_t AppTaskLEDStk256/8; /* 任務(wù)棧 */ static uint64_t AppTaskMsgProStk512/8; /* 任務(wù)棧 */ static uint64_t AppTaskStartStk512/8; /* 任務(wù)棧 */系統(tǒng)棧大小分配RTX 任務(wù)調(diào)試信息11.5 任務(wù)調(diào)度p調(diào)度器就是使用相關(guān)的調(diào)度算法來決定當(dāng)前需要執(zhí)行的任務(wù)。所有的調(diào)度器有一個(gè)共同的特性:調(diào)度器可以

48、區(qū)分就緒態(tài)任務(wù)和掛起任務(wù)。p調(diào)度器可以選擇就緒態(tài)中的一個(gè)任務(wù),然后激活它(通過執(zhí)行這個(gè)任務(wù))。不同調(diào)度器之間最大的區(qū)別就是如何分配就緒態(tài)任務(wù)間的完成時(shí)間。p嵌入式實(shí)時(shí)操作系統(tǒng)的核心就是調(diào)度器和任務(wù)切換,調(diào)度器的核心就是調(diào)度算法。11.5.1 RTX 支持的調(diào)度方式RTX操作系統(tǒng)支持三種調(diào)度方式: p 搶占式調(diào)度:每個(gè)任務(wù)都有不同不同的優(yōu)先級,任務(wù)會一直運(yùn)行直到被高優(yōu)先級任務(wù)搶占或遇到阻塞式的API函數(shù),如 os_dly_waitos_dly_wait。p 時(shí)間片調(diào)度:每個(gè)任務(wù)都有相同相同的優(yōu)先級,任務(wù)會運(yùn)行固定的時(shí)間片個(gè)數(shù)直到遇到系統(tǒng)阻塞式的API函數(shù),如os_dly_waitos_dly_w

49、ait。p 合作式調(diào)度:每個(gè)任務(wù)都有相同的優(yōu)先級,而且時(shí)間片調(diào)度要被禁止。任務(wù)會一直的運(yùn)行直到遇到阻塞式的API函數(shù),如 os_dly_waitos_dly_wait或者用戶調(diào)用函數(shù)os_tsk_passos_tsk_pass。對于RTX操作系統(tǒng)而言,實(shí)際應(yīng)用主要是搶占式調(diào)度和時(shí)間片調(diào)度,合作式調(diào)度用到的很少。11.5.2 搶占式調(diào)度器p 在實(shí)際的應(yīng)用中,不同的任務(wù)需要不同的響應(yīng)時(shí)間。如在一個(gè)應(yīng)用中需要使用電機(jī)、鍵盤和 LCD 顯示。電機(jī)比鍵盤和 LCD 需要更快速的響應(yīng),如果我們使用合作式調(diào)度器或者時(shí)間片調(diào)度,那么電機(jī)將無法得到及時(shí)的響應(yīng),這時(shí)搶占式調(diào)度是必須的。 p 如果使用了搶占式調(diào)度,

50、最高優(yōu)先級的任務(wù)一旦就緒,總能得到 CPU 的控制權(quán)。當(dāng)一個(gè)運(yùn)行著的任務(wù)被其它高優(yōu)先級的任務(wù)搶占,當(dāng)前任務(wù)的 CPU 使用權(quán)就被剝奪了,或者說被掛起了,那個(gè)高優(yōu)先級的任務(wù)立刻得到了 CPU 的控制權(quán)。搶占式調(diào)度器p 如果是中斷服務(wù)程序使一個(gè)高優(yōu)先級的任務(wù)進(jìn)入就緒態(tài),中斷完成時(shí),被中斷的任務(wù)被掛起,優(yōu)先級高的任務(wù)開始運(yùn)行。 p 使用搶占式調(diào)度器,使得最高優(yōu)先級的任務(wù)什么時(shí)候可以執(zhí)行,可以得到 CPU 的控制權(quán)是可知的,同時(shí)使得任務(wù)級響應(yīng)時(shí)間得以最優(yōu)化。 p 總的來說,學(xué)習(xí)搶占式調(diào)度掌握最關(guān)鍵的一點(diǎn)是:搶占式調(diào)度器會為每個(gè)任務(wù)都分配一個(gè)優(yōu)先級,調(diào)度器會激活就緒任務(wù)中優(yōu)先級最高的任務(wù),并運(yùn)行任務(wù)就緒

51、列表里面優(yōu)先級最高的那個(gè)任務(wù)。RTX 搶占式調(diào)度器的實(shí)現(xiàn)如禁止使用時(shí)間片調(diào)度,每個(gè)任務(wù)必須配置不同的優(yōu)先級。多任務(wù)啟動后: p首先執(zhí)行的最高優(yōu)先級的任務(wù)Task1,Task1會一直運(yùn)行直到遇到系統(tǒng)阻塞式的API函數(shù),比如延遲、事件標(biāo)志等待、信號量等待,Task1任務(wù)會被掛起,也就是釋放CPU的執(zhí)行權(quán),讓低優(yōu)先級的任務(wù)得到執(zhí)行。pRTX 操作系統(tǒng)繼續(xù)執(zhí)行任務(wù)就緒列表中下一個(gè)最高優(yōu)先級的任務(wù)Task2,執(zhí)行過程中有兩種情況:uTask1延遲時(shí)間到,接收到信號量消息等方面的原因,在搶占式調(diào)度器的作用下,Task2的執(zhí)行會被Task1搶占。uTask2會一直運(yùn)行直到遇到系統(tǒng)阻塞式的API函數(shù),比如延遲

52、,事件標(biāo)志等待,信號量等待,Task2任務(wù)會被掛起,繼而執(zhí)行就緒列表中下一個(gè)最高優(yōu)先級的任務(wù)。p根據(jù)搶占式調(diào)度器,當(dāng)前的任務(wù)要么被高優(yōu)先級任務(wù)搶占,要么通過調(diào)用阻塞式API來釋放CPU使用權(quán)讓低優(yōu)先級任務(wù)執(zhí)行,沒有用戶任務(wù)執(zhí)行時(shí)就執(zhí)行空閑任務(wù)。RTX 搶占式調(diào)度器的實(shí)現(xiàn)Task1 的優(yōu)先級為 1,Task2 的優(yōu)先級為 2,Task3 的優(yōu)先級為 3。運(yùn)行過程描述如下: pTask1在運(yùn)行中,由于Task2就緒,Task2 搶占Task1的執(zhí)行。Task2 進(jìn)入到運(yùn)行態(tài),Task1由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。pTask2在運(yùn)行中,由于Task3就緒,Task3 搶占Task2的執(zhí)行。Task3進(jìn)入到

53、運(yùn)行態(tài),Task2由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。pTask3運(yùn)行過程中調(diào)用了阻塞式函數(shù),如os_dly_wait,Task3被掛起,查找到下一個(gè)要執(zhí)行的最高優(yōu)先級任務(wù)是Task2,Task2由就緒態(tài)進(jìn)入到運(yùn)行態(tài)。 pTask2在運(yùn)行中,由于Task3再次就緒,Task3搶占Task2的執(zhí)行。Task3進(jìn)入到運(yùn)行態(tài),Task2由運(yùn)行態(tài)進(jìn)入到就緒態(tài)。11.5.3 時(shí)間片調(diào)度器 在小型的嵌入式 RTOS 中,最常用的的時(shí)間片調(diào)度算法就是 Round-robin 調(diào)度算法。實(shí)現(xiàn) Round-robin 調(diào)度算法需要給同優(yōu)先級的每個(gè)任務(wù)分配一個(gè)時(shí)間片(也就是需要運(yùn)行的時(shí)間長度,時(shí)間片用完了就進(jìn)行任務(wù)切換)。pR

54、ound-Robin Task switching選擇是否使能時(shí)間片調(diào)度,選上單選框表示使能時(shí)間片調(diào)度,取消單選框表示不使用時(shí)間片調(diào)度。pRound-Robin Timeout ticks 范圍 1 1000。表示時(shí)間片的大小,單位是系統(tǒng)時(shí)鐘節(jié)拍個(gè)數(shù)。時(shí)間片調(diào)度器p創(chuàng)建 4 個(gè)同優(yōu)先級任務(wù) Task1,Task2,Task3 和 Task4。p每個(gè)任務(wù)分配的時(shí)間片大小是 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍。運(yùn)行過程描述如下: p先運(yùn)行任務(wù) Task1,運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過時(shí)間片調(diào)度切換到任務(wù) Task2。p任務(wù) Task2 運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過時(shí)間片調(diào)度切換到任務(wù) Task3。p任

55、務(wù) Task3 在運(yùn)行期間調(diào)用了阻塞式 API 函數(shù),調(diào)用函數(shù)時(shí),5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍的時(shí)間片大小還沒有用完,此時(shí)會通過時(shí)間片調(diào)度切換到下一個(gè)任務(wù) Task4。p任務(wù) Task4 運(yùn)行夠 5 個(gè)系統(tǒng)時(shí)鐘節(jié)拍后,通過時(shí)間片調(diào)度切換到任務(wù) Task1。時(shí)間片調(diào)度器例程1. K1 按鍵按下,串口打印。2. 本實(shí)驗(yàn)將任務(wù) AppTaskLED 和 AppTaskMsgPro 的優(yōu)先級都設(shè)置為 2,同優(yōu)先級的任務(wù)才會用到時(shí)間片調(diào)度。3. 時(shí)間片調(diào)度的使能和每個(gè)任務(wù)時(shí)間片的大小在文件 RTX_Conf_CM.c 文件里面:#define OS_ROBIN 1 /使能時(shí)間片調(diào)度#define OS_ROBIN

56、TOUT 5 /設(shè)置每個(gè)同優(yōu)先級任務(wù)的時(shí)間片大小。4. 各個(gè)任務(wù)實(shí)現(xiàn)的功能如下:AppTaskUserIF 任務(wù):按鍵消息處理。AppTaskLED 任務(wù) :LED 閃爍。AppTaskMsgPro 任務(wù):消息處理,這里用作 LED 閃爍。 AppTaskStart 任務(wù):啟動任務(wù),最高優(yōu)先級任務(wù),實(shí)現(xiàn)按鍵掃描。RTX 配置系統(tǒng)棧大小分配RTX任務(wù)調(diào)試信息11.5.4 合作式調(diào)度器 對于同優(yōu)先級的任務(wù),如果將 RTX 系統(tǒng)配置向?qū)е袝r(shí)間片調(diào)度關(guān)閉后,這些同優(yōu)先級的任務(wù)就是在合作式調(diào)度器的作用下運(yùn)行。這些同優(yōu)先級的任務(wù)會依次執(zhí)行,每個(gè)任務(wù)會一直執(zhí)行直到遇到阻塞式 API 函數(shù)或者函數(shù) os_ts

57、k_pass ()就會切換到下個(gè)任務(wù)。創(chuàng)建 4 個(gè)同優(yōu)先級任務(wù) Task1,Task2,Task3 和 Task4。運(yùn)行過程描述如下: p先運(yùn)行 Task1,然后調(diào)用阻塞式 API 切換到 Task2。p Task2 運(yùn)行,然后調(diào)用阻塞式 API 切換到任務(wù) Task3。p Task3 運(yùn)行,然后調(diào)用阻塞式 API 切換到任務(wù) Task4。p任務(wù) Task4 運(yùn)行,然后調(diào)用阻塞式 API 重新切換回任務(wù) Task1。p一直如此循環(huán)往復(fù)下去。11.5.5 合作式調(diào)度器例程1. K1按鍵按下,串口打印。2. 將任務(wù) AppTaskLED 和 AppTaskMsgPro 的優(yōu)先級都設(shè)置為 2,同優(yōu)先

58、級的任務(wù)才會用到合作式調(diào)度。3. 使用合作式調(diào)度的話,在 RTX 操作系統(tǒng)的配置向?qū)募TX_Conf_CM.c 中禁止時(shí)間片調(diào)度: #define OS_ROBIN 04. 各個(gè)任務(wù)實(shí)現(xiàn)的功能如下:AppTaskUserIF 任務(wù) :按鍵消息處理。AppTaskLED 任務(wù):LED 閃爍。AppTaskMsgPro 任務(wù) :消息處理,這里用作 LED 閃爍。 AppTaskStart 任務(wù):啟動任務(wù),最高優(yōu)先級任務(wù),實(shí)現(xiàn)按鍵掃描。RTX 配置RTX 任務(wù)調(diào)試信息RTX的調(diào)度總結(jié)1.pre-emptivepre-emptive:每一個(gè)進(jìn)程都有不同的優(yōu)先級,最高優(yōu)先級的進(jìn)程會運(yùn)行,排程器不會終

59、止它,所以它會運(yùn)行直到它自行中止掛起(blocked),或者被更高優(yōu)先級的進(jìn)程打斷。自行掛起的辦法就三個(gè):os_tsk_pass(); os_dly_wait(delay_time);和os_itv_wait(void);如果其被中止掛起,其余優(yōu)先級最高的進(jìn)程會運(yùn)行。2.Round robinRound robin:每一個(gè)進(jìn)程的優(yōu)先級都是相同,每一個(gè)進(jìn)程都會被分配到一個(gè)時(shí)間片,在運(yùn)行完這個(gè)時(shí)間片后,該進(jìn)程就會加入優(yōu)先級相同隊(duì)列的末端,然后隊(duì)列最前端的進(jìn)程繼續(xù)運(yùn)行。3.Co-operativeCo-operative:這個(gè)是所有進(jìn)程都是相同的優(yōu)先度且除能了輪轉(zhuǎn)式排程。 在這種合作模式下,進(jìn)程不會

60、被排程器掛起,只能自己中止。1:30嵌入式系統(tǒng)原理與應(yīng)用59思考題(不同優(yōu)先級下的調(diào)度)AppTaskUserIF(優(yōu)先級1)AppTaskStart(優(yōu)先級4)現(xiàn)象搶占式調(diào)度bsp_Delayus(10)os_dly_wait(10)os_dly_wait(10)bsp_Delayus(10)1:30嵌入式系統(tǒng)原理與應(yīng)用60思考題(不同優(yōu)先級下的調(diào)度)AppTaskUserIF(優(yōu)先級1)AppTaskStart(優(yōu)先級4)現(xiàn)象時(shí)間片調(diào)度bsp_Delayus(10)os_dly_wait(10)os_dly_wait(10)bsp_Delayus(10)1:30嵌入式系統(tǒng)原理與應(yīng)用61思考

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論