clinux高級(jí)編程_第1頁(yè)
clinux高級(jí)編程_第2頁(yè)
clinux高級(jí)編程_第3頁(yè)
clinux高級(jí)編程_第4頁(yè)
clinux高級(jí)編程_第5頁(yè)
已閱讀5頁(yè),還剩4頁(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、C/linux高級(jí)編程設(shè)計(jì)報(bào)告題目: 字符驅(qū)動(dòng)設(shè)備設(shè)計(jì) 學(xué)生姓名: 馮永強(qiáng) 學(xué) 號(hào): 123821003 專 業(yè): 計(jì)算機(jī)科學(xué)與技術(shù) 2014年5月25日 字符驅(qū)動(dòng)設(shè)備設(shè)計(jì)1、 課程設(shè)計(jì)目的 Linux 系統(tǒng)的開源性使其在嵌入式系統(tǒng)的開發(fā)中得到了越來(lái)越廣泛的應(yīng)用,但其本身并沒(méi)有對(duì)種類繁多的硬件設(shè)備都提供現(xiàn)成的驅(qū)動(dòng)程序,特別是由于工程應(yīng)用中的靈活性,其驅(qū)動(dòng)程序更是難以統(tǒng)一,這時(shí)就需開發(fā)一套適合于自己產(chǎn)品的設(shè)備驅(qū)動(dòng)。對(duì)用戶而言,設(shè)備驅(qū)動(dòng)程序隱藏了設(shè)備的具體細(xì)節(jié),對(duì)各種不同設(shè)備提供了一致的接口,一般來(lái)說(shuō)是把設(shè)備映射為一個(gè)特殊的設(shè)備文件,用戶程序可以像對(duì)其它文件一樣對(duì)此設(shè)備文件進(jìn)行操作。通過(guò)這次課程設(shè)

2、計(jì)可以了解linux的模塊機(jī)制,懂得如何加載模塊和卸載模塊,進(jìn)一步熟悉模塊的相關(guān)操作。加深對(duì)驅(qū)動(dòng)程序定義和設(shè)計(jì)的了解,了解linux驅(qū)動(dòng)的編寫過(guò)程,提高自己的動(dòng)手能力。2、 課程設(shè)計(jì)內(nèi)容與要求(1) 設(shè)計(jì)Windows XP或者Linux操作系統(tǒng)下的設(shè)備驅(qū)動(dòng)程序;(2) 設(shè)備類型可以是字符設(shè)備、塊設(shè)備或者網(wǎng)絡(luò)設(shè)備;(3) 設(shè)備可以是虛擬的也可以是實(shí)際設(shè)備;3、 系統(tǒng)分析與設(shè)計(jì) (1) 系統(tǒng)分析 系統(tǒng)調(diào)用是操作系統(tǒng)內(nèi)核和應(yīng)用程序之間的接口,設(shè)備驅(qū)動(dòng)程序是操作系統(tǒng)內(nèi)核和機(jī)器硬件之間的接口。設(shè)備驅(qū)動(dòng)程序?yàn)閼?yīng)用程序屏蔽了硬件的細(xì)節(jié),這樣在應(yīng)用程序看來(lái),硬件設(shè)備只是一個(gè)設(shè)備文件,應(yīng)用程序可以象操作普通文

3、件一樣對(duì)硬件設(shè)備進(jìn)行操作。設(shè)備驅(qū)動(dòng)程序是內(nèi)核的一部分,它完成以下的功能:1、對(duì)設(shè)備初始化和釋放;2、把數(shù)據(jù)從內(nèi)核傳送到硬件和從硬件讀取數(shù)據(jù);3、讀取應(yīng)用程序傳送給設(shè)備文件的數(shù)據(jù)和回送應(yīng)用程序請(qǐng)求的數(shù)據(jù);4、檢測(cè)和處理設(shè)備出現(xiàn)的錯(cuò)誤。Linux下的設(shè)備驅(qū)動(dòng)程序被組織為一組完成不同任務(wù)的函數(shù)的集合,通過(guò)這些函數(shù)使得Windows的設(shè)備操作猶如文件一般。在應(yīng)用程序看來(lái),硬件設(shè)備只是一個(gè)設(shè)備文件,應(yīng)用程序可以象操作普通文件一樣對(duì)硬件設(shè)備進(jìn)行操作,如open ()、close ()、read ()、write () 等。Linux主要將設(shè)備分為二類:字符設(shè)備和塊設(shè)備。字符設(shè)備是指設(shè)備發(fā)送和接收數(shù)據(jù)以字符

