由淺入深藍牙40BLE協(xié)議棧開發(fā)攻略大全3_第1頁
由淺入深藍牙40BLE協(xié)議棧開發(fā)攻略大全3_第2頁
由淺入深藍牙40BLE協(xié)議棧開發(fā)攻略大全3_第3頁
由淺入深藍牙40BLE協(xié)議棧開發(fā)攻略大全3_第4頁
由淺入深藍牙40BLE協(xié)議棧開發(fā)攻略大全3_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、本系列教程將結(jié)合TI推出的CC254x SoC 系列,講解從環(huán)境的搭建到藍牙4.0協(xié)議棧的開發(fā)來深入學(xué)習藍牙4.0的開發(fā)過程。教程共分為六部分,本文為第三部分:第三部分知識點:第十一節(jié) 串口通信第十二節(jié) Flash的讀寫第十三節(jié) BLE協(xié)議棧簡介第十四節(jié) OSAL工作原理第十五節(jié) BLE藍牙4.0協(xié)議棧啟動分析有關(guān)TI 的CC254x芯片介紹,可點擊下面鏈接查看:主流藍牙BLE控制芯片詳解(1):TI CC2540同系列資料推薦:由淺入深,藍牙4.0/BLE協(xié)議棧開發(fā)攻略大全(1)由淺入深,藍牙4.0/BLE協(xié)議棧開發(fā)攻略大全(2)有關(guān)本文的工具下載,大家可以到以下這個地址:朱兆祺ForARM

2、第十一節(jié) 串口通信在軟件開發(fā)過程中調(diào)試是一個很關(guān)鍵的過程,而調(diào)試用的最多的手段就是打印Log,嵌入式平臺很少有顯示設(shè)備,所以我們需要將信息通過串口打印到PC端。MT254xboard上已經(jīng)通過RS232芯片將UART0連接到DB9,我們只需要將DB9連接到電腦即可,UART0 對應(yīng)的外部設(shè)備 IO 引腳關(guān)系為:P0_2-RX,P0_3-TX。我們需要將這兩個IO配置為復(fù)用功能,CC2540的USART可以配置為SPI模式或者異步UART模式,這里我們需要配置為異步UART模式。首先配置IO為UART模式:PERCFG &= 0x01; / 配置UART為位置 1P0SEL = 0x3c; /

3、P0_2,P0_3,P0_4,P0_5用作串口功能P2DIR &= 0XC0; / P0 優(yōu)先作為UART0配置UART0寄存器,將UART0配置為8N1模式,波特率為115200。U0CSR |= 0x80; / UART 方式U0GCR |= 11; / U0GCR與U0BAUD配合U0BAUD |= 216; / 波特率設(shè)為115200UTX0IF = 0; / 清除中斷標志U0CSR |= 0X40; / 允許接收IEN0 |= 0x84; / 開總中斷,接收中斷這里采用中斷方式來接收串口數(shù)據(jù),并在中斷中回調(diào)應(yīng)用層的接收處理函數(shù)。#pragma vector = URX0_VECTOR

4、_interrupt void UART0_ISR(void)uint8 ch;URX0IF = 0; / 清中斷標志ch = U0DBUF;if ( NULL != RecvCb ) / 調(diào)用回調(diào)函數(shù)RecvCb(ch);為了測試串口的通訊功能,這里我們通過串口接收命令的方式來控制LED的亮滅和蜂鳴器的響和停止,并且顯示當前的狀態(tài)。根據(jù)串口輸出提示,發(fā)送對應(yīng)字符可以實現(xiàn)相應(yīng)功能,并且顯示狀態(tài)。第十二節(jié) Flash的讀寫嵌入式系統(tǒng)中需要存儲數(shù)據(jù),而片內(nèi)的Flash資源很匱乏,所以我們經(jīng)常需要使用SpiFlash來存儲數(shù)據(jù),MT254xboard中板載了一個 512Kbyte的Flash,下面我

