ucos lwip應(yīng)用心得[社區(qū)]_第1頁(yè)
ucos lwip應(yīng)用心得[社區(qū)]_第2頁(yè)
ucos lwip應(yīng)用心得[社區(qū)]_第3頁(yè)
ucos lwip應(yīng)用心得[社區(qū)]_第4頁(yè)
ucos lwip應(yīng)用心得[社區(qū)]_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、ucos+lwip應(yīng)用心得社區(qū)                經(jīng)過(guò)幾天調(diào)試除掉幾個(gè)bug以后,ucos+lwip在我的44b0+8019開(kāi)發(fā)板上終于跑得比較穩(wěn)定了.一只覺(jué)得lwip是一個(gè)不錯(cuò)的開(kāi)放源碼的tcp/ip 協(xié)議棧,想把自己對(duì)lwip的移植和理解寫(xiě)出來(lái).但是由于最近比較忙,lwip的移植也是利用業(yè)余時(shí)間做的,今天寫(xiě)好了第一部分(lwip的 process model)先貼上來(lái),如果大家有興趣我再接著往下寫(xiě).另外我的移植參看了sk

2、yeye揚(yáng)曄大俠的代碼,大家可以去看看揚(yáng)曄大俠的lwip在ucos上移植的文章和代碼.       lwip應(yīng)用心得   lwIP是瑞士計(jì)算機(jī)科學(xué)院(Swedish Institute of Computer Science)的Adam Dunkels等開(kāi)發(fā)的一套用于嵌入式系統(tǒng)的開(kāi)放源代碼TCP/IP協(xié)議棧。Lwip既可以移植到操作系統(tǒng)上,又可以在無(wú)操作系統(tǒng)的情況下獨(dú)立運(yùn)行.          &

3、#160;                 LwIP的特性如下:(1)    支持多網(wǎng)絡(luò)接口下的IP轉(zhuǎn)發(fā)(2)    支持ICMP協(xié)議 (3)    包括實(shí)驗(yàn)性擴(kuò)展的的UDP(用戶數(shù)據(jù)報(bào)協(xié)議)(4)    包括阻塞控制,RTT估算和快速恢復(fù)和快速轉(zhuǎn)發(fā)的TCP(傳輸控制協(xié)

4、議)(5)    提供專門的內(nèi)部回調(diào)接口(Raw API)用于提高應(yīng)用程序性能(6)    可選擇的Berkeley接口API(多線程情況下)(7)     在最新的版本中支持ppp(8)     新版本中增加了的IP fragment的支持.(9)     支持DHCP協(xié)議,動(dòng)態(tài)分配ip地址.現(xiàn)在網(wǎng)上最新的版本是V0.6.4   

5、60;1.lwip的進(jìn)程模型(process model)      tcp/ip協(xié)議棧的process model一般有幾種方式.        1.tcp/ip協(xié)議的每一層是一個(gè)單獨(dú)進(jìn)程.鏈路層是一個(gè)進(jìn)程,ip層是一個(gè)進(jìn)程,tcp層是一個(gè)進(jìn)程.這樣的好處是網(wǎng)絡(luò)協(xié)        議的每一層都非常清晰,代碼的調(diào)試和理解都非常容易.但是最大的壞處數(shù)據(jù)跨層傳遞時(shí)會(huì)引起上下文切換(c

6、ontext switch).        對(duì)于接收一個(gè)TCP segment要引起3次context switch(從網(wǎng)卡驅(qū)動(dòng)程序到鏈路層進(jìn)程,從鏈路層進(jìn)程到ip層進(jìn)程,從ip層進(jìn)程        到TCP進(jìn)程).通常對(duì)于操作系統(tǒng)來(lái)說(shuō),任務(wù)切換是要浪費(fèi)時(shí)間的.過(guò)頻的context swich是不可取的.        2.另外一種方式是TCP/IP協(xié)議棧