4、的形式進(jìn)行;而塊設(shè)備則以整個(gè)數(shù)據(jù)緩沖區(qū)的形式進(jìn)行。字符設(shè)備提供給應(yīng)用程序的是一個(gè)流控制接口,主要包括open、close(或release)、read、write、ioctl、poll和mmap等。在系統(tǒng)中添加一個(gè)字符設(shè)備驅(qū)動(dòng)程序,實(shí)際上就是給上述操作添加對(duì)應(yīng)的代碼。對(duì)于字符設(shè)備和塊設(shè)備,Linux內(nèi)核對(duì)這些操作進(jìn)行了統(tǒng)一的抽象,把它們定義在結(jié)構(gòu)體file_operations中。在驅(qū)動(dòng)程序中,當(dāng)多個(gè)線程同時(shí)訪問(wèn)相同的資源時(shí)(驅(qū)動(dòng)程序中的全局變量是一種典型的共享資源),可能會(huì)引發(fā)"競(jìng)態(tài)",因此我們必須對(duì)共享資源進(jìn)行并發(fā)控制。Linux內(nèi)核中解決并發(fā)控制的最常用方法是自旋鎖與

5、信號(hào)量(絕大多數(shù)時(shí)候作為互斥鎖使用)。自旋鎖與信號(hào)量"類似而不類",類似說(shuō)的是它們功能上的相似性,"不類"指代它們?cè)诒举|(zhì)和實(shí)現(xiàn)機(jī)理上完全不一樣,不屬于一類。自旋鎖不會(huì)引起調(diào)用者睡眠,如果自旋鎖已經(jīng)被別的執(zhí)行單元保持,調(diào)用者就一直循環(huán)查看是否該自旋鎖的保持者已經(jīng)釋放了鎖,"自旋"就是"在原地打轉(zhuǎn)"。而信號(hào)量則引起調(diào)用者睡眠,它把進(jìn)程從運(yùn)行隊(duì)列上拖出去,除非獲得鎖。這就是它們的"不類"。但是,無(wú)論是互斥信號(hào)量,還是自旋鎖,在任何時(shí)刻,最多只能有一個(gè)保持者,即在任何時(shí)刻最多只能有一個(gè)執(zhí)行單元獲得鎖。這

6、就是它們的"類似"。鑒于自旋鎖與信號(hào)量的上述特點(diǎn),一般而言,自旋鎖適合于保持時(shí)間非常短的情況,它可以在任何上下文使用;信號(hào)量適合于保持時(shí)間較長(zhǎng)的情況,只能在進(jìn)程上下文使用。如果被保護(hù)的共享資源只在進(jìn)程上下文訪問(wèn),則可以以信號(hào)量來(lái)保護(hù)該共享資源,如果對(duì)共享資源的訪問(wèn)時(shí)間非常短,自旋鎖也是好的選擇。但是,如果被保護(hù)的共享資源需要在中斷上下文訪問(wèn)(包括底半部即中斷處理句柄和頂半部即軟中斷),就必須使用自旋鎖。阻塞操作是指,在執(zhí)行設(shè)備操作時(shí),若不能獲得資源,則進(jìn)程掛起直到滿足可操作的條件再進(jìn)行操作。非阻塞操作的進(jìn)程在不能進(jìn)行設(shè)備操作時(shí),并不掛起。被掛起的進(jìn)程進(jìn)入sleep狀態(tài),被從

