




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Linux驅(qū)動及應(yīng)用設(shè)計(jì)中智訊培訓(xùn)中心2013-5Linux設(shè)備驅(qū)動介紹主要議題*2Linux字符設(shè)備框架LED字符驅(qū)動分析Linux驅(qū)動調(diào)試設(shè)備驅(qū)動程序3系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,設(shè)備驅(qū)動程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口。設(shè)備驅(qū)動程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié),這樣在應(yīng)用程序看來,硬件設(shè)備只是一個設(shè)備文件,應(yīng)用程序可以象操作普通文件一樣對硬件設(shè)備進(jìn)行操作。應(yīng)用程序驅(qū)動程序設(shè)備writeread工作原理4用戶進(jìn)程利用系統(tǒng)調(diào)用在對設(shè)備文件進(jìn)行諸如read/write操作時,系統(tǒng)調(diào)用通過設(shè)備文件的主設(shè)備號找到相應(yīng)的設(shè)備驅(qū)動程序,然后讀取這個數(shù)據(jù)結(jié)構(gòu)相應(yīng)的函數(shù)指針,接著把控制權(quán)交給該函數(shù)。編寫設(shè)備驅(qū)動程序的主要工作就是編寫子函數(shù),并填充file_operations的各個域。設(shè)備驅(qū)動程序特點(diǎn)5核心代碼:設(shè)備驅(qū)動程序是核心的一部分,像核心中其他的代碼一樣,出錯將導(dǎo)致系統(tǒng)的嚴(yán)重?fù)p傷。一個編寫不當(dāng)?shù)脑O(shè)備驅(qū)動程序甚至能夠使系統(tǒng)崩潰導(dǎo)致文件系統(tǒng)的破壞和數(shù)據(jù)的丟失;標(biāo)準(zhǔn)接口:設(shè)備驅(qū)動程序必須為Linux核心或者其從屬的子系統(tǒng)提供一個標(biāo)準(zhǔn)的接口;核心機(jī)制:設(shè)備驅(qū)動程序可以使用標(biāo)準(zhǔn)核心服務(wù)比如內(nèi)存分配、中斷發(fā)送和等待對列等;動態(tài)可加載:多數(shù)的Linux設(shè)備驅(qū)動程序可以在核心模塊發(fā)出加載請求時進(jìn)行加載,同時在不使用設(shè)備時進(jìn)行卸載,這樣核心可以有效地利用系統(tǒng)的資源可配置:Linux設(shè)備驅(qū)動屬于核心的一部分,用戶可以根據(jù)自己的需要進(jìn)行配置來選擇適合自己的驅(qū)動設(shè)備驅(qū)動的功能6對設(shè)備初始化和釋放把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù)讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請求的數(shù)據(jù)檢測和處理設(shè)備出現(xiàn)的錯誤用戶態(tài)與內(nèi)核態(tài)7Linux運(yùn)轉(zhuǎn)在兩種模式下,一種是用戶態(tài),另一種是內(nèi)核態(tài)。內(nèi)核態(tài)有較高的權(quán)限,可以控制處理器內(nèi)存的映射和分配方式,訪問外設(shè)空間和處理器狀態(tài)寄存器,控制中斷等。用戶態(tài)只能運(yùn)行系統(tǒng)上的應(yīng)用程序。驅(qū)動程序作為系統(tǒng)內(nèi)核的一部分,工作在內(nèi)核態(tài)。通過get_user,put_user,copy_from_user,copy_to_user等函數(shù)實(shí)現(xiàn)應(yīng)用程序和驅(qū)動程序之間傳送數(shù)據(jù)(指針)。Linux設(shè)備驅(qū)動分類8網(wǎng)絡(luò)設(shè)備驅(qū)動:Linux的網(wǎng)絡(luò)系統(tǒng)主要是基于BSDunix的socket機(jī)制字符設(shè)備驅(qū)動:以字節(jié)為單位逐個進(jìn)行I/O操作;存取時不需要占用緩存塊設(shè)備驅(qū)動:讀寫都支持緩存,并且塊設(shè)備必須能夠隨機(jī)存取,還支持安裝文件系統(tǒng)設(shè)備驅(qū)動字符設(shè)備驅(qū)動塊設(shè)備驅(qū)動網(wǎng)絡(luò)設(shè)備驅(qū)動設(shè)備文件9Linux抽象了對硬件的處理,所有的硬件設(shè)備都可以作為普通文件一樣來看待可以使用和操作文件相同的、標(biāo)準(zhǔn)的系統(tǒng)調(diào)用接口來完成打開、關(guān)閉、讀寫和I/O控制操作對用戶來說,設(shè)備文件與普通文件并無區(qū)別字符設(shè)備和塊設(shè)備是通過文件節(jié)點(diǎn)訪問的。在Linux的文件系統(tǒng)中,可以找到(或者使用mknod創(chuàng)建)設(shè)備對應(yīng)的文件名,稱這種文件為設(shè)備文件。主設(shè)備號和次設(shè)備號10主設(shè)備號:標(biāo)識該設(shè)備的種類,也標(biāo)識了該設(shè)備所使用的驅(qū)動程序主設(shè)備號的范圍只能是1-255Linux內(nèi)核支持動態(tài)分配主設(shè)備號次設(shè)備號:標(biāo)識使用同一設(shè)備驅(qū)動程序的不同硬件設(shè)備同一個驅(qū)動程序可以管理多個設(shè)備,它們依靠次設(shè)備號來區(qū)別。次設(shè)備號只在驅(qū)動程序內(nèi)部使用,系統(tǒng)內(nèi)核直接把次設(shè)備號傳遞給驅(qū)動程序,由驅(qū)動程序去管理。udev設(shè)備文件系統(tǒng)11Linux2.6的內(nèi)核引進(jìn)了udev設(shè)備文件系統(tǒng),拋棄了對devfs(Linux2.4)的支持,devfs和udev是生成設(shè)備文件節(jié)點(diǎn)的兩種方法,devfs工作在內(nèi)核態(tài),udev工作在用戶空間,/dev是設(shè)備文件的存放目錄Linux2.6下udev支持proc和sysfs等等虛擬文件系統(tǒng);sysfs文件系統(tǒng)把連接在系統(tǒng)上的設(shè)備和總線組織成一個分級的文件,它們可以在用戶空間存取Linux2.6內(nèi)核通過一系列的數(shù)據(jù)結(jié)構(gòu)定義了設(shè)備模型,設(shè)備模型與sysfs文件系統(tǒng)中的目錄和文件存在在一一對應(yīng)的關(guān)系,udev可以利用sysfs中記錄的信息和定義規(guī)則并提取主設(shè)備號和次設(shè)備號動態(tài)創(chuàng)建/dev設(shè)備文件節(jié)點(diǎn)配置設(shè)備文件系統(tǒng)12在linux2.6內(nèi)核中,設(shè)備文件系統(tǒng)可在配置內(nèi)核時定制。Linux2.6內(nèi)核配置層次Filesystems->Pseudofilesystem->sysfsfilesystemsupport和/procfilesystemsupportLinux設(shè)備驅(qū)動介紹主要議題*13Linux字符設(shè)備框架LED字符驅(qū)動分析Linux驅(qū)動調(diào)試設(shè)備驅(qū)動程序的開發(fā)過程14嵌入式Linux系統(tǒng)驅(qū)動程序開發(fā)與普通Linux開發(fā)沒有區(qū)別??梢栽谟布a(chǎn)廠家或者Internet上尋找驅(qū)動程序,也可以根據(jù)相近的硬件驅(qū)動程序來改寫,這樣可以加快開發(fā)速度。實(shí)現(xiàn)一個嵌入式Linux設(shè)備驅(qū)動的大致流程如下:查看原理圖,理解設(shè)備的工作原理。一般嵌入式處理器的生產(chǎn)商提供參考電路,也可以根據(jù)需要自行設(shè)計(jì)。定義設(shè)備號。設(shè)備由一個主設(shè)備號和一個次設(shè)備號來標(biāo)識。主設(shè)備號惟一標(biāo)識了設(shè)備類型,即設(shè)備驅(qū)動程序類型,它是塊設(shè)備表或字符設(shè)備表中設(shè)備表項(xiàng)的索引。次設(shè)備號僅由設(shè)備驅(qū)動程序解釋,區(qū)分被一個設(shè)備驅(qū)動控制下的某個獨(dú)立的設(shè)備實(shí)現(xiàn)初始化函數(shù)。在驅(qū)動程序中實(shí)現(xiàn)驅(qū)動的注冊和卸載設(shè)備驅(qū)動程序的開發(fā)過程15設(shè)計(jì)所要實(shí)現(xiàn)的文件操作,定義file_operations結(jié)構(gòu)實(shí)現(xiàn)所需的文件操作調(diào)用,如read、write等實(shí)現(xiàn)中斷服務(wù),并用request_irq向內(nèi)核注冊,中斷并不是每個設(shè)備驅(qū)動所必需編譯該驅(qū)動程序到內(nèi)核中,或者用insmod命令加載模塊測試該設(shè)備,編寫應(yīng)用程序,對驅(qū)動程序進(jìn)行測試Linux設(shè)備驅(qū)動程序結(jié)構(gòu)16staticints5pv210_led_open(structinode*inode,structfile*filp){設(shè)備打開時的操作…}staticints5pv210_led_release(structinode*inode,structfile*filp){設(shè)備關(guān)閉時的操作…}Linux設(shè)備驅(qū)動程序的代碼結(jié)構(gòu)大致可以分為如下幾個部分:驅(qū)動程序的注冊與注銷、設(shè)備的打開與釋放、設(shè)備的讀寫操作、設(shè)備的控制操作、設(shè)備的中斷和輪詢處理一個最簡單字符驅(qū)動程序,由下面6個函數(shù)和1個結(jié)構(gòu)體就可組成Linux設(shè)備驅(qū)動程序結(jié)構(gòu)17staticints5pv210_led_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){設(shè)備寫入時的操作…}staticints5pv210_led_read(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){讀取設(shè)備時的操作…}staticstructfile_operationsmy_fops={對文件操作結(jié)構(gòu)體成員定義初始值…}staticints5pv210_led_write(structfile*file,constchar*buffer,size_tcount,loff_t*ppos){設(shè)備寫入時的操作…}Linux設(shè)備驅(qū)動程序結(jié)構(gòu)18staticvoid__exits5pv210_led_exit(void){刪除設(shè)備節(jié)點(diǎn),注銷設(shè)備…}文件操作結(jié)構(gòu)體structfile_operations{
structmodule*owner;
loff_t(*llseek)(structfile*,loff_t,int);
ssize_t(*read)(structfile*,char*,size_t,loff_t*);
ssize_t(*write)(structfile*,constchar*,size_t,loff_t*);
int(*readdir)(structfile*,void*,filldir_t);
unsignedint(*poll)(structfile*,structpoll_table_struct*);
int(*ioctl)(structinode*,structfile*,unsignedint,unsignedlong);
int(*mmap)(structfile*,structvm_area_struct*);
int(*open)(structinode*,structfile*);
……}19文件操作函數(shù)簡介20llseek(file,offset,whence):修改文件的讀寫指針read(file,buf,count,offset):從設(shè)備文件的offset處開始讀出count個字節(jié),然后增加*offset的值write(file,buf,count,offset):從設(shè)備文件的offset處寫入count個字節(jié),然后增加*offset的值ioctl(inode,file,cmd,arg):向一個硬件設(shè)備發(fā)命令,對設(shè)備進(jìn)行控制文件操作函數(shù)簡介21mmap(file,vma):將設(shè)備空間映射到進(jìn)程地址空間open(inode,file):打開并初始化設(shè)備release(inode,file):關(guān)閉設(shè)備并釋放資源fsync(file,dentry):實(shí)現(xiàn)內(nèi)存與設(shè)備之間的同步通信fasync(file,on):實(shí)現(xiàn)內(nèi)存與設(shè)備之間的異步通信Linux設(shè)備驅(qū)動程序結(jié)構(gòu)22struct
file_operationss5pv210_led_ctrl_ops={ .owner =THIS_MODULE,
.open =s5pv210_led_open,
.write =
s5pv210_led_write, .read =s5pv210_led_read, .release =s5pv210_led_release,};Linux2.6內(nèi)核使用C99標(biāo)準(zhǔn)初始化結(jié)構(gòu)體加載模塊的一般標(biāo)準(zhǔn)形式為卸載模塊的一般標(biāo)準(zhǔn)形式為模塊的加載和卸載23/*初始化設(shè)備*/staticint__initinitialization_funtion(void){}module_init(initialization_funtion);/*卸載設(shè)備*/staticvoid__exitexit_funtion(void){}module_exit(exit_funtion);Linux設(shè)備驅(qū)動介紹主要議題*24Linux字符設(shè)備框架LED字符驅(qū)動分析Linux驅(qū)動調(diào)試LED硬件連接圖25頭文件和變量聲明26/*頭文件聲明*/#include<linux/init.h>#include<linux/module.h>#include<linux/kernel.h>#include<linux/sched.h>#include<asm/uaccess.h>#include<plat/gpio-cfg.h>#include<linux/gpio.h>#include<linux/cdev.h>#include<linux/fs.h>#include<linux/device.h>#defineDEVICE_LIST"led_test“ /*定義設(shè)備目錄*//*定義設(shè)備節(jié)點(diǎn)*/#defineDEVICE_NODE"led_light"#defineLED10x01#defineLED20x02#defineLED30x04#defineLED40x08staticdev_tnum_dev; /*定義申請?jiān)O(shè)備號的變量*/staticstructcdev*cdev_p; /*定義字符設(shè)備的變量*/staticstructclass*led_dev_class;staticunsignedcharled_status=0;/*定義一個LED狀態(tài)的全局變量*/s5pv210_led_open和s5pv210_led_release函數(shù)會在設(shè)備打開和關(guān)閉時被調(diào)用,其工作很簡單,僅僅執(zhí)行兩個函數(shù)try_module_get(THIS_MODULE)和module_put(THIS_MODULE)。這兩個函數(shù)負(fù)責(zé)記錄(增加或者減少)設(shè)備模塊被使用的情況,防止當(dāng)有應(yīng)用程序使用驅(qū)動程序時,此模塊被意外地卸載打開和關(guān)閉操作27staticints5pv210_led_open(structinode*inode,structfile*filp){try_module_get(THIS_MODULE);return0;
}staticints5pv210_led_release(structinode*inode,structfile*filp){module_put(THIS_MODULE);return0;}設(shè)置LED燈狀態(tài)28staticvoidset_led_status(unsignedcharstatus){
/*表示LED燈的狀態(tài)是否發(fā)生變化*/
unsignedcharled_status_changed;
led_status_changed=led_status^(status&0xF);
led_status=(status&0xF);
/*如果4個LED燈的狀態(tài)發(fā)生了變化*/
if(led_status_changed!=0x00){
/*判斷是否改變LED1燈的狀態(tài)*/
if(led_status_changed&LED1){
if(led_status&LED1)
gpio_direction_output(S5PV210_GPJ2(0),0);
else
gpio_direction_output(S5PV210_GPJ2(0),1);}/*判斷是否改變LED2燈的狀態(tài)*/if(led_status_changed&LED2){if(led_status&LED2)gpio_direction_output(S5PV210_GPJ2(1),0);elsegpio_direction_output(S5PV210_GPJ2(1),1);}/*判斷是否改變LED3燈的狀態(tài)*/if(led_status_changed&LED3){if(led_status&LED3)gpio_direction_output(S5PV210_GPJ2(2),0);elsegpio_direction_output(S5PV210_GPJ2(2),1);}
/*判斷是否改變LED4燈的狀態(tài)*/if(led_status_changed&LED4){if(led_status&LED4)gpio_direction_output(S5PV210_GPJ2(3),0);elsegpio_direction_output(S5PV210_GPJ2(3),1);}}}copy_to_user和copy_from_user函數(shù)29unsignedlongcopy_to_user(void__user*to,constvoid*from,unsignedlongn)功能:從內(nèi)核空間拷貝一塊兒數(shù)據(jù)到用戶空間;To:
目標(biāo)地址,這個地址是用戶空間的地址;From:
源地址,這個地址是內(nèi)核空間的地址;N:
將要拷貝的數(shù)據(jù)的字節(jié)數(shù)返回值:如果數(shù)據(jù)拷貝成功,則返回零;否則,返回沒有拷貝成功的數(shù)據(jù)字節(jié)數(shù)unsignedlongcopy_from_user(void*to,constvoid__user*from,unsignedlongn)功能:從用戶空間拷貝數(shù)據(jù)到內(nèi)核空間To:
目標(biāo)地址,這個地址是內(nèi)核空間的地址;From:
源地址,這個地址是用戶空間的地址;返回者:如果數(shù)據(jù)拷貝成功,則返回零;否則,返回沒有拷貝成功的數(shù)據(jù)字節(jié)數(shù)寫入操作30staticssize_ts5pv210_led_write(structfile*file,constchar*buf,size_tcount,loff_t*f_ops){unsignedcharstatus;if(count==1){/*向用戶空間寫數(shù)據(jù),如果寫失敗,則返回錯誤*/if(copy_from_user(&status,buf,sizeof(unsignedchar)))return-EFAULT;set_led_status(status);returnsizeof(unsignedchar);}elsereturn-EFAULT;}讀狀態(tài)操作31staticssize_ts5pv210_led_read(structfile*file,char*buf,size_tcount,loff_t*f_ops){/*從用戶空間讀取數(shù)據(jù),獲取LED燈的狀態(tài)*/copy_to_user(buf,(char*)&led_status,sizeof(unsignedchar));returnsizeof(unsignedchar);}設(shè)備控制初始化32staticints5pv210_led_ctrl_init(void){interr;structdevice*temp=NULL;unsignedintgpio;
/*GPIO口的初始化LED1,LED2,LED3,LED4,設(shè)置為輸出*/for(gpio=S5PV210_GPJ2(0);gpio<S5PV210_GPJ2(4);gpio++){s3c_gpio_cfgpin(gpio,S3C_GPIO_SFN(1));}/*動態(tài)注冊led_test設(shè)備,num_dev為動態(tài)分配出來的設(shè)備號(主設(shè)備號+次設(shè)備號)*/err=alloc_chrdev_region(&num_dev,0,1,DEVICE_LIST);if(err<0){printk(KERN_ERR"LED:unabletogetdevicename%d/n",err);returnerr;}cdev_p=cdev_alloc(); /*動態(tài)分配cdev內(nèi)存空間*/cdev_p->ops=&s5pv210_led_ctrl_ops;err=cdev_add(cdev_p,num_dev,1); /*加載設(shè)備驅(qū)動*/if(err){printk(KERN_ERR"LED:unabletoaddthedevice%d/n",err);returnerr;}
/*在/sys/class下創(chuàng)建led_test目錄*/led_dev_class=class_create(THIS_MODULE,DEVICE_LIST); if(IS_ERR(led_dev_class)){err=PTR_ERR(led_dev_class);gotounregister_cdev;}/*基于/sys/class/led_test和/dev下面創(chuàng)建led_light設(shè)備文件*/temp=device_create(led_dev_class,NULL,num_dev,NULL,DEVICE_NODE);if(IS_ERR(temp)){err=PTR_ERR(temp);gotounregister_class;}return0;unregister_class:class_destroy(led_dev_class);unregister_cdev:cdev_del(cdev_p);returnerr;}模塊初始化33*模塊的初始化*/staticint__inits5pv210_led_init(void){intret;ret=s5pv210_led_ctrl_init();if(ret){printk(KERN_ERR"Apply:S5PV210_LED_init--Fail!!!/n");returnret;}return0;}模塊注銷34/*模塊的退出*/staticvoid__exits5pv210_led_exit(void){device_destroy(led_dev_class,DEVICE_NODE);class_destroy(led_dev_class);cdev_del(cdev_p);unregister_chrdev_region(num_dev,1);}module_init(s5pv210_led_init);module_exit(s5pv210_led_exit);/*模塊許可證聲明,可是使用‘GPL’或者‘DualBSD/GPL’*/MODULE_LICENSE("GPL");Linux設(shè)備驅(qū)動介紹主要議題*35Linux字符設(shè)備框架LED字符驅(qū)動分析Linux驅(qū)動調(diào)試驅(qū)動調(diào)試*36Linux字符設(shè)備驅(qū)動編寫完成后,需要編寫Makefile文件,對其進(jìn)行編譯;然后編寫測試程序及Makefile,對其進(jìn)行調(diào)試測試。設(shè)備驅(qū)動Makefile*37INSTALLDIR =/opt/tftpifneq($(KERNELRELEASE),)obj-m:=led.oelseKERNELDIR:=/usr/local/src/s210x/x210_android-2.3/kernelPWD:=$(shellpwd)default: $(MAKE)-C$(KERNELDIR)M=$(PWD)modulesclean: rm-rf*.o*.order.*.cmd*.ko*.mod.c*.symversendifinstall:led.ko mkdir-p$(INSTALLDIR) cp--target-dir=$(INSTALLDIR)led.ko測試?yán)?include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<fcntl.h>#defineDEVICE_NODE"/dev/led_light“intmain(intargc,char**argv){ intfd,i; unsignedcharstatus; unsignedchart; /*打開設(shè)備節(jié)點(diǎn)*/ fd=open(DEVICE_NODE,O_RDWR); if(fd==-1){ printf("opendevice%serror\n",DEVICE_NODE); exit; }38while(1){ for(i=0;i<4;i++){ /依次點(diǎn)亮LED1..LED4 t=(1<<i)&0x0F; write(fd,&t,sizeof(i)); if(read(fd,&status,1)!=0) {
printf("ledstatus:%0x\n",status); } sleep(1); }}close(fd);return
溫馨提示
- 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)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 尿道壁瘺修復(fù)中的靶向藥物開發(fā)方向-洞察闡釋
- 2025-2030中國溴代叔丁烷行業(yè)發(fā)展分析及發(fā)展前景與趨勢預(yù)測研究報告
- 2025-2030中國混合(2合1)筆記本電腦行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 2025-2030中國液壓托盤車行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 基于AI的網(wǎng)絡(luò)事件關(guān)聯(lián)與語義分析-洞察闡釋
- 2025-2030中國浮動式風(fēng)力發(fā)電機(jī)行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 延胡索化學(xué)成分提取技術(shù)-洞察闡釋
- 2025-2030中國氨綸纖維行業(yè)現(xiàn)狀供需分析及市場深度研究發(fā)展前景及規(guī)劃可行性分析研究報告
- 2025-2030中國棕櫚仁脂肪酸二乙醇酰胺行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略研究報告
- 2025-2030中國無機(jī)試劑行業(yè)市場深度調(diào)研及發(fā)展趨勢和投資前景預(yù)測研究報告
- (四調(diào))武漢市2025屆高中畢業(yè)生四月調(diào)研考試 英語試卷(含答案)
- NB/T 11446-2023煤礦連采連充技術(shù)要求
- DBJ41∕T 228-2019 河南省房屋建筑施工現(xiàn)場安全資料管理標(biāo)準(zhǔn)
- 三級安全教育考試試題(的)
- DB13 5325-2021 生活垃圾焚燒大氣污染控制標(biāo)準(zhǔn)
- 芒針療法課件
- 鼓樂鏗鏘課件 (2)
- 小學(xué)二年級下冊科學(xué)課件1.《春夏秋冬》大象版(22張)ppt課件
- 鋼結(jié)構(gòu)工程質(zhì)量通病防治圖冊
- 地下水八大離子-陰陽離子平衡計(jì)算公式
- 派力肯安全防護(hù)箱
評論
0/150
提交評論