7、在操作系統(tǒng)內(nèi)核當(dāng)中.應(yīng)用程序通過(guò)操作系統(tǒng)的系統(tǒng)調(diào)用(system call)和協(xié)議棧來(lái)進(jìn)行通訊.        這樣TCP/IP的協(xié)議棧就限定于特定的操作系統(tǒng)內(nèi)核了.如windows就是這種方式.        3.lwip的process model:所有tcp/ip協(xié)議棧都在一個(gè)進(jìn)程當(dāng)中,這樣tcp/ip協(xié)議棧就和操作系統(tǒng)內(nèi)核分開(kāi)了.而應(yīng)用層程序既可以       

8、; 是單獨(dú)的進(jìn)程也可以駐留在tcp/ip進(jìn)程中.如果應(yīng)用程序是單獨(dú)的進(jìn)程可以通過(guò)操作系統(tǒng)的郵箱,消息隊(duì)列等和tcp/ip進(jìn)程進(jìn)行通訊.            如果應(yīng)用層程序駐留tcp/ip進(jìn)程中,那應(yīng)用層程序就利用內(nèi)部回調(diào)函數(shù)口(Raw API)和tcp/ip協(xié)議棧通訊.對(duì)于ucos來(lái)說(shuō)進(jìn)程就是一個(gè)系統(tǒng)任務(wù).lwip的process model請(qǐng)參看下圖.在圖中可以看到整個(gè)tcp/ip協(xié)議棧都在同一個(gè)任務(wù)(tcpip_thread)中.應(yīng)用層程序既可以是獨(dú)立的任務(wù)(

9、如圖中的tftp_thread,tcpecho_thread),也可以在tcpip_thread中(如圖左上角)中利用內(nèi)部回調(diào)函數(shù)口(Raw API)和tcp/ip協(xié)議棧通訊    2 Port Lwip to uCos          在這個(gè)項(xiàng)目中我用的硬件平臺(tái)是s3c44b0x+rtl8019.ucos在44b0上的移植在網(wǎng)上有很多大俠非常詳盡的講解和移植代碼.我就不敢羅嗦了.需要說(shuō)明的一點(diǎn)是lwip會(huì)為每個(gè)網(wǎng)絡(luò)連接動(dòng)態(tài)分配一些信號(hào)量(semaphone)和消

10、息隊(duì)列(Message Queue),當(dāng)連接斷開(kāi)時(shí)會(huì)刪掉這些semaphone和Queue.而Ucos-2.0不支持semaphone和Queue的刪除,所以要選擇一些較高版本的ucos.我用的是ucos-2.51.    2.1 Lwip的操作系統(tǒng)封裝層(operating system.emulation layer)        Lwip為了適應(yīng)不同的操作系統(tǒng),在代碼中沒(méi)有使用和某一個(gè)操作系統(tǒng)相關(guān)的系統(tǒng)調(diào)用和數(shù)據(jù)結(jié)構(gòu).而是在lwip和操作系統(tǒng)之間增加了一個(gè)操作系統(tǒng)封裝

11、層.操作系統(tǒng)封裝層為操作系統(tǒng)服務(wù)(定時(shí),進(jìn)程同步,消息傳遞)提供了一個(gè)統(tǒng)一的接口.在lwip中進(jìn)程同步使用semaphone和消息傳遞采用”mbox”(其實(shí)在ucos的實(shí)現(xiàn)中我們使用的是Message Queue來(lái)實(shí)現(xiàn)lwip中的”mbox”,下面大家可以看到這一點(diǎn))Operating system emulation layer的原代碼在/lwip/src/core/sys.c中.而和具體的操作系統(tǒng)相關(guān)的代碼在./lwip/src/arch/sys_arch.c中.操作系統(tǒng)封裝層的主要函數(shù)如下:void sys_init(void)/系統(tǒng)初始化sys_thread_t sys_thread_