7、調(diào)度器的運(yùn)行隊(duì)列移走,直到等待的條件被滿足。在Linux驅(qū)動(dòng)程序中,我們可以使用等待隊(duì)列(wait queue)來(lái)實(shí)現(xiàn)阻塞操作。wait queue很早就作為一個(gè)基本的功能單位出現(xiàn)在Linux內(nèi)核里了,它以隊(duì)列為基礎(chǔ)數(shù)據(jù)結(jié)構(gòu),與進(jìn)程調(diào)度機(jī)制緊密結(jié)合,能夠用于實(shí)現(xiàn)核心的異步事件通知機(jī)制。等待隊(duì)列可以用來(lái)同步對(duì)系統(tǒng)資源的訪問(wèn),上節(jié)中所講述Linux信號(hào)量在內(nèi)核中也是由等待隊(duì)列來(lái)實(shí)現(xiàn)的。結(jié)合阻塞與非阻塞訪問(wèn)、poll函數(shù)可以較好地解決設(shè)備的讀寫,但是如果有了異步通知就更方便了。異步通知的意思是:一旦設(shè)備就緒,則主動(dòng)通知應(yīng)用程序,這樣應(yīng)用程序根本就不需要查詢?cè)O(shè)備狀態(tài),這一點(diǎn)非常類似于硬件上"

8、中斷"地概念,比較準(zhǔn)確的稱謂是"信號(hào)驅(qū)動(dòng)(SIGIO)的異步I/O"。在本課程設(shè)計(jì)中主要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的字符驅(qū)動(dòng)設(shè)備,運(yùn)用信號(hào)量和自旋鎖進(jìn)行相關(guān)的并發(fā)控制。(2) 系統(tǒng)設(shè)計(jì) 2.1 測(cè)試環(huán)境: 系統(tǒng): linuxmint 15 gcc version : 4.7.3 2.2 模塊設(shè)計(jì): 打開設(shè)備 讀操作 寫操作釋放設(shè)備 退出設(shè)備字符設(shè)備驅(qū)動(dòng)2.3 數(shù)據(jù)結(jié)構(gòu)說(shuō)明:字符設(shè)備驅(qū)動(dòng)主要應(yīng)用了三種數(shù)據(jù)結(jié)構(gòu):file_operations結(jié)構(gòu),這是設(shè)備驅(qū)動(dòng)程序所提供的一組用一個(gè)結(jié)構(gòu)向系統(tǒng)進(jìn)行說(shuō)明的入口點(diǎn);file結(jié)構(gòu),主要用于與文件系統(tǒng)對(duì)應(yīng)的設(shè)備驅(qū)動(dòng)程序。代表一個(gè)打開的文件,它

9、由內(nèi)核在open時(shí)創(chuàng)建,并傳遞給在該文件上進(jìn)行操作的所有函數(shù),直到碰到最后的close函數(shù)。在文件的所有實(shí)例都被關(guān)閉之后,內(nèi)核會(huì)釋放這個(gè)數(shù)據(jù)結(jié)構(gòu); inode結(jié)構(gòu),提供了關(guān)于特殊設(shè)備文件/dev/mydev的信息。使用cat /proc/kmsg &來(lái)監(jiān)測(cè)Kernel中的輸出信息,即程序中的printk的輸出信息。同時(shí)通過(guò)#include<errno.h>來(lái)引入相關(guān)的錯(cuò)誤定義,在對(duì)應(yīng)錯(cuò)誤發(fā)生的時(shí)候向內(nèi)核輸出出錯(cuò)信息。各個(gè)結(jié)構(gòu)的定義如下:(1)file_operations結(jié)構(gòu): static const struct file_operations my_fops = .o

