




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
RAW-OSRTOS,RAW-OSForFun的產(chǎn)物。其豐富的內(nèi)核特計(jì),以及創(chuàng)新的設(shè)計(jì)足以和目前任何主流商業(yè)RTOS可睥睨。特性,中斷下半部特性(work_queue工作隊(duì)列),基于idle任務(wù)的觸發(fā)機(jī)制,block,byte,page,malloc,slab五種方式的內(nèi)存對(duì)于本文檔內(nèi)容和例程,不懂,請(qǐng)到下面提問: : Raw-os 硬件平臺(tái) 正點(diǎn)原子STM32F4探索者開發(fā)開發(fā)環(huán)境 :存放ST標(biāo)準(zhǔn)的固件庫(kù)。 下面又有extension :用戶程序,下面的s子 存放所有用戶的s命令實(shí)現(xiàn)。 :存放FATFS,LWIP等第協(xié)議棧源碼。(RAW_U8INIT_TASK_STK_SIZE,voidInit_Task_Func(voidOK,創(chuàng)建一個(gè)任務(wù)基本上就這些東西了,注意,上面代碼是了任務(wù)執(zhí)行函數(shù),當(dāng)然還需要實(shí)現(xiàn)它。完整代碼參見例程1。RTOSRTOS啟動(dòng)之前不允許產(chǎn)生任何硬api,api在初始化硬件中voidInit_Task_Func(void{//1.InitialalltheusedHardware//2.Createother}置Systick的中斷頻率:SysTick_Config(SystemCoreClock/ 表示OS的時(shí)鐘周期為10ms。Raw-os支持時(shí)間片輪轉(zhuǎn)調(diào)度,多個(gè)任務(wù)可以設(shè)置相同的優(yōu)先級(jí),從理論上的USART1(PA9,PA10兩個(gè)引腳)到電腦串口,波特率為115200。另外,本文檔后面的例程,包括s,都需要在SecureCRT這個(gè)軟件下使各打印10次語(yǔ)句,當(dāng)任務(wù)的時(shí)間片到時(shí),即被系統(tǒng)CPU使用權(quán)轉(zhuǎn)而運(yùn)行////voidFirst_Task(void*{intfor(i=0;i<10;i{ //翻轉(zhuǎn)LED1}}//voidSecond_Task(void*{intfor(i=0;i<10;i{ //翻轉(zhuǎn)LED2}}10次語(yǔ)句,兩個(gè)任務(wù)都沒有主動(dòng)去放棄CPU使用權(quán),但由于具有相同的優(yōu)先級(jí),那么當(dāng)?shù)谝粋€(gè)任務(wù)在執(zhí)行過程中其時(shí)間片到時(shí),會(huì)被系統(tǒng)CPU控制權(quán),轉(zhuǎn)而運(yùn)行第二個(gè)任務(wù),第二個(gè)任務(wù)在執(zhí) tasktime 實(shí)驗(yàn)結(jié)果:LED進(jìn)行多次翻轉(zhuǎn),按理說是按下一次,釋放一次信號(hào)量,LED只翻轉(zhuǎn)一次的,那是什么原因呢?當(dāng)然是因?yàn)榘磩?wù)執(zhí)行了多次,所以LED也翻轉(zhuǎn)多次。//// {2.3.}raw_enter_interrupt()和raw_finish_int()是在中斷服務(wù)程序的開始和退出處s詳RAW-OSS使用一種簡(jiǎn)單、易用、高效的機(jī)制使得應(yīng)用程序支持命令行護(hù)一個(gè)單向鏈表,新加入令依次掛help這個(gè)鏈表頭后面,當(dāng)在應(yīng)用層面,比如串口終端中,輸入命令時(shí),執(zhí)行s 解析的任務(wù)會(huì)這個(gè)命令,并通過mand()函數(shù)從單鏈表頭開始查找這個(gè)命令是否已(掛接到命統(tǒng)令列表中進(jìn)行比對(duì),從而識(shí)別這個(gè)命令。S機(jī)制的實(shí)現(xiàn)需要依賴串口,所以在本例中,工程如下你用時(shí)候,你會(huì)愛上s的。首先分析下一個(gè)命令體所對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)類型,rsh.htypedeftypedefstruct{constRAW_S8*const constRAW_S8*const RAW_S8} 第二項(xiàng)pcHelpString是這個(gè)命令對(duì)應(yīng)的使用說明。 typedeftypedefRAW_S32xWriteBufferLen,constRAW_S8mandString pcWriteBuffermandString:用戶輸入的整個(gè)命令行(參數(shù)從此命令行中提取eg:添加一個(gè)打印Raw-os內(nèi)核版本version命令: {(constRAW_S8(constRAW_S8*)"version: gettheRaw-oskernelversion.",0命令名為version.gettheRaw-oskernel命令的執(zhí)行函數(shù)實(shí)現(xiàn)如下version命令回調(diào):RAW-OSKernelstaticRAW_S32get_os_version(RAW_S8*pcWriteBuffer,RAW_U32xWriteBufferLen,constRAW_S8*const {RAW_U8version[6]=//raw_strcat((char*)pcWriteBuffer,(char*)"RAW-OSVersion:");version[0]=RAW_OS_VERSION/1000+0X30;version[1]=version[2]=RAW_OS_VERSION%1000/100+0X30;version[3]=RAW_OS_VERSION%100/10+0X30;version[4]=RAW_OS_VERSION%10+0X30;version[5]=return//}((RAW_S8*pcWriteBuffer,RAW_U32xWriteBufferLen,constRAW_S8*const pcWriteBuffer 2.這個(gè)新mand(constxCommandLineInput*mandToRegister,xCommandLineInputListItem點(diǎn)到系統(tǒng)中,代碼如下: 會(huì)打印出這個(gè)命令,當(dāng)然,僅是以此例作為s使用說明,在本例程中,實(shí)際上我們是以控制LED為例,添加了另外四個(gè)命令,輸入help如下:以此四個(gè)命令為例說明了不帶參數(shù)令使用方法和帶參數(shù)令注冊(cè)使用方法,上面命令中的led命令有兩個(gè)參數(shù),其命令體如下:led開關(guān), const{(constRAW_S8(constRAW_S8*)"led:<lednumber><onoroff>lednumber(1,2),on(1),off(0).", 2pParameter=(RAW_S8 pParameter=(RAW_S8 rsh_get_parameter函數(shù)的第一個(gè)參數(shù)就是你輸入令字符串,第二個(gè)參數(shù) 關(guān)于s 機(jī)制令體定義,命令部分更具體的內(nèi)容請(qǐng)讀者查看源碼定義一個(gè)鏈表結(jié)點(diǎn)結(jié)構(gòu)體類型和幾個(gè)API函數(shù)的使用啦,外加一點(diǎn)點(diǎn)鏈表知識(shí)。在本節(jié)繼續(xù)向系統(tǒng)了幾個(gè)命令,包括打印內(nèi)核版本號(hào),打印MCU查看內(nèi)核版本令version和查看MCUID令chip_id命令執(zhí)行還有個(gè)stack命令則是本節(jié)重點(diǎn)要介紹的,先輸入執(zhí)行下試試看:可以看到系統(tǒng)此時(shí)只有兩個(gè)任務(wù):idle_task和s_taskidle_task是系統(tǒng)必須有的一個(gè)任務(wù),而stask即為我們創(chuàng)建的s任務(wù)。RTOS使用當(dāng)中經(jīng)常遇到的問題,有時(shí)候莫名其妙的程序就跑飛HardFault_Handler中,這種情況很有可能就是棧空間溢出了,解決問題的方一個(gè)命令stack則可以動(dòng)態(tài)實(shí)時(shí)的查看系統(tǒng)中所有運(yùn)行的任務(wù)的??臻g使用情臺(tái)一個(gè)字是4個(gè)字節(jié))。/*enable/*enablesystemzero#define#defineCONFIG_RAW_TASK_0111即統(tǒng)計(jì)任務(wù),然后重新編譯程序,,然后重新執(zhí)行stack命令,查看結(jié)果如級(jí)為0的task_0任務(wù)和統(tǒng)計(jì)任務(wù)。同時(shí)可查看他們的任務(wù)??臻g剩余。述,對(duì)stack命令令體定義,等不在列出,下面分析下其代碼實(shí)現(xiàn):staticstaticRAW_S32 mand(RAW_S8*pcWriteBuffer,size_txWriteBufferLen,constRAW_S8* {LISTRAW_U32 1.task_debugiter=/*doituntillistpointerisbacktotheoriginalwhile(iter!=&(raw_task_debug.task_head))2.task_debug =iter-3.task_debugtask_iter=raw_list_entry(iter,RAW_TASK_OBJ,//4.獲取該任務(wù)的剩余??臻g,存在 5.Uart_Printf("tasknameis%15s***task stacksizeis%d\r\n",task_iter->task_name,stack_ /*move/*movetolistnext*/iter=iter_temp;}return}stack1,2,3,4,5寫的很清stack命令的時(shí)候,就會(huì)遍歷這個(gè)鏈表,獲得每一raw_task_stack_check函數(shù),分析源碼發(fā)現(xiàn)該函數(shù)支持兩種增長(zhǎng)模while(*task_stack++==0) }用,_stk變量即最終得到的剩余棧大小。RAW-OS系統(tǒng)中實(shí)現(xiàn)??臻g檢測(cè)的原理,更深入的研究分析請(qǐng)查看本節(jié)例程原碼和RAW-OS源碼。然而,raw-os4種任務(wù)棧溢出的檢測(cè),大部分時(shí)候防患于未然,是最好的方式。只要在raw_config.h里面打開宏定義12%的整體空間的raw-os一家提供了這種任務(wù)棧的檢測(cè)機(jī)制。具體的代碼可以參考raw_idle.c不再細(xì)述。Raw-os提供了定時(shí)器給用戶去使用。軟件定時(shí)器的代碼在raw_timer.c里面。使用的時(shí)候需要打開raw_config.h中的CONFIG_RAW_TIMER和定時(shí)器的精度有raw_config.h里的RAW_TIMER_RATE去定義使用,具體的軟件定時(shí)器的頻率可以有:舉一個(gè)例子,RAW_TICKS_PER_SECOND為100,10,那說明軟件定時(shí)器的頻率是一秒10次,即一次是100ms軟件定時(shí)器的實(shí)現(xiàn)有一個(gè)系統(tǒng)開啟的任務(wù)去實(shí)現(xiàn),這個(gè)任務(wù)就是#if#if(CONFIG_RAW_TIMER>/*settimertaskstacksize,adjustasyouneed*/#defineTIMER_STACK_SIZE#define5tick時(shí)間,有的人把系統(tǒng)定時(shí)器的頻率開得很大,比如1000Hz,這樣對(duì)于系統(tǒng)損耗很大,對(duì)于100MHz以下的cpu,推薦50Hz或者更小。如果系統(tǒng)中不存rawos//// 創(chuàng)建軟件定時(shí)器,安裝回調(diào)函數(shù),////周期為2個(gè)ticks,即20msKey_Timer_Function,0,100,2,{{case{//0,1,2////{Key_State //}}case{//{釋放信號(hào)量(喚醒阻塞在該信號(hào)量上的最高優(yōu)先級(jí)任務(wù))Key_State OK狀態(tài)(等待松開}{釋放信號(hào)量(喚醒阻塞在該信號(hào)量上的最高優(yōu)先級(jí)任務(wù)Key_State OK狀態(tài)(等待松開}{釋放信號(hào)量(喚醒所有阻塞在該信號(hào)量上的任務(wù))Key_StateState_Press_OKOK狀態(tài)(等待松開}{Key_State //}}case{//if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2)&&GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)){Key_State //}}}return}個(gè)LED都翻轉(zhuǎn)。Raw-os消息系統(tǒng)提供的機(jī)制有很多:queue,mqueue,queue_size,queue是最基本的消息模塊了(消息在程序中的體現(xiàn)為一個(gè)指向用戶數(shù)據(jù)的兩種機(jī)制是可以合起來(lái)的,在發(fā)送消息的同時(shí)也發(fā)送消息大小嘛,Raw-os分開queue_buffercopy到其內(nèi)部緩沖(FIFO),copy出來(lái),這適用于某些特殊的情況mqueuequeue的特殊改進(jìn),即是對(duì)發(fā)送的消息進(jìn)行優(yōu)先級(jí)排序,緊急還是所有的任務(wù)?Post喚醒一個(gè)任務(wù)具體又是什么情況?/*enable/*enableSCHED_FIFOandSCHED_RR#define1提供不同的API供用戶選用。LED的不同狀態(tài),實(shí)際的程序引入了等待u8 voidTask_Queue_Fun(void*{RAW_U16RAW_U32timeout_value=500;signedchar*msg;{res=raw_queue_receive(&Key_Queue,timeout_value,ifRAW_BLOCK_TIMEOUTres {}elseifRAW_SUCCESS {if(0==raw_strncmp((constchar*)msg,"KEY0",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY1",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY2",4){}}}}消息到隊(duì)列中,任務(wù)接收后打印出消息內(nèi)容,并根據(jù)內(nèi)容控制LED翻轉(zhuǎn)。queue_sizequeue這個(gè)新的數(shù)組結(jié)構(gòu)名為RAW_MSG_SIZE,其定義如下:typedeftypedefstructRAW_MSG_SIZEstruct }指向用戶發(fā)送數(shù)據(jù)段的指針void*msg_ptr,和用戶數(shù)據(jù)段的大小msg_size。RAW_QUEUE_SIZERAW_QUEUE_SIZE raw_queue_size_createraw_queue_size_create(&Key_Queue,"KEY_QUEUE",key_queue,voidvoidMSG_SIZE_TYPE“KEY2123”三則消息到隊(duì)列中,創(chuàng)建一個(gè)任務(wù)平時(shí)阻塞在消息上,一旦有消voidTask_Queue_Size_Fun(void*{RAW_U16RAW_U32timeout_value=500; void*msg; //消息指針MSG_SIZE_TYPE {if(RAW_BLOCK_TIMEOUT==res{}elseifRAW_SUCCESS {if(0==raw_strncmp((constchar*)msg,"KEY0",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY1",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY2",4){}}}}針,queue_sizequeue_buffer不在轉(zhuǎn)存消息的指針,而是將消息copy一份到用戶空間,也即轉(zhuǎn)發(fā)消息內(nèi)容和消息大小。RAW_QUEUE_BUFFERRAW_QUEUE_BUFFER 其中queue_buffer數(shù)組即為Key_Queue內(nèi)部的一個(gè)順序隊(duì)列(此順序隊(duì)即copy到這個(gè)順序隊(duì)列中,創(chuàng)建隊(duì)列如下:1024*4,voidvoidMSG_SIZE_TYPE隊(duì)列中內(nèi)容,并根據(jù)內(nèi)容來(lái)控制LED的不同狀態(tài),實(shí)際的程序引入了等待voidTask_Queue_Buffer_Fun(void*{RAW_U16RAW_U32timeout_value=500個(gè)時(shí)鐘周期,RAW_U8RAW_U8MSG_SIZE_TYPEraw_memset(msg,0,{if(RAW_BLOCK_TIMEOUT==res{}elseifRAW_SUCCESS {if(0==raw_strncmp((constchar*)msg,"KEY0",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY1",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY2",4){}}}}數(shù)據(jù)長(zhǎng)度,這也和queue_buffer的內(nèi)部數(shù)據(jù),copy等實(shí)現(xiàn)機(jī)制有關(guān),具體此問題作一個(gè)形像的演示,在下兩節(jié)將說明采用mutex來(lái)解決此問題。在本例程序中了lcd_test命令,請(qǐng)首先保證LCD驅(qū)動(dòng)程序正確,LCD設(shè)備的時(shí)候,會(huì)被高優(yōu)先級(jí)任務(wù)搶占,這樣造成LCD設(shè)備使用,因?yàn)榈蛢?yōu)voidFirst_Task(void*{{//優(yōu)先級(jí)高,2sLCD資源LCD_ShowString(20,180,200,16,16,(u8*)"}}oThisisvoidSecond_Task(void*{charstr[]="ThisisSecondTask:";inti=0;{while(++i<{str[sizeof(str2i0x30;}if(i=={i=}}}LCDLCD2就被打斷了。搶占,此時(shí)它還未使用完LCD。mutex的出現(xiàn)是為了解決優(yōu)先級(jí)反轉(zhuǎn)的問題,由于優(yōu)先級(jí)反轉(zhuǎn)對(duì)實(shí)時(shí)性影響太大,所以mutex的穩(wěn)定性直接影響了實(shí)時(shí)性??v觀目前多種實(shí)時(shí)操作系統(tǒng)mutexRTOSmutex優(yōu)先級(jí)逐步還原的問題,導(dǎo)致了實(shí)時(shí)性以及其它的一些邏輯錯(cuò)誤等等。rawos的mutex模塊成功彌補(bǔ)了其它實(shí)時(shí)系統(tǒng)在這方面的不足。Rawos的mutex同時(shí)支持優(yōu)先級(jí)置頂和優(yōu)先級(jí)繼承的方式來(lái)解決優(yōu)先級(jí)RAW_MUTEXraw_mutex_create(&lcd_mutex,(RAW_U8*)"lcd_mutex", ,級(jí)被自動(dòng)提升為高優(yōu)先任務(wù)的優(yōu)先級(jí),比如在本例中兩個(gè)任務(wù)的優(yōu)先級(jí)分別10分析采用mutex實(shí)驗(yàn)思路:創(chuàng)建兩個(gè)任務(wù)分時(shí)使用LCD,在低優(yōu)先級(jí)任務(wù)使用共享資源LCDmutex,它的優(yōu)先級(jí)會(huì)被提升為高優(yōu)先級(jí)任務(wù)的voidFirst_Task(void*{{//1.1優(yōu)先級(jí)高,但要使用臨界資源,也要先獲得mutexUart_Printf("Task1getmutex,Task1currentPriorityis:LCD_ShowString(20,180,200,16,16,(u8*)" oThisisFirst //3.使用完畢,釋放臨界資源Uart_Printf("Task1putmutex\r\n");}}voidSecond_Task(void*{charstr[]="ThisisSecondTask:";inti=0;{任務(wù)切換,Task1要獲得鎖但被Task2占有,Task1把Task2的優(yōu)先級(jí)提高,然后執(zhí)行Task2Uart_Printf("Task2getmutex,Task2currentPriorityi=while(++i {str[sizeof(str2i0x30}Uart_Printf("Task2putmutex!\r\n");}}2raw_sleep進(jìn)行任務(wù)切12的優(yōu)先為和自已一樣(故稱優(yōu)先級(jí)繼承),然后接著執(zhí)行任務(wù)2LCD設(shè)備,直到使用完畢釋放鎖后,阻塞在在對(duì)于mutex的使用,首先是定義并創(chuàng)建它:RAW_MUTEX//任務(wù)占有mutex時(shí)置頂?shù)膬?yōu)先級(jí)為8raw_mutex_create(&lcd_mutex,(RAW_U8*)"lcd_mutex", ,8);#defineRAW_MUTEX_NONE_
priorityprotocol(優(yōu)先級(jí)置頂)。所謂優(yōu)先級(jí)置頂方法需要給每一個(gè)mutex靜態(tài)指定一個(gè)優(yōu)先級(jí),第一個(gè)獲得mutex的任務(wù)會(huì)把優(yōu)先級(jí)提高到靜態(tài)指定的優(yōu)先級(jí)。優(yōu)先級(jí)置頂?shù)姆椒ㄐ枰猰utex的所有任務(wù)優(yōu)先級(jí)都要搞清楚,通常適用于系統(tǒng)中運(yùn)行的任mutex鎖,這個(gè)時(shí)候假設(shè)mutex1的任務(wù)有t1,t2,t3,t1的優(yōu)先級(jí)為20,t2的優(yōu)先25,t330,數(shù)字越小表明優(yōu)先級(jí)越高。這個(gè)時(shí)候mutex1的優(yōu)先級(jí)置頂?shù)膬?yōu)先級(jí)是19,即比t1,t2的優(yōu)先級(jí)要高。假設(shè)任務(wù)t3首先獲得mutex1,這個(gè)時(shí)候任務(wù)t3的優(yōu)先級(jí)會(huì)提升為19,所以t3會(huì)運(yùn)行完分析采用mutex實(shí)驗(yàn)思路:創(chuàng)建兩個(gè)任務(wù)分時(shí)使用LCD,在低優(yōu)先級(jí)任務(wù)使用共享資源LCDmutexmutex時(shí)指voidFirst_Task(voidvoidFirst_Task(void*{{mutex期間,mutex8Uart_Printf("Task1getmutex,Task1currentPriorityLCD_ShowString(20,180,200,16,16,(u8*)"oThisis /*Uart_Printf("Task1putmutex,Task1currentPriority}}voidSecond_Task(void*{charstr[]="ThisisSecondTask:";inti=0;{Uart_Printf("Task2getmutex,Task2currentPriorityi=while(++i<={str[sizeof(str)-2]=i+/*}Uart_Printf("Task2putmutex,Task2currentPriority}}動(dòng)態(tài)內(nèi)存分配往往是一個(gè)必需的過程,標(biāo)準(zhǔn)C庫(kù)的malloc以及可以嵌入式系統(tǒng)上不是總是有標(biāo)準(zhǔn)CC標(biāo)準(zhǔn)C庫(kù)中的malloc以 內(nèi)存管理往往是一個(gè)復(fù)雜的過程,Raw-os5種內(nèi)存分配方法,分別是block,byte,page,malloc,slab。以下會(huì)講解這5種基本原理以及適用場(chǎng)合。這5種里面只有block和slab是沒有內(nèi)存碎片的,其余的都會(huì)有一定的5block和byte能用于中斷內(nèi)內(nèi)存分配,強(qiáng)烈推薦使用中斷內(nèi)采用block內(nèi)存分配,因?yàn)閎yte內(nèi)存的分配除了在分配情況block內(nèi)存分配顧名思義是一塊塊的分配內(nèi)存給用戶,每一塊的內(nèi)存空間都定了不利于不確定大小的內(nèi)存分配。實(shí)戰(zhàn)中可以分配多個(gè)不同大小的block去滿足變長(zhǎng)的分配完全是可行的。強(qiáng)烈建議大部分情況用block去解決內(nèi)存分配如上如圖所示分配了4個(gè)塊,每塊大小為2K。用戶使用block內(nèi)存分配2Kbyte內(nèi)存分配顧名思義是可以分配任何大小的字節(jié)的內(nèi)存給用戶,缺點(diǎn)是page內(nèi)存分配顧名思義是可以分配以page為單位的內(nèi)存給用戶去使用,pagepage2K4K大小。好處是用戶大內(nèi)存分配的話很方便,速度也很快。壞處是可能存在page級(jí)別的內(nèi)存碎片。malloc內(nèi)存分配是可以分配任意字節(jié)的小的,也存在內(nèi)存碎片。具體和標(biāo)準(zhǔn)C庫(kù)的內(nèi)存分配全部吻合。slab內(nèi)存分配也是基于一塊塊的分配給用戶,不過這一塊快的各自大小是rawos支持的內(nèi)存種類繁多,從小級(jí)別的內(nèi)存分配到大級(jí)別的內(nèi)block內(nèi)存分配方法對(duì)應(yīng)的是raw_block.c,byte內(nèi)存分配的方法對(duì)應(yīng)的是raw_byte.c,page內(nèi)存分配的方法對(duì)應(yīng)的是raw_page.c,malloc的內(nèi)存分配算法對(duì)應(yīng)的是raw_malloc.c,slab內(nèi)存分配算法對(duì)應(yīng)的是raw_slab.c。在尊重實(shí)時(shí)操作系統(tǒng)RTOS的下,RAW-OS引進(jìn)了額外4種內(nèi)存heap_1,heap_2,heap_3,heap_4,4種內(nèi)存分heap_1heap_2bestfitheap_3采用了C庫(kù)自定義的malloc以及,但是加了可重入機(jī)制,對(duì)heap_4firstfitheap_1,heap_2heap_3,heap_4的時(shí)候,需要分別他們修改他們各自的配置文件來(lái)指定堆的大小等,比如heap_1_config.h,heap_2_config.h,heap_3_config.h,heap_4_config.h。blockbyte內(nèi)存分配適合在中blockbyte內(nèi)存分配方#define#defineRAW_BLOCK_SIZE1024* unsignedcharMEM_POOL 創(chuàng)建一個(gè)塊內(nèi)存池,10K,raw_block_pool_create(&block_pool,(RAW_U8*)"block_pool",1024,raw_block_pool,RAW_BLOCK_SIZE);voidFirst_Task(voidFirst_Task(void*{intret;inti=0;{ret=raw_block_allocate(&block_pool,ifRAW_NO_MEMORYret {Uart_Printf("blockpoolnomemorytobe} {ptr:%p\r\n",i,block_ptr[i]);iif(i>={i=}}}}voidSecond_Task(void*{inti=0;intret;{if(RAW_SUCCESS!=ret){}{block_ptr[i]=NULL; //釋放后要置NULL}i}}voidThrid_Task(void*{inti;int{for(i0i20i {ifblock_ptr[iNULL)有效內(nèi)存,{ret=raw_block_release(&block_pool,ifif(RAW_SUCCESS!={%d,blockptr:}{block_ptr[i]=NULL; //釋放后要置NULLUart_Printf("blockreleasesuccess!,blocknumber:%d,blockptr:}}}}}#define#define 1024*voidFirst_Task(voidFirst_Task(void*{intret;inti=0;{ret=raw_byte_allocate(&byte_pool,(RAW_VOID1024*(i+1)ifRAW_NO_MEMORYret {Uart_Printf("bytepoolnomemorytobe} {%p\r\n",i,byte_ptr[i])iif(i>={i=}}}}voidSecond_Task(void*{inti=0;intret;{ret=raw_byte_release(&byte_pool,(RAW_VOIDif(RAW_SUCCESS!={Uart_Printf("bytereleaseerror!,bytenumber:%d,byte}{byte_ptr[i]=NULL; //釋放后要置NULLUart_Printf("bytereleasesuccess!,bytenumberd,byteptr:}i}}voidThrid_Task(void*{inti;{for(i=0;i<20;i{if(byte_ptr[i]!=NULL{ret=raw_byte_release(&byte_pool,if(RAW_SUCCESS!={ptr:%p\r\n",i,byte_ptr[i]);}{byte_ptr[i]=NULL; //釋放后要置NULLUart_Printf("blockreleasesuccess!,bytenumber:%d,byteptr:}}}}}本節(jié)演示基于RTOS的heap_4內(nèi)存管理使用,首先添加heap_4.c源文其中heap_4.c文件在Raw-os源 下的 下面heap_4_config.h頭文件在Raw-os源 下的Heap_4內(nèi)存管理的API使用也相當(dāng)簡(jiǎn)單:10K大小的內(nèi)存控制塊(內(nèi)存池)2按下,為按鍵按下的次數(shù),按鍵0按下,則釋放所有內(nèi)存。voidFirst_Task(void*{unsignedint{count= memory:%d}}voidSecond_Task(void*{inti={mem_ptr=mem_4_malloc(1000*i);if(NULL==mem_ptr){}{iUart_Printf("memorymallocsuccess,}}}voidThrid_Task(void*{{ mem_ptr=}}16.當(dāng)一個(gè)任務(wù)需要和多種同步的時(shí)候可以使用標(biāo)志來(lái)同步。一組事件標(biāo)志有32個(gè)bit。一個(gè)任務(wù)可以同步任何一個(gè)的發(fā)生,這個(gè)時(shí)候就叫或的機(jī)制,也可以同步所有的發(fā)生,這個(gè)時(shí)候叫與的機(jī)制。理論上rawos可以無(wú)限的創(chuàng)建標(biāo)志,但是實(shí)踐上內(nèi)存制約了這一點(diǎn)。標(biāo)志的代碼在raw_event.c。(and),假如一個(gè)任務(wù)等待幾個(gè)標(biāo)志位的任何一個(gè)滿足條件,就能運(yùn)行,這是沒有的,如果滿足標(biāo)志了就相當(dāng)于狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換。建,設(shè)置,獲取。代碼如下://定義一 設(shè)置////設(shè)置 組的BIT2raw_event_set(&Key_Event,0x2,RAW_OR);獲取////獲取 的BIT3或BIT2,有任一滿足返回, 到event_flag中raw_event_get(&Key_Event,0x6,RAW_OR_CLEAR,&event_flag,三個(gè)任務(wù)阻塞到這個(gè)上,當(dāng)按鍵按下的時(shí)候,相應(yīng)的任務(wù)被喚醒。voidFirst_Task(void*{{ raw_event_get(&Key_Event,0x2,RAW_OR_CLEAR,Uart_Printf("Task1ReceiveEventBIT2,theeventflagValueis:}}voidSecond_Task(void*{{ raw_event_get(&Key_Event,0x1,RAW_OR_CLEAR,Uart_Printf("Task1ReceiveEventBIT1,TheEventFlagValueis:}}voidThrid_Task(void*{{//阻塞等待 raw_event_get(&Key_Event,0x6,RAW_OR_CLEAR,is:0X%X\r\n",event_flag);}}17.::本實(shí)驗(yàn)的源碼在eventset部分和上節(jié)一樣,在eventget//獲取 raw_event_get(&Key_Event,0x6,RAW_AND_CLEAR,&event_flag,//設(shè)置 組的BIT2raw_event_set(&Key_Event,0x2,RAW_OR);Idle_TaskCPU_Taskraw_config.h宏,這樣系統(tǒng)中就有一個(gè)預(yù)定義的優(yōu)先級(jí)為0的任務(wù)Task_0,它的源碼在raw_task_0.c中。Tick_Task1,如果系統(tǒng)沒有中,這樣會(huì)影響到實(shí)時(shí)性,所以建議開啟Tick_Task。Timer_Task任務(wù)中,#defineCPU_TASK_PRIORITY#defineCPU_STACK_SIZE
(CONFIG_RAW_PRIO_MAX-三項(xiàng)表示它的棧是256。這個(gè)函數(shù)通常放在配置完OS時(shí)鐘之后:對(duì)于統(tǒng)計(jì)任務(wù)的使用就是開啟宏,調(diào)用初始化函數(shù)兩步,然后系統(tǒng)提供給//打印CPU利用率和最大CPU利用 Uart_Printf("CPUUsage:%d CPUMaxUsage:%d 本例程向系統(tǒng)中cpuusage命令,在s中輸入此命令,查的FIFO即環(huán)形緩沖區(qū),是只能在一端寫數(shù)據(jù),在另一端讀的結(jié)構(gòu)。是一種使放在extension 下的lib子 中,實(shí)現(xiàn)文件為fifo.c或fifo_lock.c,兩個(gè)的區(qū)別在于后者在讀寫FIFO過程中加入了鎖機(jī)制,這樣對(duì)多任務(wù)環(huán)境下操作更安FIFO具體的原理請(qǐng)參見本文檔的附錄四RAW-OSFIFO機(jī)制分析,端中輸入一個(gè)字符時(shí),觸發(fā)USART的接收中斷,在中斷中釋放信號(hào)量去同步S任務(wù),然后輸入的字符存到緩中區(qū)中。如果收到的字符是回冊(cè)符,則如果是回冊(cè)符,則釋放信號(hào)量去同步S任務(wù)去FIFO中的內(nèi)容(命令字符ch=_Taskif(ch=={ }elseif(ch {故此處無(wú)處理,僅為演示Raw-os內(nèi)核擴(kuò)展模塊FIFO的使用,}{ } /*/*等待信號(hào)量阻塞,直到終端輸入回冊(cè)符后喚醒////printalen=fifo_out_all(&USART1_FIFO,(void*)input_buffer);if(len){input_buffer[len]={ret mand((const}while(ret==}細(xì)心的讀者會(huì)發(fā)現(xiàn),面的例程中,都是任務(wù)阻塞在一個(gè)內(nèi)核對(duì)像上,比如,在例程4中s任務(wù)阻塞一個(gè)信號(hào)量上,在例程7–9中任務(wù)阻塞在一個(gè)隊(duì)rawos支持任務(wù)同時(shí)阻塞在隊(duì)列(queue)或者信號(hào)量(semaphore)上。rawos實(shí)現(xiàn)多對(duì)象阻塞的功能主要是通過函數(shù)通知的功能來(lái)實(shí)現(xiàn)的。通過個(gè)的函數(shù)。怎么樣一個(gè)函數(shù)通知功能的回調(diào)函數(shù)呢?舉例如下raw_semphore_send_notify(&sem1,notify_function)通過此函數(shù)調(diào)用可以注冊(cè)一個(gè)回調(diào)函數(shù)notify_function到信號(hào)量sem上,當(dāng)用戶使用函數(shù)raw_semaphore_put的時(shí)候就可以觸發(fā)此回調(diào)函數(shù)。通過此函數(shù)可以一個(gè)回調(diào)函數(shù)notify_function到queue1上。當(dāng)用戶使用函數(shù)raw_queue_end_post時(shí)會(huì)觸發(fā)此的回調(diào)函數(shù)。上圖(1)處任務(wù)1需要等待queue1或者queue2有消息才能繼續(xù)運(yùn)行。queue1queue21(2)和(3)queue1queue21需要去接收,(4)和(5)1rawos對(duì)于上面問題的解決方式,不同的操作系上圖(1)處任務(wù)1阻塞在網(wǎng)關(guān)處當(dāng)sem1的內(nèi)部計(jì)數(shù)器值為0時(shí)說明queue1和queue20queue1queue2有消息。(2)和(3)queue1queue21(4)和(5)處說明任務(wù)1接收了消息后繼續(xù)運(yùn)行。sem1的網(wǎng)關(guān),具體的代碼演示如下:queue1以及queue2上注冊(cè)一個(gè)通知函數(shù)voidvoidnotify_queue(RAW_QUEUE{}可以看到只要queue1和queue2里面一有消息就會(huì)觸發(fā)notify_queue回sem1,1。任務(wù)1的代碼如下ret=raw_queue_receive(&queue1,RAW_NO_WAIT,if(ret=={/*Accessqueue1}retret=raw_queue_receive(&queue2,RAW_NO_WAIT,if(ret=={/*Accessqueue2}1sem1queue1queue2上有notify_queue這個(gè)回調(diào)函數(shù),回調(diào)函數(shù)內(nèi)會(huì)釋放一個(gè)信號(hào)量,進(jìn)而喚醒任務(wù)1。raw_queue_receive時(shí)需要采用沒有消息立馬返回的功能,即超時(shí)參數(shù)為RAW_NO_WAIT。void{//3. raw_queue_send_notify(&Queue_1,notify_queue_1);raw_queue_send_notify(&Queue_2,notify_queue_2);raw_queue_send_notify(&Queue_3,notify_queue_3);raw_task_create(&Task_MultiPend,(RAW_U8*)"Task_Multi",0,10,0,Task_MultiPend_Stack,TASK_STACK_SIZE,Task_MultiPend_Fun,}{}{}{}voidTask_MultiPend_Fun(void*{RAW_U16res;signedchar*msg;{ res=raw_queue_receive(&Queue_1,RAW_NO_WAIT,if(res=={}{{res=raw_queue_receive(&Queue_2,RAW_NO_WAIT,if(res=={}{}} if(0==raw_strncmp((constchar*)msg,"KEY0",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY1",4){}elseif(0==raw_strncmp((constchar*)msg,"KEY2",4){}}}實(shí)驗(yàn)思路:創(chuàng)建一個(gè)任務(wù)阻塞在多個(gè)內(nèi)核對(duì)像上,在本節(jié)例程中是阻塞在KEY2KEY1步任務(wù),然后任務(wù)再?gòu)南㈥?duì)列中消息或信號(hào)量。而控制不同的LED工作。中斷下半部workqueueRaw-os提供獨(dú)特的中斷下半部機(jī)制,其實(shí)現(xiàn)方法有多種,具體原理與源碼raw-osworkqueue實(shí)現(xiàn)方法。在這里做出實(shí)驗(yàn)說明。實(shí)驗(yàn)思路:500ms的#definePORT_STACK RAW_VOIDvoidMy_Func(RAW_U32arg,void{Uart_Printf("%d} unsignedcharmsg[]=unsignedintcount=oworld!msg void{/*模擬 到數(shù)據(jù)*/count++;if(count>999)count=msgmsg[sizeof(msg)-4]=count/100+0X30;msg[sizeof(msg)-3]=count%100/10+0X30;msg[sizeof(msg)-2]=count%10+0X30;}void{//初始化workqueuesystem//創(chuàng)建一個(gè)workqueue//}raw_os內(nèi)核中采用了一套通用的、一般的、可以用到各種不同數(shù)據(jù)結(jié)構(gòu)的previousnext從具體的“宿主”數(shù)LIST,這種數(shù)據(jù)結(jié)構(gòu)既可以“寄宿”typedeftypedefstruct{structLISTstructLIST}{ list_head->previous=}{return(list->next==}RAW_INLINERAW_INLINEvoidlist_insert(LIST*head,LIST{element->previous=head->previous;element->next=head;head->previous->next=element;head->previous=element;}{element->previous->next=element->next;element->previous->next=element->next;}#define#definelist_entry(node,type,((type*)((RAW_U8*)(node)把上面的代碼分開來(lái)理解,先說(RAW_U32)(&((type*)0)(type*)00type(RAW_U32)(&((type*)0)->member)RAW_U32型,事實(shí)上它就offset大小,再看(type*)((RAW_U8nodememberlist類型的結(jié)點(diǎn),它是嵌入到宿主結(jié)構(gòu)體nodeoffset (RAW_U8*)(node)(RAW_U32)(&((type*)0)->member)已經(jīng)是宿主結(jié)構(gòu)體的起始地址,再對(duì)它進(jìn)行一下強(qiáng)制類型轉(zhuǎn)換(type*)就得到宿主結(jié)構(gòu)體類型了。RAW-OSS使用一種簡(jiǎn)單、易用、高效的機(jī)制使得應(yīng)用程序支持命令行護(hù)一個(gè)單向鏈表,新加入令依次掛help這個(gè)鏈表頭后面,當(dāng)在應(yīng)用層面輸入命令時(shí),執(zhí)行s解析的任務(wù)會(huì)這個(gè)命令,并通過 函數(shù)從單鏈表頭開始查找這個(gè)命令是否已(掛接到命令鏈表,每個(gè)命令會(huì)首先分析下一個(gè)命令所對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)類型,rsh.h文件中定義了定義一個(gè)typedeftypedefstruct{constRAW_S8*constRAW_S8*constRAW_S8}//上面的數(shù)據(jù)結(jié)構(gòu)中第一項(xiàng) typedeftypedefRAW_S32MAND_LINE_CALLBACK)(RAW_S8size_txWriteBufferLen,constRAW_S8mandString pcWriteBuffer:命令執(zhí)行的輸出結(jié):eg:添加一個(gè)打印MCUIDstaticstaticconstmand{ no 0staticxCommandLineInputListItemmand_list_pointmand_list_point->pxNext=pxNewListItem;mand_list_point=pxNewListItem;} typedeftypedefstruct{constxCommandLineInput* structxCOMMAND_INPUT_LIST*pxNext;}mandLineDefinition那對(duì)于這個(gè)函數(shù)來(lái)說,首先是將欲添加令結(jié)構(gòu)staticxCommandLineInputListItemmand_list_pointstaticxCommandLineInputListItemmand_list_point 上面代碼是定義了一個(gè)指針,并初始化該指針指向鏈表的頭結(jié)點(diǎn)—help命/*/*Thedefinitionofthe"help"command.Thiscommandisalwaysattheofthelistofregisteredcommands.staticconst mand{"help:Listsalltheregistered0/*/*定義一個(gè)命令鏈表,所有的 命令均掛接在這個(gè)鏈表上static mands{0command,definedinthisfile.*/arenootherregisteredcommandsyet.當(dāng)啟動(dòng)系統(tǒng)時(shí),首先啟動(dòng)s_Task,在s_Task中完成一些硬件初始化工作,然后依次各個(gè)命令,然后改變Task的優(yōu)先級(jí)使其最低,并且讓這個(gè)/*定義一個(gè)指針,指向當(dāng)前正在檢索的鏈表結(jié)點(diǎn)*pcWriteBuffer,size_txWriteBufferLen{RAW_S32xReturn=constRAW_S8* RAW_U8s_input_length; ifmandInput==0)}if(pcWriteBuffer==0)}if(xWriteBufferLen==0)}if mand_point==0)for mand_point mand_point!=0; mand_point mand_point->pxNext) mandString if(s_input_length mand_length)mpare_length=}else}
mpare_length if(raw_strncmp((constchar mandInput,(const mpare_length)==0) berOfParameters>=0){ if mandInput) erOfParameters){xReturn=}} }}}}if mand_point&&(xReturn==1))raw_strncpy((char*)pcWriteBuffer,"\rIncorrectcommandparameter(s).Enter\"help\"toviewalistofavailablecommands.\r\n\r\n",xWriteBufferLen); mand_point }elseif mand_point!=0)xReturn rpreter(pcWriteBuffer,xWriteBufferLen, if(xReturn==1) mand_point=}}elseraw_strncpy((char*)pcWriteBuffer,(constchar*)"\rCommandnotrecognised.Enter\"help\"toviewalistofavailablecommands.\r\n\r\n",xWriteBufferLen);xReturn=}return}//得到命令行的長(zhǎng)度 staticstaticRAW_U8command_length_get(constRAW_S8{constRAW_S8for(sc=command;(*sc!='\0')&&(*sc!='');++sc)returnsc-command;}//得到參數(shù)的個(gè)數(shù) staticstaticRAW_S8rsh_get_parameters_numbers(constRAW_S8{RAW_S8cParameters=RAW_S32xLastCharacterWasSpace=while({if(({mandString!=0x00mandString)==''if(xLastCharacterWasSpace!=0{ xLastCharacterWasSpace=0;}}{xLastCharacterWasSpace=}}return}//uxWantedParameter,RAW_S32*pxParameterStringLength{RAW_S32uxParametersFound constRAW_S8*pcReturn=while(uxParametersFound<uxWantedParameter{''){}}while(((==''){mandString)!=0x00)&&((}if( mandString!=0x00{if(uxParametersFound==uxWantedParameter{pcReturn while((( mandString)!=0x00)((mandString)!=''){(*pxParameterStringLength}}}{}}return}staticconstxCommandLineInputListItemstaticstaticmand(RAW_S8*pcWriteBuffer,xWriteBufferLen,constRAW_S8 mandString{RAW_S32(voidifmand_point==0)/*Resetmandpointerbacktothestartofthelist.mand_point }thenextcommandinthelist.raw_strncpy((char*)pcWriteBuffer,(const*mand_point ifmand_point==0)stringstoreturnafterthisoneand1shouldbereturned.*/xReturn=}elsexReturn=}return}附錄三、RAW-OSW-OS0usSTM32平臺(tái)編寫的時(shí)鐘節(jié)拍服務(wù)函數(shù)voidvoid{#if(CONFIG_RAW_TASK_0>}大0中斷特性時(shí)的處理方法作一個(gè)分析。RAW_VOIDRAW_VOID{#if(CONFIG_RAW_TASK_0>0)if(raw_int_nesting)}#if(CONFIG_RAW_USER_HOOK>/*update/*updatesystemtimetocalculatewhethertasktimeout#if(CONFIG_RAW_TICK_TASK> /*updatetasktimesliceif#if(CONFIG_SCHED_FIFO_RR>0) //計(jì)算時(shí)間片/*informthetimertasktoupdatesoftwaretimer*/#if(CONFIG_RAW_TIMER>0) //開了定時(shí)器}系統(tǒng)時(shí)鐘節(jié)拍的執(zhí)行流程一般是這樣的ISRISR時(shí)最后調(diào)用,那么這兩個(gè)函數(shù)做了RAW_U16RAW_U16{ifif(raw_int_nesting>={return} return}義RAW_VOIDRAW_VOID{ //if(raw_int_nesting==0)}//中斷嵌入層數(shù)-1if(raw_int_nesting)}if(raw_sched_lock)}ifif(high_ready_obj==raw_task_active)}}unsignedintcpu_sr={cpu_sr=#if#if(CONFIG_RAW_TICK_TASK> 0task_0機(jī)制,0tick_tasktick_taskraw_time_tickupdateticklist。txj的這句話讓我深刻,Raw-os最大關(guān)中斷0us特性確實(shí)牛X,task_0特性#if#if(CONFIG_RAW_TICK_TASK>staticvoidtick_task_process(void{while(1){retraw_task_semaphore_get(RAW_WAIT_FOREVER);ifif(ret==RAW_SUCCESS)if(raw_os_active==RAW_OS_RUNNING)}}}}void{//創(chuàng)建tick_task任務(wù),用于updateticklistraw_task_create(&tick_task_objRAW_U8*)"tick_task_object"0,TICK_TASK_PRIORITY,0,tick_task_stack,TICK_TASK_STACK_SIZE,(RAW_U8*)"tick_semaphore_obj",0);}#if#if(CONFIG_RAW_TICK_TASK>這樣用的,raw_task_semaphore_put(&tick_task_obj),直接把信號(hào)量發(fā)給了tick_taskRAW-OS中提供了任務(wù)信號(hào)量這種機(jī)制,當(dāng)時(shí)確的知道ISR和任務(wù)或任務(wù)和任務(wù)之間的同步關(guān)系時(shí),可以直接把信號(hào)量發(fā)給這個(gè)任務(wù)。合txj的講解看,理解的更好。 FIFOLinuxFIFO有異曲同工之妙,是一種典型空余大小(字節(jié)structraw_fifostructraw_fifo這正是該fifo實(shí)現(xiàn)的精妙之處。staticstaticRAW_U32fifo_unused(structraw_fifo{return(fifo->mask+1)-(fifo->in-fifo-}RAW_S8fifo_init(structraw_fifo*fifo,void*buffer,RAW_U32RAW_U32fifo_in(structraw_fifo*fifo,constvoid*buf,unsignedintRAW_U32fifo_out(structraw_fifo*fifo,void*buf,RAW_U32len);RAW_U32fifo_out_peek(structraw_fifo*fifo,void*buf,RAW_U32len);RAW_U32fifo_out_all(structraw_fifo*fifo,voidstaticstaticstructraw_fifostaticchar//定義一個(gè)變量(uart接收數(shù)據(jù)緩沖//內(nèi)存地址sizeRAW_S8fifo_init(structraw_fifo*fifo,void*buffer,RAW_U32{}fifo->in=fifo->out=fifo->data=if(size<2)fifo->mask=return}fifo->mask=size-1; _bytes=size;return}FIFO寫(入隊(duì)功能描述:把buf中l(wèi)en長(zhǎng)度數(shù)據(jù)寫入FIFO RAW_U32fifo_in(structraw_fifo*fifo,constvoid*buf,RAW_U32{RAW_U32l;l=if(len>lenlen=fifo_copy_in(fifo,buf,len,fifo-fifo->in _bytes-=return} len,RAW_U32off){RAW_U32RAW_U32size=fifo->mask+off&=fifo-l=fifo_min(len,size-off);raw_memcpy((unsignedchar*)fifo->data+off,src,lensizefifo->in,則下面是回寫到隊(duì)頭,lensizeraw_memcpy(fifo->data,(unsignedchar*)src+l,len-}off&=fifo->maskfifo->in&(fifo->size1),在初始化代碼保證了fifo->size2102410000000000,fifo->size101111111111,OKfifo->in對(duì)fifo->sizefifo->infifo->in本質(zhì)上為unsignedint,溢出了呢?后面再分析。參數(shù)說明:fifo:目標(biāo)FIFO;buf:讀出數(shù)據(jù)的 地址;len:讀出數(shù)據(jù)長(zhǎng)度功能描述:從fifo中讀出len長(zhǎng)度的數(shù)據(jù)到buf中返回值:讀出數(shù)據(jù)的長(zhǎng)度RAW_U32fifo_out(structraw_fifo*fifo,void*buf,RAW_U32{ leninternal_fifo_out_peek(fifobuflen);fifo->out+=len; //移動(dòng)讀指針 _bytes+=len; return }參數(shù)說明:fifo:目標(biāo)FIFO;buf:讀出數(shù)據(jù)的 地址;len:讀出數(shù)據(jù)長(zhǎng)度功能描述:從fifo中off位置讀出len長(zhǎng)度的數(shù)據(jù)到buf中返回值:讀出數(shù)據(jù)的長(zhǎng)度RAW_U32{RAW_U32l=fifo->in-fifo- iflen len= // kfifo_copy_out(fifo,buf,len,fifo->out);returnlen; //返回 }參數(shù)說明:fifo:目標(biāo)FIFO;
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 修建贊助合同范本
- 勞務(wù)時(shí)間合同范本
- 內(nèi)外架合同范例
- 化肥合作合同范例
- 專項(xiàng)經(jīng)理聘用合同范本
- 農(nóng)業(yè)購(gòu)貨合同范本
- 化工產(chǎn)品購(gòu)銷服務(wù)合同范本
- 醫(yī)院購(gòu)銷合同范本
- 出口布料銷售合同范例
- 養(yǎng)殖水車出租合同范例
- DB34∕T 3247-2018 井采煤礦綠色礦山建設(shè)要求
- 2024至2030年中國(guó)小模數(shù)齒輪市場(chǎng)調(diào)查與行業(yè)前景預(yù)測(cè)專題研究報(bào)告
- DB32T-公路橋梁水下結(jié)構(gòu)檢測(cè)評(píng)定標(biāo)準(zhǔn)
- 小學(xué)語(yǔ)文教師讀書筆記范文(5篇)
- 2023年部編人教版六年級(jí)道德與法治下冊(cè)全冊(cè)課件【全套】
- 《茉莉花》(課件)人音版音樂六年級(jí)上冊(cè)
- 肌肉注射的常見并發(fā)癥及預(yù)防處理措施
- 景觀模型設(shè)計(jì)與制作:第7章 建筑模型制作基本技法
- 關(guān)愛婦女防治兩癌講座課件
- DL∕T 584-2017 3kV~110kV電網(wǎng)繼電保護(hù)裝置運(yùn)行整定規(guī)程
- (正式版)FZ∕T 80018-2024 服裝 防靜電性能要求及試驗(yàn)方法
評(píng)論
0/150
提交評(píng)論