5、們來驅(qū)動此Flash。上一小節(jié)中我們用SPI的方式驅(qū)動了LCD12864,這節(jié)我們繼續(xù)用SPI來驅(qū)動板載的 Flash,詳細的說明了如何驅(qū)動這片F(xiàn)lash,在此不做累述,我們復(fù)制LCD12864工程,重命名為SpiFlash,在此工程中添加GD25Q40的兩個驅(qū)動文件。下面我們來檢測這個Flash,檢測的方法為,全部寫入0xAA,然后再讀出,對比是否為0xAA,如果是,那Flash是沒有問題的,否則Flash可能已經(jīng)有壞塊。具體的代碼見例程,這個過程所需要的時間取決于我們需要檢測的區(qū)域大小,如果完全檢測,則可能需要幾分鐘的時間。int main(void)SysStartXOSC();LCD1

6、2864_Init(); / LCD初始化GD25Q40_Init(); / Flash初始化LCD12864_DisStr(0, “Flash Check.?!保?sprintf(LCDBuf, “Flash ID :%04X”, GD25Q40_ReadID(); / 讀取器件IDLCD12864_DisStr(1, LCDBuf);GD25Q40_EraseChip(); / 擦除整片F(xiàn)lash 大約需要10SLCD12864_DisStr(2, “Erase Chip Complete”);uint32 iCnt = 0;/ 全部寫入0xAAconst uint8 Write = 0x

7、AA;for(iCnt=0; iCnt CHECK_ADDR_RANGE; iCnt+)GD25Q40_Write(&Write, iCnt, 1); / 寫入0xAA/ 讀取Flash內(nèi)部的值,與寫入的值對比uint8 Read;for(iCnt=0; iCnt = CHECK_ADDR_RANGE)LCD12864_DisStr(3, “Flash Check Success”);GD25Q40_EraseChip(); / 再次擦除while(1);return 0;MT254X藍牙4.0開發(fā)板Flash效果:第十三節(jié) BLE協(xié)議棧簡介TI的協(xié)議棧分為兩部分:控制器和主機。對于4.0以前

8、的藍牙,這兩部分是分開的。所有profile和應(yīng)用都建構(gòu)在GAP或GATT之上。根據(jù)這張圖,我們從底層開始介紹。TI的這款CC2540器件可以單芯片實現(xiàn)BLE藍牙協(xié)議棧結(jié)構(gòu)圖的所有組件,包括應(yīng)用程序。1.1.1 PHY層1Mbps自適應(yīng)跳頻GFSK(高斯頻移鍵控),運行在免證的2.4GHz。1.1.2 LL層LL層為RF控制器,控制設(shè)備處于準備(standby)、廣播、監(jiān)聽/掃描(scan)、初始化、連接,這五種狀態(tài)中一種。五種狀態(tài)切換描述為:未連接時,設(shè)備廣播信息,另外一個設(shè)備一直監(jiān)聽或按需掃描,兩個設(shè)備連接初始化,設(shè)備連接上了。發(fā)起聊天的設(shè)備為主設(shè)備,接受聊天的設(shè)備為從設(shè)備,同一次聊天只能

9、有一個意見領(lǐng)袖,即主設(shè)備和從設(shè)備不能切換。1.1.3 HCI層HCI層為接口層,向上為主機提供軟件應(yīng)用程序接口(API),對外為外部硬件控制接口,可以通過串口、SPI、USB來實現(xiàn)設(shè)備控制。1.1.4 L2CAP層L2CAP層提供數(shù)據(jù)封裝服務(wù),允許邏輯上的點對點通訊。1.1.5 SM層SM層提供配對和密匙分發(fā),實現(xiàn)安全連接和數(shù)據(jù)交換。1.1.6 ATT層ATT層負責數(shù)據(jù)檢索,允許設(shè)備向另外一個設(shè)備展示一塊特定的數(shù)據(jù)稱之為屬性,在ATT環(huán)境中,展示屬性的設(shè)備稱之為服務(wù)器,與它配對的設(shè)備稱之為客戶端。鏈路層的主機從機和這里的服務(wù)器、客服端是兩種概念,主設(shè)備既可以是服務(wù)器,也可以是客戶端。從設(shè)備毅然

10、。1.1.7 GATT層GATT層定義了使用 ATT 的服務(wù)框架和配置文件(profiles)的結(jié)構(gòu)。BLE 中所有的數(shù)據(jù)通信都需要經(jīng)過 GATT。GATT負責處理向上與應(yīng)用打交道,其關(guān)鍵工作是把為檢索工作提供合適的profile結(jié)構(gòu),而profile由檢索關(guān)鍵詞(characteristics)組成。1.1.8 GAP層GAP直接與應(yīng)用程序或配置文件(profiles)通信的接口,處理設(shè)備發(fā)現(xiàn)和連接相關(guān)服務(wù)。另外還處理安全特性的初始化。對上級,提供應(yīng)用程序接口,對下級,管理各級職能部門,尤其是指示LL層控制室五種狀態(tài)切換,指導(dǎo)保衛(wèi)處做好機要工作。1.2 TI協(xié)議棧源碼介紹在第二章我們講解了源

11、碼的安裝,這里我們就來剖析源碼的結(jié)構(gòu)。打開協(xié)議棧目錄我們可以看到下圖:BLE源碼:目錄名內(nèi)容說明Accessories一些工具和已經(jīng)編譯好的Hex文件此文件夾中有Btool的安裝包、USB-CDC的驅(qū)動。ComponentsHal驅(qū)動,OSAL源碼、協(xié)議棧通用源碼此文件夾是OSAL各層組件的實現(xiàn)Documents幫助文檔協(xié)議棧說明文檔,這是學(xué)習BLE最好的資料。Projects工程文件這里有一些TI的Demo,我們開發(fā)一般是在Demo的基礎(chǔ)上進行這里TI給出了很多Demo,這些例程都是經(jīng)過了SIG評審的,ble 文件夾中有很多工程文件,有些是具體的應(yīng)用,例如BloodPressure、Gluc

12、oseCollector 、GlucoseSensor 、 HeartRate 、HIDEmuKbd 等都為傳感器的實際應(yīng)用,有相應(yīng)標準的 Profile。其中有4種角色: SimpleBLEBroadcaster 、 SimpleBLECentral 、SimpleBLEObserver、SimpleBLEPeripheral。他們都有自己的特點。1.Broadcaster 廣播員 非連接性的信號裝置2.Observer 觀察者 掃描得到,但不能鏈接3.Peripheral 從機 可鏈接,在單個鏈路層鏈接中作為從機4.Central 主機 掃描設(shè)備并發(fā)起鏈接,在單鏈路層或多鏈路層中作為主機。

13、我們的講解將圍繞這主機和從機進行。因為其它的設(shè)備都是基于這兩種設(shè)備擴展開來的。第十四節(jié) OSAL工作原理藍牙為了實現(xiàn)同多個設(shè)備相連,或?qū)崿F(xiàn)多功能,也實現(xiàn)了功能擴充,這就產(chǎn)生了調(diào)度問題。因為,雖然軟件和協(xié)議棧可擴充,但終究最底層的執(zhí)行部門只有一個。為了實現(xiàn)多事件和多任務(wù)切換,需要把事件和任務(wù)對應(yīng)的應(yīng)用,并起一個名字OSAL操作系統(tǒng)抽象層。OSAL管理的實現(xiàn)如果實現(xiàn)軟件和硬件的低耦合,使軟件不經(jīng)改動或很少改動即可應(yīng)用在另外的硬件上,這樣就方便硬件改造、升級、遷移后,軟件的移植。HAL硬件抽象層正是用來抽象各種硬件的資源,告知給軟件。其作用類似于嵌入式系統(tǒng)設(shè)備驅(qū)動的定義硬件資源的h頭文件。BLE低功

14、耗藍牙系統(tǒng)架構(gòu):OSAL作為調(diào)度核心,BLE協(xié)議棧、profile定義、所有的應(yīng)用都圍繞它來實現(xiàn)。OSAL不是傳統(tǒng)大家使用的操作系統(tǒng),而是一個允許軟件建立和執(zhí)行事件的循環(huán)。軟件功能是由任務(wù)事件來實現(xiàn)的,創(chuàng)建一個任務(wù)事件需要以下工作:1. 創(chuàng)建task identifier任務(wù)ID;2. 編寫任務(wù)初始化(task initialization routine)進程,并需要添加到OSAL初始化進程中,這就是說系統(tǒng)啟動后不能動態(tài)添加功能;3. 編寫任務(wù)處理程序;4. 如有需要提供消息服務(wù)。BLE協(xié)議棧的各層都是以O(shè)SAL任務(wù)方式實現(xiàn),由于LL控制室的時間要求最為迫切,所以其任務(wù)優(yōu)先級最高。為了實現(xiàn)任

15、務(wù)管理,OSAL通過消息處理(messageprocess),存儲管理,計時器定時等附加服務(wù)實現(xiàn)。系統(tǒng)啟動流程:為了使用OSAL,在main函數(shù)的最后要啟動一個名叫osal_start_system的進程,該進程會調(diào)用由特定應(yīng)用決定的啟動函數(shù) osalInitTasks(來啟動系統(tǒng))。osalInitTasks逐個調(diào)用BLE協(xié)議棧各層的啟動進程來初始化協(xié)議棧。隨后,設(shè)置一個任務(wù)的 8bit任務(wù)ID(task ID),跳入循環(huán)等待執(zhí)行任務(wù),系統(tǒng)啟動完成。1. 任務(wù)優(yōu)先級決定于任務(wù)ID,任務(wù)ID越小,優(yōu)先級越高2. BLE協(xié)議棧各層的任務(wù)優(yōu)先級比應(yīng)用程序的高3. 初始化協(xié)議棧后,越早調(diào)入的任務(wù),任

16、務(wù)ID越高,優(yōu)先級越低,即系統(tǒng)傾向于處理新到的任務(wù)每個事件任務(wù)由對應(yīng)的16bit事件變量來標示,事件狀態(tài)由旗號(taskflag)來標示。如果事件處理程序已經(jīng)完成,但其旗號并沒有移除,OSAL會認為事情還沒有完成而繼續(xù)在該程序中不返回。比如,在SimpleBLEPeripheral實例工程中,當事件START_DEVICE_EVT發(fā)生,其處理函數(shù)SimpleBLEPeripheral_ProcessEvent就運行,結(jié)束后返回16bit事件變量,并清除旗語 SBP_START_DEVICE_EVT。每當OSAL事件檢測到了有任務(wù)事件,其相應(yīng)的處理進程將被添加到由處理進程指針構(gòu)成的事件處理表單中

17、,該表單名叫taskArr(taskarray)。taskArr中各個事件進程的順序和osalInitTasks初始化函數(shù)中任務(wù)ID的順序是對應(yīng)的。有兩種,最簡單的方法是使用osal_set_event函數(shù)(函數(shù)原型在OSAL.h文件中),在這個函數(shù)中,用戶可以像定義函數(shù)參數(shù)一樣設(shè)置任務(wù)ID 和事件旗語。第二種方法是使用osal_start_timerEx函數(shù)(函數(shù)原型在OSAL_Timers.h文件中),使用方法同 osal_set_event函數(shù),而第三個以毫秒為單位的參數(shù)osal_start_timerEx則指示該事件處理必須要在這個限定時間內(nèi),通過定時器來為事件處理計時。類似于Linu

18、x嵌入式系統(tǒng)內(nèi)存分配C函數(shù)mem_alloc,OSAL利用osal_mem_alloc提供基本的存儲管理,但osal_mem_alloc只有一個用于定義byte數(shù)的參數(shù)。對應(yīng)的內(nèi)存釋放函數(shù)為osal_mem_free。不同的子系統(tǒng)通過OSAL的消息機制通信。消息即為數(shù)據(jù),數(shù)據(jù)種類和長度都不限定。消息收發(fā)過程描述如下:接收信息,調(diào)用函數(shù)osal_msg_allocate創(chuàng)建消息占用內(nèi)存空間(已經(jīng)包含了osal_mem_alloc函數(shù)功能),需要為該函數(shù)指定空間大小,該函數(shù)返回內(nèi)存空間地址指針,利用該指針就可把所需數(shù)據(jù)拷貝到該空間。發(fā)送數(shù)據(jù),調(diào)用函數(shù)osal_msg_send,需為該函數(shù)指定發(fā)送目

19、標任務(wù),OSAL通過旗語SYS_EVENT_MSG告知目標任務(wù),目標任務(wù)的處理函數(shù)調(diào)用osal_msg_receive來接收發(fā)來的數(shù)據(jù)。建議每個OSAL任務(wù)都有一個消息處理函數(shù),每當任務(wù)收到一個消息后,通過消息的種類來確定需要本任務(wù)做相應(yīng)處理。消息接收并處理完成,調(diào)用函數(shù)osal_msg_deallocate來釋放內(nèi)存(已經(jīng)包含了osal_mem_free函數(shù)功能)。為了實現(xiàn)更好的移植性,協(xié)議棧將硬件層抽象出了一個HAL硬件抽象層,當新的硬件平臺做好后,只需修改HAL,而不需修改HAL之上的協(xié)議棧的其他組件和應(yīng)用程序。第十五節(jié) BLE藍牙4.0協(xié)議棧啟動分析TI的這款CC2540/CC2541

20、器件可以單芯片實現(xiàn)BLE藍牙協(xié)議棧結(jié)構(gòu)圖的所有組件,包括應(yīng)用程序。從這章開始我們來剖析協(xié)議棧源碼,我們選用 SimpleBLEPeripheral工程開刀,這是一個從機的例程,基本的工作是對外廣播,等待主機來連接,讀寫展示的屬性。首先打開工程文件,打開后可以看到整個工程的結(jié)構(gòu)。我們按照系統(tǒng)的啟動順序來一步一步走,我們都知道在C代碼中,一般啟動的首個函數(shù)為main,這個函數(shù)在 SimpleBLEPeripheral_Main.c中,打開文件,可以看到這個文件只有一個main函數(shù)和一個函數(shù)的申明,我們暫時不理會那個申明的函數(shù),先看main都做了些什么工作:Int main(void)/* Init

21、ialize hardware */HAL_BOARD_INIT(); / 硬件初始化/ Initialize board I/OInitBoard( OB_COLD ); / 板級初始化/* Initialze the HAL driver */HalDriverInit(); / Hal驅(qū)動初始化/* Initialize NV system */osal_snv_init(); / Flash存儲SNV初始化/* Initialize LL */* Initialize the operating system */osal_init_system(); / OSAL初始化/* Enab

22、le interrupts */HAL_ENABLE_INTERRUPTS(); / 使能總中斷/ Final board initializationInitBoard( OB_READY ); / 板級初始化#if defined ( POWER_SAVING )osal_pwrmgr_device( PWRMGR_BATTERY ); / 低功耗管理#endif/* Start OSAL */osal_start_system(); / No Return from here 啟動OSALreturn 0;通過代碼我們可以看到,系統(tǒng)啟動的過程,主要是做了一些初始化,如果開啟了低功耗,則還

23、需要開啟低功耗管理。我們先不去理會初始化做了什么,但是我們知道在main函數(shù)的最后啟動了OSAL,那么我們就進去看看OSAL是如何運作的。在IAR中如果需要跳轉(zhuǎn)到某個函數(shù)或變量的定義,可以在此函數(shù)名中右擊然后選擇Go To Definition就可以調(diào)到相應(yīng)的定義。void osal_start_system( void )#if !defined ( ZBIT ) & !defined ( UBIT )for(;) / Forever Loop#endifosal_run_system();這里看到我們進入了一個死循環(huán),并且一直調(diào)用osal_run_system(),那我們再進入此函數(shù)。vo

24、id osal_run_system( void )uint8 idx = 0;#ifndef HAL_BOARD_CC2538osalTimeUpdate(); / 定時器更新#endifHal_ProcessPoll(); / Hal層信息處理do if (tasksEventsidx) / Task is highest priority that is ready.break; while (+idx tasksCnt); / 檢查每個人任務(wù)是否有事件if (idx tasksCnt) / 有事件發(fā)生uint16 events;halIntState_t intState;HAL_EN

25、TER_CRITICAL_SECTION(intState); / 進入臨界區(qū)events = tasksEventsidx;tasksEventsidx = 0; / Clear the Events for this task. 清除事件標志HAL_EXIT_CRITICAL_SECTION(intState); / 退出臨界區(qū)activeTaskID = idx;events = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù)activeTaskID = TASK_NO_TASK;HAL_ENTER_CRITICAL_SECTION(intState);