10、wner = THIS_MODULE, .llseek = my_llseek, .read = my_read, .write = my_write, .open = my_open, .release = my_release, .unlocked_ioctl = ioctl, ;(2)file結(jié)構(gòu): 1)讀 static ssize_t my_read(struct file *filp, char _user *buf, size_t size, loff_t *ppos) 2)寫 static ssize_t my_write(struct file *filp, const cha

11、r _user *buf, size_t size, loff_t *ppos) 3)seek文件定位 static loff_t my_llseek(struct file *filp, loff_t offset, int whence) 4)IO控制 static int ioctl (struct file *file, unsigned int cmd, unsigned long arg)(3)inode結(jié)構(gòu): 1) 打開 int my_open(struct inode *inode, struct file *filp) 2) 釋放 int my_release(struct

12、inode *inode, struct file *filp)(4) 信號(hào)量定義:1) 定義信號(hào)量 static struct semaphore sem;2) 初始化信號(hào)量為1 sema_init ( &sem, 1 );3) 獲取信號(hào)量 up( &sem )4) 釋放信號(hào)量 down( &sem )(5) 自旋鎖定義:1) 獲得自旋鎖 spin_lock ( &spin );2) 釋放自旋鎖 spin_unlock ( &spin );(6) 模塊初始化和退出1) 模塊初始化 module_init(mydev_init);2) 模塊退出 modu

13、le_exit(mydev_exit);2.4 算法流程圖如下:結(jié)束 文件釋放函數(shù) mydev_release 設(shè)備驅(qū)動(dòng)模塊 卸載函數(shù)mydev_exit()開始設(shè)備驅(qū)動(dòng)模塊加載函數(shù)ly_init()文件打開函數(shù)ly_open() 信號(hào)量 獲取 自旋鎖 獲取讀函數(shù) mydev_read 寫函數(shù)mydev_write4、 系統(tǒng)調(diào)試與分析4.1 使用su用戶4.2 對(duì)源程序進(jìn)行編譯4.3 打開后臺(tái)內(nèi)核輸出監(jiān)控4.4 加載驅(qū)動(dòng)程序并查看4.5 顯示主設(shè)4.6 創(chuàng)建節(jié)點(diǎn)并查看4.7 編譯測(cè)試程序4.8 運(yùn)行測(cè)試程序4.9 打開設(shè)備4.11 啟動(dòng)另一個(gè)終端,打開設(shè)備4.10 讀設(shè)備(創(chuàng)建設(shè)備的時(shí)候已經(jīng)在

14、緩存區(qū)設(shè)置數(shù)據(jù))4.11 寫入數(shù)據(jù)4.12 繼續(xù)讀數(shù)據(jù)(MAX_BUFF是20)4.13 釋放設(shè)備4.14 退出測(cè)試程序5、 程序清單mydev.c :#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/cdev.h>#include <asm/uaccess.h>#include <linux/semaphore.h>#define DEFAU

15、LT_MSG "Hello,Welcome to OS course design" /*默認(rèn)字符設(shè)備數(shù)據(jù)*/#define DEVICE_NAME "mydev" /*設(shè)備名*/#define MAXBUF 100 /*設(shè)備數(shù)據(jù)緩沖區(qū)大小*/static unsigned char mydev_bufMAXBUF; /*設(shè)備內(nèi)存數(shù)據(jù)緩沖區(qū)*/static struct semaphore sem; /* 定義互斥信號(hào)量 */static int globalvar_count = 0; /* 定義設(shè)備計(jì)數(shù) */static DEFINE_SPINLOC

16、K ( spin ); /* 定義自旋鎖 */*定義讀寫釋放打開*/static int mydev_open ( struct inode *inode, struct file *file );static int mydev_release ( struct inode *inode, struct file *file );static ssize_t mydev_read ( struct file *file, char _user *buf, size_t count, loff_t *pos );static ssize_t mydev_write ( struct file

17、*file, const char _user *buf, size_t count, loff_t *pos );static int mydev_open ( struct inode *inode, struct file *file ) /獲得自選鎖 spin_lock ( &spin ); /臨界資源訪問(wèn) if ( globalvar_count ) spin_unlock ( &spin ); return -EBUSY; globalvar_count+; /釋放自選鎖 spin_unlock ( &spin ); return 0;static int