12、new(void (* function)(void *arg), void *arg,int prio)/創(chuàng)建一個(gè)新進(jìn)程  sys_mbox_t sys_mbox_new(void)/創(chuàng)建一個(gè)郵箱  void  sys_mbox_free(sys_mbox_t mbox)/釋放并刪除一個(gè)郵箱  void  sys_mbox_post(sys_mbox_t mbox, void *data) /發(fā)送一個(gè)消息到郵箱  void sys_mbox_fetch(sys_mbox_t

13、 mbox, void *msg)/等待郵箱中的消息  sys_sem_t sys_sem_new(u8_t count)/創(chuàng)建一個(gè)信號(hào)量void sys_sem_free(sys_sem_t sem)/釋放并刪除一個(gè)信號(hào)量void sys_sem_signal(sys_sem_t sem)/發(fā)送一個(gè)信號(hào)量void sys_sem_wait(sys_sem_t sem)/等待一個(gè)信號(hào)量  void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)/設(shè)置一個(gè)超時(shí)事件  

14、void sys_untimeout(sys_timeout_handler h, void *arg)/刪除一個(gè)超時(shí)事件  關(guān)于操作系統(tǒng)封裝層的信息可以閱讀lwip的doc目錄下面的sys_arch.txt.文件.2.2 Lwip在ucos上的移植.2.2.1 系統(tǒng)初始化   sys_int必須在tcpip協(xié)議棧任務(wù)tcpip_thread創(chuàng)建前被調(diào)用.  #define MAX_QUEUES        20#define MAX_QUEU

15、E_ENTRIES   20typedef struct        OS_EVENT*   pQ;/ucos中指向事件控制塊的指針       void*  pvQEntriesMAX_QUEUE_ENTRIES;/消息隊(duì)列/MAX_QUEUE_ENTRIES消息隊(duì)列中最多消息數(shù) TQ_DESCR, *PQ_DESCR;typedef PQ_DESCR  

16、;sys_mbox_t;/可見(jiàn)lwip中的mbox其實(shí)是ucos的消息隊(duì)列static char pcQueueMemoryPoolMAX_QUEUES * sizeof(TQ_DESCR) ;   void sys_init(void)    u8_t i;    s8_t   ucErr;            pQueueMem =

17、 OSMemCreate( (void*)pcQueueMemoryPool, MAX_QUEUES, sizeof(TQ_DESCR), &ucErr );/為消息隊(duì)列創(chuàng)建內(nèi)存分區(qū)    /init lwip task prio offset    curr_prio_offset = 0;    /init lwip_timeouts for every lwip task    /初始化lwip定時(shí)事件表,具體實(shí)現(xiàn)參考下面

18、章節(jié)    for(i=0;i<LWIP_TASK_MAX;i+)        lwip_timeoutsi.next = NULL;    2.2.2 創(chuàng)建一個(gè)和tcp/ip相關(guān)新進(jìn)程:lwip中的進(jìn)程就是ucos中的任務(wù),創(chuàng)建一個(gè)新進(jìn)程的代碼如下:#define LWIP_STK_SIZE      10*1024/和tcp/ip相關(guān)任務(wù)的堆棧大小.可以根據(jù)情況自/

19、己設(shè)置,44b0開(kāi)發(fā)板上有8M的sdram,所以設(shè)大/一點(diǎn)也沒(méi)有關(guān)系:)/max number of lwip tasks#define LWIP_TASK_MAX    5 /和tcp/ip相關(guān)的任務(wù)最多數(shù)目/first prio of lwip tasks#define LWIP_START_PRIO   5 /和tcp/ip相關(guān)任務(wù)的起始優(yōu)先級(jí),在本例中優(yōu)先級(jí)可/以從(5-9).注意tcpip_thread在所有tcp/ip相關(guān)進(jìn)程中/應(yīng)該是優(yōu)先級(jí)最高的.在本例中就是優(yōu)先級(jí)5 /如果用戶需要?jiǎng)?chuàng)建和tcp/ip無(wú)關(guān)任務(wù),

20、如uart任務(wù)等,/不要使用5-9的優(yōu)先級(jí)    OS_STK LWIP_TASK_STKLWIP_TASK_MAXLWIP_STK_SIZE;/和tcp/ip相關(guān)進(jìn)程/的堆棧區(qū)     u8_t curr_prio_offset ;     sys_thread_t sys_thread_new(void (* function)(void *arg), void *arg,int prio)  if(curr_prio_offset

21、 < LWIP_TASK_MAX)      OSTaskCreate(function,(void*)0x1111, &LWIP_TASK_STKcurr_prio_offsetLWIP_STK_SIZE-1,LWIP_START_PRIO+curr_prio_offset );    curr_prio_offset+;     return 1;   else     / PR

