版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
CC2538之Contiki3.0實(shí)驗(yàn):3- CC2538之Contiki3.0實(shí)驗(yàn):4- 閱讀:cc2538cb套件如上圖;地址套件支持TinyOS,Contiki3.0等主流的 n系統(tǒng)網(wǎng)盤-資料區(qū)網(wǎng)盤-資料區(qū)n/Zigbee開 序模塊說備1USBUART/供2Reset復(fù)32.00mm14PinJTAGXDS103V34SMASMA2.4G5Mcu512kFlash/32k6預(yù)留,DIY使用(8CC25387D3(PC0~綠 D2(PC1~黃)D1(PC2~紅8USBCC2538PA0/PA1注①,預(yù)留IO口,如中標(biāo)示為6的外設(shè),間距2.00mm,從左到右分別為:CC2538IOUART、SPI、I2C、SSI、ADC、輸入、輸出等,靈活度高,故用戶可以使用預(yù)留的IO口完成DIY傳感器的接入或其它的總②,cc2538cb節(jié)點(diǎn)采用PL2303USB轉(zhuǎn)串而不是直接使用2538的USB功能;在的驅(qū)動(dòng)對(duì)于虛擬機(jī) 等是免驅(qū)的,能夠更加簡單快速的使Linux/Android,用戶可以O(shè)TG線完成cc2538cb和Android等的接入測試CC2538Contiki3.01-Contiki 博客帖子已經(jīng)介紹了TinyOS編程和實(shí)驗(yàn)例程;下面將來啃一下我一直特別排斥的在contiki-3.0\examples\cc2538cb 一個(gè)c文件,命名test_null.c加入:[cpp][cpp]view #include PROCESS(test_null"我是菜鳥 #warning我是菜11. PROCESS_THREAD(test_null,ev, 先不介紹基本的概念;讓我們繼續(xù);先怎么也讓他編譯過去再說;新建Makefile文件;加入: CONTIKI_PROJECT= all: include CONTIKI includeOK!現(xiàn)在來編譯,啟動(dòng) ,進(jìn)入 ,輸入命令 然后輕敲回車,等待編譯不出意外應(yīng)該會(huì)有一個(gè)“warning我是菜鳥”在s上;打印這個(gè)純粹是知道了下面咱們懶人一把,在編譯命令省去平臺(tái), 下面新建一=cc2538cb現(xiàn)在再來編譯一次,命令輸入和第一次變化了,不需要指定平臺(tái)了,直接輸入命令:make就行了,好了,懶人法成功!總覺得這個(gè)例程代碼空蕩了點(diǎn),編譯了也不想到板子玩,也罷,有三個(gè)led,咱們把它全部點(diǎn)亮,修改代碼 #include #include ," PROCESS_THREAD(test_null,ev, 12.去除#warning再次編譯,生成后可以到板子看看三個(gè)LED燈貌似被不小呵呵,玩笑開到這里,下面讓我們學(xué)下這個(gè)例程:先來看看Makefile文件:CONTIKI_PROJECT=test_null 大家可以回憶一下TinyOS的例程Makefile的編寫應(yīng)該就明白了,編譯App/工程,可以有多個(gè),用空格符分all: 照著抄寫就行CONTIKI= 指定contiki的 ;當(dāng)是contiki-3.0\examples\cc2538cb\null,往前級(jí),正好退到contiki-include$(CONTIKI)/Makefile.include和上一句配合指定文件路徑 文 指定平臺(tái),像作者這類懶人專屬,編譯命令省 文件;我們看到了好像有點(diǎn)和C語言開發(fā)有點(diǎn)陌生的東西來看看contiki-3.0\core\sys\process.h中部分: #ifPROCESS_THREAD(name,ev,\process_thread_##name #definePROCESS(name,\structprocessname={NULL,\11.17.staticPT_THREAD(process_thread_##name(structpt process_data_t25.#define22.#defineprocess_event_tev,\16.#definePROCESS_THREAD(name,ev,process_thread_##name\PROCESS_THREAD(name,ev, \structprocessname={\ #definePROCESS(name, #if! #define\ #else/*AUTOSTART_ENABLE externint #endif/*AUTOSTART_ENABLE\ #define structprocess*constautostart_processes[]={VA_ARGS, #if10.10.#error"CcompilermustsupportVA_ARGS11.有關(guān)otiki的T網(wǎng)上介紹實(shí)在是很多,再者本身確實(shí)也是C語言,我就不啰嗦了;需要參考文檔網(wǎng)盤contikipooheads說明.pdf;大家需要注意看這篇文檔的5.3部分;在O_THD中不要有swich的代碼;可以自己去測試編寫后的編譯看看報(bào)出什么;文檔原文依賴編譯器檢測,大部分的編譯器并不會(huì)報(bào)錯(cuò)....我們現(xiàn)在使用了Contiki瞎寫了一份幾乎沒有任何作用的代碼,下一次我將給大家編寫一次類似TinyOS的傳感器部分;了解Contiki和TinyOS的事件驅(qū)制;CC2538之Contiki3.0實(shí)驗(yàn):2-PROCESS你不懂閱讀C代碼的傷悲相信不少朋友在Contiki查閱了不少帖子和資料,但是我只能說一句,貌似沒多大用啊,看了很多的帖子發(fā)現(xiàn)還是理解不了Contiki的設(shè)計(jì);真心很麻煩的東東,本科生們就更加痛苦了,這個(gè)OS是這么麻煩,為什么這么說呢,沒記錯(cuò)我本科的時(shí)候的C語言基本知識(shí)就是會(huì)點(diǎn)結(jié)構(gòu)體;也許時(shí)代進(jìn)步很多學(xué)生的專業(yè)知識(shí)很扎實(shí)!回想一下TinyOS,代碼的閱讀是那么舒心,整個(gè)代碼也根本談POST在全sheude數(shù)組元素中存下ID號(hào),POLL執(zhí)行取出ID號(hào),然后調(diào)用SWITCH(ID);case下面是ID號(hào)對(duì)應(yīng)的函數(shù),代碼分析簡單;看不懂nesC也可以通過轉(zhuǎn)成app.c后從main函數(shù)查看任務(wù)是怎樣調(diào)度的;Contiki對(duì)于新手則不像TinyOS那么簡單,C語言的技巧應(yīng)用的淋漓盡致;C不過關(guān)的朋友們下面還是就先前第一個(gè)例程開始閱讀代碼;test_null.c中: #ifPROCESS_THREAD(name,ev, #ifPROCESS_THREAD(name,ev,\process_thread_##name\structprocessname={\ #definePROCESS(name, #definePROCESS(name,\ PROCESS_THREAD(name,ev,\ structprocessname={NULL,\ 11. structprocess structprocess #if #definePROCESS_NAME_STRING(process) constchar PT_THREAD((*thread)(structpt*,process_event_t, structpt unsignedcharstate,12.core/sys/process.h中定義: #definePROCESS_THREAD(name,ev, process_event_tev,process_data_t staticPT_THREAD(process_thread_##name(structpt 現(xiàn)在咱們需要看的是PT_THREAD宏定義了: #definePT_THREAD(name_args)char上面展 staticcharprocess_thread_##name(structpt\process_data_tprocess_event_tev,好了,現(xiàn)在我們清楚了這些玩意的意思,當(dāng)然我就不分析了,大家在使 之前必須是C語言功底深厚不清楚的朋友提示一下函數(shù)指針 #if! #if! #define\ #else/*AUTOSTART_ENABLE externint 11.10.#error"CcompilermustsupportVA_ARGS #endif/*AUTOSTART_ENABLE\ #define structprocess*constautostart_processes[]={VA_ARGS, #if在contiki_main中調(diào)用: 看一下 * int for(i=0;processes[i]!=NULL;++i) PRINTF("autostart_start:startingprocess'%s'\n",processes[i]- 10. #define #definePT_BEGIN(pt){charPT_YIELD_FLAG=1;if(PT_YIELD_FLAG){;}core/sys/lc.h #define簡寫 #definePT_BEGIN(pt){charPT_YIELD_FLAG=1;if(PT_YIELD_FLAG){;}(pt)->注意符號(hào)'{' #define #definePT_END(pt)LC_END((pt)->lc);PT_YIELD_FLAG=0; PT_INIT(pt);returnPT_ENDED; #definePT_INIT(pt) <spanstyle="font-family:Arial,Helvetica,sans-serif;background-color:rgb(255,255,255);"> core/sys/lc.h #define #define和上面的注意一樣是符號(hào)呵呵,不多說了,大家應(yīng)該清楚這兩個(gè)玩意應(yīng)該是配合使用了的WAIT,YIELD,WAITWHILE,EXIT,不做介紹,代碼的閱讀真心累這是沒有辦法的事情,沒有文檔能夠說清楚它的設(shè)計(jì)思想,最好是自己去理解!5,contiki-main.c文件,查看intmain(void)函數(shù)函數(shù),去除煩人的代碼 10.#if 14.#endif/*NETSTACK_CONF_WITH_IPV6 while(1) 22.先拋開queuebuf_init(以后必須學(xué)習(xí),至少也應(yīng)該提供內(nèi)存的申請(qǐng)使用和釋放)剩 lastevent= nevents=fevent= #if process_maxevents=10.#endif/*PROCESS_CONF_STATS process_current=process_list=14. process_start(structprocess*p,process_data_t structprocess /*Firstmakesurethatwedon'ttrytostartaprocessthat alreadyrunning. for(q=process_list;q!=p&&q!=NULL;q=q- /*Ifwefoundtheprocessontheprocesslist,webailout. if(q==p) /*Putontheprocs p->next= process_list= p->state= PRINTF("process:starting'%s'\n", /*Postasynchronousinitializationeventtotheprocess. 28.process_post_synch和process_post的區(qū)別我就不介紹了,自己可以對(duì)照代碼閱讀;概念那些我最不擅長,一句話,想學(xué)會(huì)這個(gè)系統(tǒng),就得不斷的去啃代碼在core/sys/process.c中 if(poll_requested)} 15. returnnevents+ /*Processoneeventfromthequeue/*Processpollevents. do_poll和do_event的代碼自行閱讀,但是本質(zhì)是在處理結(jié)構(gòu)體值后call_process(...)這個(gè)才是正主了在core/sys/process.c static call_process(structprocess*p,process_event_tev,process_data_t int #if if(p->state==PROCESS_STATE_CALLED) printf("process:process'%s'calledagainwithevent%d\n",PROCESS_NAME_STRING(p),ev); 11.#endif/*DEBUG if((p->state&PROCESS_STATE_RUNNING) p->thread!=NULL) PRINTF("process:callingprocess'%s'withevent%d\n",PROCESS_NAME_STRING(p),ev); process_current= p->state= ret=p->thread(&p->pt,ev, if(ret==PT_EXITED ret==PT_ENDED ev==PROCESS_EVENT_EXIT) exit_process(p, }else p->state= 26.其中的ret=p->thread(&p->pt,ev,data);大家參考test_null.cPROCESS的寫法和我提示的函數(shù)指針不知不覺都寫了這么多字了,算了,下一次再帶來編程事件的理解;至少讓我先理解Contiki是怎么設(shè)計(jì)思想然后再去編寫代碼;現(xiàn)在已經(jīng)戰(zhàn)戰(zhàn)兢兢了,這個(gè)系統(tǒng)說是purec,但是還是不太理解他的所謂的thread,現(xiàn)在就已經(jīng)接觸了不少編程了,大家知道在最后編寫復(fù)雜應(yīng)用如果吃不透他的設(shè)計(jì)思想一旦代碼有BUG,是設(shè)想的;TinyOS,哪有這么多!CC2538之Contiki3.0實(shí)驗(yàn):3-通過對(duì)PEOCESS的一些亂講,應(yīng)該有一點(diǎn)可以知道就是我們每編寫一個(gè)PROCESS_THREAD(...)實(shí)際就是弄出了一個(gè)(structprocess;大家可以理解是不是每一個(gè)PROCESS_THREAD或者其他的都會(huì)在cmpile的時(shí)候產(chǎn)生一個(gè)全局的struct變量;回憶一下: structprocess structprocess #if #definePROCESS_NAME_STRING(process) constchar PT_THREAD((*thread)(structpt*,process_event_t, structpt unsignedcharstate,12.至此我們至少CTRL+C/CTRL+V寫出自己的小的測試程序,我們不管是學(xué)習(xí)TinyOS或者Contiki實(shí)際并不是只是make然后,驗(yàn)證結(jié)果就完事了,TinyOS和Contiki都是event驅(qū)動(dòng);RIOT在Contiki介紹完后會(huì)重點(diǎn)去介紹;個(gè)人還是比較喜歡他的風(fēng)格一點(diǎn);回憶TinyOS的event是很簡單的,采用signal拋出事件,使用者處理Contiki的event咱們慢慢來看;我們現(xiàn)在在test_null基礎(chǔ)上再編寫一次,達(dá)首先在:core/sys/process.h中 typedefunsignedchar typedefunsignedchar typedefvoid我們這次需要用到的函數(shù)為: process_post(structprocess*p,process_event_tev,process_data_t staticprocess_num_events_t if(PROCESS_CURRENT()==NULL) PRINTF("process_post:NULLprocesspostsevent%dtoprocess'%s',nevents%d\n", }else PRINTF("process_post:Process'%s'postsevent%dtoprocess'%s',nevents%d\n", p==PROCESS_BROADCAST?"<broadcast>":PROCESS_NAME_STRING(p), if(nevents==PROCESS_CONF_NUMEVENTS)17.#if if(p==PROCESS_BROADCAST) printf("softpanic:eventqueueisfullwhenbroadcastevent%dwaspostedfrom%s\n",ev,PROCESS_NAME_STRING(process_current)); }else printf("softpanic:eventqueueisfullwhenevent%dwaspostedto%sfrom%s\n",ev,PROCESS_NAME_STRING(p),PROCESS_NAME_STRING(process_current); 23.#endif/*DEBUG return snum=(process_num_events_t)(fevent+nevents)% events[snum].ev= events[snum].data= events[snum].p= 34.#if在core/sys/process.c ) if(nevents>process_maxevents) 41. return38.#endif/*PROCESS_CONF_STATSprocess_maxevents=下面修改test_null.c文 #include #include staticprocess_event_t PROCESS(test_null我是菜鳥 PROCESS(test_event我還是菜鳥 10.PROCESS_THREAD(test_null,ev,11. event_xxoo= process_post(&test_event,event_xxoo, 16.18.PROCESS_THREAD(test_event,ev,19. PROCESS_WAIT_EVENT_UNTIL(ev== 26.看到不認(rèn)識(shí)的家伙了在core/sys/process.c中 return 在 中: #define #definePROCESS_WAIT_EVENT_UNTIL(c)PT_TIELD_UNTIL在core/sys/pt.h中 #definePT_YIELD_UNTIL(pt, do PT_YIELD_FLAG= if((PT_YIELD_FLAG==0)||!(cond)) return }我們的設(shè)計(jì)思想是,test_null拋出事件,test_event獲取該事件后亮燒寫到cc2538cb節(jié)點(diǎn)后,contiki-main先將三個(gè)led燈fade,流水燈效果;然后咱們發(fā)現(xiàn)三個(gè)led燈點(diǎn)亮了說明test_event的leds_on(LEDS_ALL);得到了執(zhí)行,事件的測試在此大家可以再去想一下Contiki的thread模型, 到底干了什么 是否支持咱們回溯事件的拋出者是誰有一個(gè)例程我們最好去學(xué)習(xí)參考,以便以后寫出自己的應(yīng)用,那就是er_timer;可以參考2530的代碼或者 下的 #include#include#include<stdio.h>/*Forprintf()-staticstructetimeret_staticstructetimerstaticuint16_tstaticuint8_t- o_world_process, oworldPROCESS(blink_process,"LEDblink o_world_process,- o_world_process,ev,{etimer_set(&et_o,CLOCK_SECOND*count=while(1)if(ev==PROCESS_EVENT_TIMER)printf("Sensorsays#%u\n",}} 34.35.-36.PROCESS_THREAD(blink_process,ev,37. blinks= while(1) PROCESS_WAIT_EVENT_UNTIL(ev== leds_on(blinks& printf("Blink...(state%0.2X)\n", 54.55. -其中的代碼可以自己去閱讀,參考process閱讀;我們看到兩種事件 ifif(ev== PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_THREAD(etimer_process,ev,structetimer*t, PROCESS_THREAD(etimer_process,ev,structetimer*t, timerlist=while(1)if(ev==PROCESS_EVENT_EXITED)structprocess*p=while(timerlist!=NULL&&timerlist->p==p)timerlist=timerlist- if(timerlist!=NULL)t=while(t->next!=NULL)if(t->next->p==p)t->next=t->next-}t=t- }elseif(ev!=PROCESS_EVENT_POLL) u=for(t=timerlist;t!=NULL;t=t->next)if(processpost(t->p,PROCESSEVENTTIMER,t)==PROCESS_ERR_OK)/*Resetthe oftheeventtimer,tosignalthatetimerhasexpired.Thisislatercheckedinetimer_expired()function.t->p=if(u!=NULL)u->next=t-}elsetimerlist=t- t->next= goto }else u= 63.貌似有了PROCESS_EVENT_TIMER的大家可以自己去思考一下,do_poll和do_eventPROCESS_EVENT_TIMER的定義在core/sys/process.h #define 在這里我們基本上能夠總算接觸到了Contiki的event,的自己去看代碼理解,也許你需要一個(gè)sourceinghit來閱讀代碼,而不用像我一樣一個(gè)一個(gè)文件打開查看;雖然還是覺得有點(diǎn);只能說再此我并沒有感覺到C語言的Contiki的優(yōu)勢!并不是我黑Contiki,我移植TinyOS很多地方也是參考的Contiki;現(xiàn)在能體會(huì)到的就是編寫應(yīng)用還是相對(duì)要復(fù)雜可以自己結(jié)合前面幾篇文檔對(duì)照代碼形成自理解;現(xiàn)在的作者也是Cntki的菜鳥但是應(yīng)用神馬的就得從基礎(chǔ)做起;不得不說的是cc2538dk平臺(tái)本質(zhì)是TI的SmartRF06EB板子,的代碼(驅(qū)動(dòng)部分)主要是參考他修改而來,3.0代碼和2.7代碼部分在底層變動(dòng)較大;高手們可以互相印證,至少我比較喜歡2.7的啟動(dòng)文件的寫法CC2538之Contiki3.0實(shí)驗(yàn):4-相信大家看完前面作者的瞎掰也迷茫了,沒錯(cuò),Contiki的學(xué)習(xí)靠自己的努力辛苦,多去閱讀代碼,正如套用有一本物聯(lián)網(wǎng)的書籍講的“你不會(huì)C語言,那你來這干嘛”;面的基本介紹大家Contiki的例程自我編寫;Makefile編寫,makesizeof(),process等等占用大小,以決定大家項(xiàng)目的資源分配,了解eventcontiki-main<==>main.c;閱讀啟動(dòng)文件,makefile文件已方便以后自己添加c庫文件;其次慢慢的去了解對(duì)于Contiki的條件編譯參數(shù);Contiki編程的一些需要避開的地方;我們清楚的知道先不談Contiki的event驅(qū)制拋開應(yīng)用層的rime/uip,他的應(yīng)該是pt(叫process也好,thread也好);編程的注意事項(xiàng)也是因他而來,如switch不可出現(xiàn)PROCESS中;PROCESS中慎用局部變量(無上下文保存/不同于函數(shù)的調(diào)用當(dāng)ISR發(fā)生的時(shí)候,局部變量等是保存的,處ISR回來繼續(xù)運(yùn)行)可以用static修飾,Contiki的系統(tǒng)庫很多這樣做的,共享/臨界資源的保護(hù);有得必有失;Contikimt則根據(jù)自己的需求選擇使用;TinyOS大家不要理解成thread模式;現(xiàn)thread,實(shí)際上也確實(shí)用不著;TinyOScthread,有些廠家也給出了代碼,但是始終不溫不火;因?yàn)閷?duì)于應(yīng)用這些根本用不上;編程應(yīng)該越簡單越好,技巧用得越多帶來的BUG可能越多,也越難讓大家都讀懂我們的分析是Contiki是在編譯的時(shí)候給了process結(jié)構(gòu)體初值,對(duì)于大家的free而是類似6lon的先弄一個(gè)靜態(tài)數(shù)組,然后自己編寫ip_malloc/ip_free;當(dāng)然Contiki也有內(nèi)存操作部分;TinyOS有Poll;quene;fragpoll等現(xiàn)在讓我們閱讀一下contiki-main.c(cc2538cb/cc2538dk)部分,發(fā)現(xiàn)button_sensor_init();呵呵,使用TI評(píng)估板或者國內(nèi)各種山寨TI評(píng)估板的朋友很熟悉了;TI這個(gè)家伙的常規(guī)做法按鍵;我都不清楚焊接按鍵干什么;對(duì)于cc2538cb節(jié)點(diǎn),大家肯定疑惑為什么不引出按鍵;我反問一句;已經(jīng)引出IO口;要實(shí)現(xiàn)按鍵本質(zhì)是IO口的電平變化;拿一根導(dǎo)線/鑷子又或者指甲剪/挖耳勺;將引出IO口短接到vdd(引出)或gnd(引出)不就可以了?ADC也是如測量電源和地;當(dāng)然也可以讓一個(gè)IO口輸出電平;短接讓另一個(gè)IO口ADC值;在contiki-3.0\platform\cc2538cb\dev下的button-sensor.csmartrf-sensors.c出現(xiàn) SENSORS_SENSOR(button_left_sensor,BUTTON_SENSOR,NULL,config_left, SENSORS_SENSOR(button_right_sensor, SENSORS_SENSOR(button_left_sensor,BUTTON_SENSOR,NULL,config_left, SENSORS_SENSOR(button_right_sensor,BUTTON_SENSOR,NULL,config_right, SENSORS_SENSOR(button_up_sensor,B
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ù)合同簡易版2篇
- 攪拌機(jī)銷售合同范例3篇
- 新版視頻剪輯視頻合同3篇
- 新最完整房屋買賣合同范文3篇
- 教育培訓(xùn)服務(wù)合同協(xié)議書3篇
- 放牧合同書樣本全新版3篇
- 工業(yè)振動(dòng)控制設(shè)備安裝工程合同書3篇
- 斷橋鋁門窗安裝招標(biāo)3篇
- 數(shù)量責(zé)任聲明3篇
- 撤銷委托決定3篇
- 2024-2030年中國金華火腿腌制項(xiàng)目可行性研究報(bào)告
- 2024-2030年中國家用小家電項(xiàng)目可行性研究報(bào)告
- 《隧道工程監(jiān)控量測》課件
- 環(huán)保項(xiàng)目荒山租賃協(xié)議模板
- xx單位政務(wù)云商用密碼應(yīng)用方案V2.0
- 2024年度校園體育設(shè)施維修保養(yǎng)合同
- 機(jī)電一體化項(xiàng)目職業(yè)技能大賽試題(SX-815Q)
- 電廠應(yīng)急物資培訓(xùn)
- 2025年春九年級(jí)語文下冊(cè) 第三單元綜合測試卷(人教陜西版)
- 吊裝起重作業(yè)安全培訓(xùn)課件
- 行政人員的培訓(xùn)
評(píng)論
0/150
提交評(píng)論