26、 / 進入臨界區(qū)tasksEventsidx |= events; / Add back unprocessed events to the current task.HAL_EXIT_CRITICAL_SECTION(intState); / 退出臨界區(qū)#if defined( POWER_SAVING ) / 沒有事件發(fā)生,并且開啟了低功耗模式else / Complete pass through all task events with no activity? / 系統(tǒng)進入低功耗模式osal_pwrmgr_powerconserve(); / Put the processor/sy

27、stem into sleep#endif/* Yield in case cooperative scheduling is being used. */#if defined (configUSE_PREEMPTION) & (configUSE_PREEMPTION = 0)osal_task_yield();#endif在這里可以看到這個OSAL的核心,整個OSAL通過檢測每個任務(wù)是否有事件發(fā)生,如果有則執(zhí)行相應(yīng)的任務(wù),處理相應(yīng)的事件。如果沒有事件需要處理并且開啟了低功耗模式,則系統(tǒng)就會進入低功耗模式。這里有一個很關(guān)鍵的地方,OSAL是如何知道哪個事件需要哪個任務(wù)來處理呢?events

28、 = (tasksArridx)( idx, events ); / 執(zhí)行事件處理函數(shù)我們看這里有一個很關(guān)鍵的數(shù)組tasksArr,很顯然,這是一個函數(shù)指針數(shù)組,我們看看它的定義。const pTaskEventHandlerFn tasksArr =LL_ProcessEvent, / task 0Hal_ProcessEvent, / task 1HCI_ProcessEvent, / task 2#if defined ( OSAL_CBTIMER_NUM_TASKS )OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), / t