22、INT(" lwip task prio out of range ! error! ");  從代碼中可以看出tcpip_thread應(yīng)該是最先創(chuàng)建的.  2.2.3 Lwip中的定時(shí)事件      在tcp/ip協(xié)議中很多時(shí)候都要用到定時(shí),定時(shí)的實(shí)現(xiàn)也是tcp/ip協(xié)議棧中一個(gè)重要的部分.lwip中定時(shí)事件的數(shù)據(jù)結(jié)構(gòu)如下. struct sys_timeout   struct sys_timeout *next;/指向下一個(gè)定時(shí)結(jié)構(gòu)  u3

23、2_t time;/定時(shí)時(shí)間  sys_timeout_handler h;/定時(shí)時(shí)間到后執(zhí)行的函數(shù)  void *arg;/定時(shí)時(shí)間到后執(zhí)行函數(shù)的參數(shù).;struct sys_timeouts   struct sys_timeout *next;struct sys_timeouts lwip_timeoutsLWIP_TASK_MAX;Lwip中的定時(shí)事件表的結(jié)構(gòu)如下圖,每個(gè)和tcp/ip相關(guān)的任務(wù)的一系列定時(shí)事件組成一個(gè)單向鏈表.每個(gè)鏈表的起始指針存在lwip_timeouts的對(duì)應(yīng)表項(xiàng)中.   

24、              函數(shù)sys_arch_timeouts返回對(duì)應(yīng)于當(dāng)前任務(wù)的指向定時(shí)事件鏈表的起始指針.該指針存在lwip_timeoutsMAX_LWIP_TASKS中.struct sys_timeouts null_timeouts;struct sys_timeouts * sys_arch_timeouts(void)  u8_t curr_prio;  s16_t err,offset;OS_T

25、CB curr_task_pcb;  null_timeouts.next = NULL;  /獲取當(dāng)前任務(wù)的優(yōu)先級(jí)  err = OSTaskQuery(OS_PRIO_SELF,&curr_task_pcb);  curr_prio = curr_task_pcb.OSTCBPrio;    offset = curr_prio - LWIP_START_PRIO;  /判斷當(dāng)前任務(wù)優(yōu)先級(jí)是不是tcp/ip相關(guān)任務(wù),優(yōu)先級(jí)5-9 &#

26、160;if(offset < 0 | offset >= LWIP_TASK_MAX)      return &null_timeouts;    return &lwip_timeoutsoffset;          注意:楊曄大俠移植的代碼在本函數(shù)有一個(gè)bug.楊曄大俠的移植把上面函數(shù)中的OS_TCB curr_task_tcb定義成了全局變量,使本函數(shù)成為了一個(gè)不可

27、重入函數(shù).我也是在進(jìn)行如下測(cè)試時(shí)發(fā)現(xiàn)了這個(gè)bug.我的開(kāi)發(fā)板上設(shè)置的ip地址是5.我在windows的dos窗口內(nèi)運(yùn)行         ping 5 l 2000 t,不間斷用長(zhǎng)度為2000的數(shù)據(jù)報(bào)進(jìn)行ping測(cè)試,同時(shí)使用tftp客戶端軟件給5下載一個(gè)十幾兆程序,同時(shí)再使用telnet連接5端口7(echo端口),往該端口寫(xiě)數(shù)測(cè)試echo功能.    在運(yùn)行一段時(shí)間以后,開(kāi)發(fā)板

28、進(jìn)入不再響應(yīng).我當(dāng)時(shí)也是經(jīng)過(guò)長(zhǎng)時(shí)間的分析才發(fā)現(xiàn)是因?yàn)樵诘蛢?yōu)先級(jí)任務(wù)運(yùn)行ys_arch_timeouts()時(shí)被高優(yōu)先級(jí)任務(wù)打斷改寫(xiě)了curr_task_tcb的值,從而使sys_arch_timeouts返回的指針錯(cuò)誤,進(jìn)而導(dǎo)致系統(tǒng)死鎖.函數(shù)sys_timeout給當(dāng)前任務(wù)增加一個(gè)定時(shí)事件:void sys_timeout(u32_t msecs, sys_timeout_handler h, void *arg)  struct sys_timeouts *timeouts;  struct sys_timeout *timeout, *t; 