18、mydev_release ( struct inode *inode, struct file *file ) globalvar_count-; printk ( "設(shè)備資源釋放!n" ); return 0;static ssize_t mydev_read ( struct file *file, char _user *buf, size_t count, loff_t *pos ) /*從設(shè)備讀取count個(gè)數(shù)據(jù)到用戶數(shù)據(jù)區(qū)buf中*/ int size = count < MAXBUF ? count : MAXBUF; /*檢測(cè)讀取的數(shù)據(jù)大小count

19、是否比設(shè)備數(shù)據(jù)緩沖區(qū)大,如何大則截取MAXBUF的大小*/ printk ( "mydev: This is my device!n" ); /*把設(shè)備內(nèi)存mydev_buf中的數(shù)據(jù)拷貝到用戶空間buf中,數(shù)量為size*/ if ( copy_to_user ( buf, mydev_buf, size ) ) up ( &sem ); return -ENOMEM; /*內(nèi)存不足錯(cuò)誤*/ up ( &sem ); return size;static ssize_t mydev_write ( struct file *filp, const char

20、_user *buf, size_t count, loff_t *pos ) /*把buf中count個(gè)數(shù)據(jù)寫入設(shè)備內(nèi)存空間中*/ int size = count < MAXBUF ? count : MAXBUF; /*檢測(cè)寫入的數(shù)據(jù)大小count是否比設(shè)備數(shù)據(jù)緩沖區(qū)大*/ /獲得信號(hào)量 if ( down_interruptible ( &sem ) ) return - ERESTARTSYS; printk ( "mydev:This is my device!n" ); memset ( mydev_buf, 0, sizeof ( mydev_

21、buf ) ); /*將設(shè)備內(nèi)存清空*/ /*把buf中的用戶數(shù)據(jù)寫入到設(shè)備內(nèi)存mydev_buf中,數(shù)量為size*/ if ( copy_from_user ( mydev_buf, buf, size ) ) up ( &sem ); return -ENOMEM; up ( &sem ); return size;static struct file_operations mydev_fops = .read = mydev_read, .write = mydev_write, .open = mydev_open, .release = mydev_release,

22、;static struct cdev *mydev_cdev; /*新設(shè)備指針*/static int _init mydev_init ( void ) /*模塊初始化*/ dev_t dev; /*設(shè)備號(hào)*/ int error; error = alloc_chrdev_region ( &dev, 0, 2, DEVICE_NAME ); /*動(dòng)態(tài)分配一個(gè)設(shè)備號(hào)*/ if ( error ) /*返回值不為0表示分配失敗*/ printk ( "動(dòng)態(tài)分配設(shè)備號(hào)失??!n" ); return error; mydev_cdev = cdev_alloc();

23、 /*新分配一個(gè)字符設(shè)備對(duì)象*/ if ( mydev_cdev = NULL ) printk ( "動(dòng)態(tài)分配字符設(shè)備對(duì)象失敗!n" ); unregister_chrdev_region ( dev, 2 ); /*注銷一個(gè)分配的設(shè)備號(hào)區(qū)域*/ return -ENOMEM; mydev_cdev->ops = &mydev_fops; /*設(shè)定字符設(shè)備操作函數(shù)指針*/ mydev_cdev->owner = THIS_MODULE; /*設(shè)備的屬主*/ error = cdev_add ( mydev_cdev, dev, 1 ); /*將設(shè)備添加

24、到內(nèi)核中去*/ if ( error ) printk ( "設(shè)備添加失??!n" ); unregister_chrdev_region ( dev, 2 ); /*注銷一個(gè)分配的設(shè)備號(hào)區(qū)域*/ cdev_del ( mydev_cdev ); /*刪除字符設(shè)備對(duì)象*/ return error; memset ( mydev_buf, 0, sizeof ( mydev_buf ) ); /*清空設(shè)備緩沖區(qū)數(shù)據(jù)*/ memcpy ( mydev_buf, DEFAULT_MSG, sizeof ( DEFAULT_MSG ) ); /*設(shè)定設(shè)備緩沖區(qū)默認(rèn)數(shù)據(jù)*/ prin