29、ask 3#endifL2CAP_ProcessEvent, / task 4GAP_ProcessEvent, / task 5GATT_ProcessEvent, / task 6SM_ProcessEvent, / task 7GAPRole_ProcessEvent, / task 8GAPBondMgr_ProcessEvent, / task 9GATTServApp_ProcessEvent, / task 10SimpleBLEPeripheral_ProcessEvent / task 11;可以看到在這個數(shù)組的定義中,每個成員都是任務(wù)的執(zhí)行函數(shù),按照任務(wù)的優(yōu)先級排序,并且在

30、osalInitTasks中初始化的時候,我們可以看到每個任務(wù)都有一個對應(yīng)的初始化函數(shù),并且傳遞了一個taskID,此ID從0開始自增,這里有一點非常重要,初始化的順序和任務(wù)數(shù)組的定義順序是一樣的,這就保證了我們給任務(wù)發(fā)生消息或事件時能夠準確的傳遞到相應(yīng)的任務(wù)處理函數(shù)。void osalInitTasks( void )uint8 taskID = 0;tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);osal_memset( tasksEvents, 0, (sizeof( uint16 ) * task

31、sCnt);/* LL Task */LL_Init( taskID+ );/* Hal Task */Hal_Init( taskID+ );/* HCI Task */HCI_Init( taskID+ );#if defined ( OSAL_CBTIMER_NUM_TASKS )/* Callback Timer Tasks */osal_CbTimerInit( taskID );taskID += OSAL_CBTIMER_NUM_TASKS;#endif/* L2CAP Task */L2CAP_Init( taskID+ );/* GAP Task */GAP_Init( taskID+ );/* GATT Task */GATT_Init( taskID+ );/* SM Task */SM_Init( taskID+ );/* Profiles */GAPRole_Init( taskID+ );GAPBondMgr_Init( taskID+ );GATTServApp_Init( taskID+ );/* Application */SimpleBLEPeripheral_Init( taskID );應(yīng)用層的初始化

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論