29、; timeout = memp_malloc(MEMP_SYS_TIMEOUT);/為定時(shí)事件分配內(nèi)存  if (timeout = NULL)     return;    timeout->next = NULL;  timeout->h = h;  timeout->arg = arg;  timeout->time = msecs;  timeouts = sys_arch

30、_timeouts();/返回當(dāng)前任務(wù)定時(shí)事件鏈表起始指針  if (timeouts->next = NULL) /如果鏈表為空直接增加該定時(shí)事件    timeouts->next = timeout;    return;     /如果鏈表不為空,對(duì)定時(shí)事件進(jìn)行排序.注意定時(shí)事件中的time存儲(chǔ)的是本事件/時(shí)間相對(duì)于前一事件的時(shí)間的差值  if (timeouts->next->time >

31、; msecs)     timeouts->next->time -= msecs;    timeout->next = timeouts->next;    timeouts->next = timeout;   else     for(t = timeouts->next; t != NULL; t = t->next)    

32、0;  timeout->time -= t->time;      if (t->next = NULL |   t->next->time > timeout->time)   if (t->next != NULL)     t->next->time -= timeout->time;    timeout->

33、;next = t->next;  t->next = timeout;  break;            函數(shù)sys_untimeout從當(dāng)前任務(wù)定時(shí)事件鏈表中刪除一個(gè)定時(shí)事件void sys_untimeout(sys_timeout_handler h, void *arg)    struct sys_timeouts *timeouts;   

34、; struct sys_timeout *prev_t, *t;    timeouts = sys_arch_timeouts();/返回當(dāng)前任務(wù)定時(shí)事件鏈表起始指針    if (timeouts->next = NULL)/如果鏈表為空直接返回                return;    

35、;        /查找對(duì)應(yīng)定時(shí)事件并從鏈表中刪除.    for (t = timeouts->next, prev_t = NULL; t != NULL; prev_t = t, t = t->next)            if (t->h = h) && (t->arg = arg)  

36、                  /* We have a match */            /* Unlink from previous in list */           

37、; if (prev_t = NULL)                timeouts->next = t->next;            else            

38、    prev_t->next = t->next;            /* If not the last one, add time of this one back to next */            if (t->next != NULL)   &#

39、160;            t->next->time += t->time;            memp_free(MEMP_SYS_TIMEOUT, t);            return; &#

40、160;              return;2.2.3  “mbox”的實(shí)現(xiàn):                         (1)mbox的創(chuàng)建   

41、   sys_mbox_t sys_mbox_new(void)        u8_t       ucErr;        PQ_DESCR    pQDesc;    /從消息隊(duì)列內(nèi)存分區(qū)中得到一個(gè)內(nèi)存塊    

42、    pQDesc = OSMemGet( pQueueMem, &ucErr );       if( ucErr = OS_NO_ERR )             /創(chuàng)建一個(gè)消息隊(duì)列        pQDesc->pQ=OSQCreate(&(pQDesc-&

43、gt;pvQEntries0), MAX_QUEUE_ENTRIES );                      if( pQDesc->pQ != NULL )             return pQDesc;   

44、;               return SYS_MBOX_NULL;       (2)發(fā)一條消息給”mbox”  const void * const pvNullPointer = 0xffffffff;void sys_mbox_post(sys_mbox_t mbox, void *data)    INT8U err;&#

45、160;   if( !data )      data = (void*)&pvNullPointer;   err= OSQPost( mbox->pQ, data);在ucos中,如果OSQPost (OS_EVENT *pevent, void *msg)中的msg=NULL 會(huì)返回一條OS_ERR_POST_NULL_PTR錯(cuò)誤.而在lwip中會(huì)調(diào)用sys_mbox_post(mbox,NULL)發(fā)送一條空消息,我們?cè)诒竞瘮?shù)中把NULL變成一個(gè)常量指針0xfff