25、tk ( "設(shè)備添加成功,設(shè)備緩沖區(qū)默認(rèn)數(shù)據(jù): Hello,Welcome to OS course design!n" ); sema_init ( &sem, 1 ); return 0;static void _exit mydev_exit ( void ) /*模塊卸載*/ unregister_chrdev_region ( mydev_cdev->dev, 2 ); cdev_del ( mydev_cdev ); printk ( "設(shè)備刪除成功!n" );module_init ( mydev_init );module_

26、exit ( mydev_exit );MODULE_LICENSE ( "GPL" );test.c:#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#define MAXBUF 20int main() int testdev; int i; int len; int t; char sel; int flag; char bufMAXBUF, tmpMAXBUF; printf ( "1、打開設(shè)備n2、

27、寫操作n3、讀操作n4、釋放設(shè)備n5、退出n" ); while ( 1 ) printf ( "請(qǐng)輸入要執(zhí)行的操作:" ); sel = getchar(); getchar(); switch ( sel ) case '1': testdev = open ( "/dev/mydev", O_RDWR ); if ( testdev < 0 ) printf ( "設(shè)備打開失敗 n" ); break; flag = 0; printf ( "設(shè)備打開成功!n" ); brea

28、k; case '2': if ( flag ) printf ( "請(qǐng)先打開設(shè)備!n" ); continue; printf ( "請(qǐng)輸入要寫入的字符串:" ); gets ( tmp ); len = sizeof ( tmp ); /strlen(tmp); t = write ( testdev, tmp, len ); if ( t < 0 ) perror ( "寫操作失敗!n" ); exit ( -1 ); printf ( "字符串:%s 寫入成功!n", tmp ); b

29、reak; case '3': if ( flag ) printf ( "請(qǐng)先打開設(shè)備!n" ); continue; lseek ( testdev, 0, SEEK_SET ); t = read ( testdev, buf, MAXBUF ); if ( t < 0 ) perror ( "讀操作失?。" ); exit ( -1 ); printf ( "讀操作成功!結(jié)果為:%sn", buf ); break; case '4': if ( flag ) printf ( &quo

30、t;請(qǐng)先打開設(shè)備!n" ); break; /release(testdev); close ( testdev ); printf ( "設(shè)備釋放成功!n" ); flag = 1; break; case '5': close ( testdev ); exit ( 0 ); default: printf ( "輸入有誤!n" ); break; makefile:DEBFLAGS = -O2EXTRA_CFLAGS += $(DEBFLAGS)# CFLAGS += -I$(LDDINC)ifneq ($(KERNELR

31、ELEASE),)# call from kernel build systemxbrige-objs := mydev.o obj-m:= mydev.oelseKERNELDIR ?= /lib/modules/$(shell uname -r)/buildPWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules#$(MAKE) -C $(KERNELDIR) M=$(PWD) LDDINC=$(PWD)/./include modulesendifclean:rm -rf *.o * core .depend

32、.*.cmd *.ko *.mod.c .tmp_versionsdepend .depend dep:$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -M *.c > .dependifeq (.depend,$(wildcard .depend)include .dependendif6、 課設(shè)總結(jié)在這次課程設(shè)計(jì)之前就一直在使用linux系統(tǒng),在筆記本電腦上使用的是linuxmint15,所以在進(jìn)行本次課程設(shè)計(jì)的時(shí)候選題為第二個(gè)會(huì)比較容易搭建環(huán)境。但是使用linux也主要是在應(yīng)用層面進(jìn)行一些編程和娛樂(lè)活動(dòng),并沒(méi)有涉及到驅(qū)動(dòng)或者內(nèi)核層次的hack,所以在本次課程設(shè)計(jì)中選擇驅(qū)動(dòng)開發(fā)也可以鍛煉我相關(guān)的能力驅(qū)動(dòng)相較于Linux系統(tǒng)是更加熟悉的一個(gè)名詞,每次重裝系統(tǒng)都要安裝各種各樣的驅(qū)動(dòng),不然計(jì)算機(jī)就不能正常運(yùn)行,

溫馨提示

  • 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)論