46、fffff.    (3)從”mbox”中讀取一條消息#define SYS_ARCH_TIMEOUT 0xffffffffvoid sys_mbox_fetch(sys_mbox_t mbox, void *msg)  u32_t time;  struct sys_timeouts *timeouts;  struct sys_timeout *tmptimeout;  sys_timeout_handler h;  void *arg;again:&

47、#160; timeouts = sys_arch_timeouts();/返回當(dāng)前任務(wù)定時(shí)事件鏈表起始指針  if (!timeouts | !timeouts->next) /如果定時(shí)事件鏈表為空    sys_arch_mbox_fetch(mbox, msg, 0);/無(wú)超時(shí)等待消息   else     if (timeouts->next->time > 0)    /如果超時(shí)事件鏈表不為空,而且第一

48、個(gè)超時(shí)事件的time !=0/帶超時(shí)等待消息隊(duì)列,超時(shí)時(shí)間等于超時(shí)事件鏈表中第一個(gè)超時(shí)事件的time,      time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time);     /在后面分析中可以看到sys_arch_mbox_fetch調(diào)用了ucos中的OSQPend系統(tǒng)調(diào)/用從消息隊(duì)列中讀取消息./如果”mbox”消息隊(duì)列不為空,任務(wù)立刻返回,否則任務(wù)進(jìn)入阻塞態(tài)./需要重點(diǎn)說(shuō)明的是sys_arch_mbo

49、x_fetch的返回值time:如果sys_arch_mbox_fetch/因?yàn)槌瑫r(shí)返回,time=SYS_ARCH_TIMEOUT,/如果sys_arch_mbox_fetch因?yàn)槭盏较⒍祷?/time = 收到消息時(shí)刻的時(shí)間-執(zhí)行sys_arch_mbox_fetch時(shí)刻的時(shí)間,單位是毫秒/由于在ucos中任務(wù)調(diào)用OSQPend系統(tǒng)調(diào)用進(jìn)入阻塞態(tài),到收到消息重新開(kāi)始執(zhí)行/這段時(shí)間沒(méi)有記錄下來(lái),所以我們要簡(jiǎn)單修改ucos的源代碼.(后面我們會(huì)看到).     else       /如果定

50、時(shí)事件鏈表不為空,而且第一個(gè)定時(shí)事件的time =0,表示該事件的定時(shí)/時(shí)間到      time = SYS_ARCH_TIMEOUT;        if (time = SYS_ARCH_TIMEOUT)      /一個(gè)定時(shí)事件的定時(shí)時(shí)間到      tmptimeout = timeouts->next;  &#

51、160;   timeouts->next = tmptimeout->next;      h = tmptimeout->h;      arg = tmptimeout->arg;      memp_free(MEMP_SYS_TIMEOUT, tmptimeout);      /從內(nèi)存中釋放該

52、定時(shí)事件,并執(zhí)行該定時(shí)事件中的函數(shù)      if (h != NULL)           h(arg);           /因?yàn)槎〞r(shí)事件中的定時(shí)時(shí)間到或者是因?yàn)閟ys_arch_mbo_fetch超時(shí)到而執(zhí)行到/這里,返回本函數(shù)開(kāi)頭重新等待mbox的消息     

53、60;goto again;     else     /如果sys_arch_mbox_fetch無(wú)超時(shí)收到消息返回/則刷新定時(shí)事件鏈表中定時(shí)事件的time值.      if (time <= timeouts->next->time)   timeouts->next->time -= time;       else   

54、;timeouts->next->time = 0;            u32_t  sys_arch_mbox_fetch(sys_mbox_t mbox, void *data, u32_t timeout)    u32_t     ucErr;    u16_t ucos_timeout;  /在 lwip中 ,timeout的單位是ms    / 在ucosII ,timeout 的單位是timer tick    ucos_timeout = 0;  if(timeout != 0)  ucos_timeout = (timeout )*( OS_TICKS_PER_SEC/1000);  if(ucos_timeout < 1)  

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論