《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 通信與網(wǎng)絡(luò) > 設(shè)計(jì)應(yīng)用 > 基于K64的USB驅(qū)動(dòng)構(gòu)件化設(shè)計(jì)
基于K64的USB驅(qū)動(dòng)構(gòu)件化設(shè)計(jì)
2017年電子技術(shù)應(yīng)用第7期
胡唯唯1,王宜懷1,張 永2
1.蘇州大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,江蘇 蘇州215006;2.蘇州華祥信息科技有限公司,江蘇 蘇州215006
摘要: USB由于其支持熱插拔、接口簡單、擴(kuò)展方便以及數(shù)據(jù)傳輸率高等特點(diǎn),已經(jīng)成為當(dāng)前主流的數(shù)據(jù)通信方式。USB協(xié)議比較復(fù)雜,驅(qū)動(dòng)程序的開發(fā)具有一定難度,同時(shí)由于硬件平臺的多樣性,使得開發(fā)過程中有很多重復(fù)性的工作。鑒于此,根據(jù)USB協(xié)議棧架構(gòu)和驅(qū)動(dòng)構(gòu)件化思想設(shè)計(jì)了USB驅(qū)動(dòng)構(gòu)件;并使用恩智浦半導(dǎo)體公司的K64微控制器,在KDS 3.0環(huán)境下對該構(gòu)件進(jìn)行測試,作為一個(gè)HID(人機(jī)接口)設(shè)備與PC的上位機(jī)軟件之間通信,為USB驅(qū)動(dòng)程序的開發(fā)提供了基本規(guī)范和參考。
中圖分類號: TP311
文獻(xiàn)標(biāo)識碼: A
DOI:10.16157/j.issn.0258-7998.2017.07.014
中文引用格式: 胡唯唯,王宜懷,張永. 基于K64的USB驅(qū)動(dòng)構(gòu)件化設(shè)計(jì)[J].電子技術(shù)應(yīng)用,2017,43(7):55-58.
英文引用格式: Hu Weiwei,Wang Yihuai,Zhang Yong. The development of USB driver component based on K64[J].Application of Electronic Technique,2017,43(7):55-58.
The development of USB driver component based on K64
Hu Weiwei1,Wang Yihuai1,Zhang Yong2
1.College of Computer Science and Technology,Soochow University,Suzhou 215006,China; 2.Suzhou Huaxiang Information Technology Company,Suzhou 215006,China
Abstract: USB has developed into one major means of current data-communication due to its rewarding features , including hot-plugging availability, simplified interface, convenient extension and high-efficiency transmission. Due to the complexity of USB protocol stack, it is difficult to develop the driver. Furthermore, much repeated work exists in the development process because of the variety of the hardware platform. Therefore, the USB driver component is designed in accordance with the USB protocol stack and the thought of driver component. Then it is tested using the K64 MCU from NXP Semiconductor in the KDS 3.0 IDE, which works as a HID device to communicate with PC software. This provides the basic rules and references for the development of USB driver component.
Key words : USB;driver component;K64;enumeration

0 引言

    USB現(xiàn)已成為嵌入式設(shè)備的一種主要通信接口,但是由于USB協(xié)議的復(fù)雜性和硬件平臺的多樣性,使得USB驅(qū)動(dòng)程序開發(fā)存在難度大、成本高、可移植差、難以維護(hù)等缺點(diǎn)。為了解決這些問題,本文在深入分析USB協(xié)議的基礎(chǔ)上,對USB設(shè)備的功能進(jìn)行抽象,并采用驅(qū)動(dòng)構(gòu)件化的設(shè)計(jì)思想開發(fā)USB驅(qū)動(dòng)構(gòu)件[1]。同時(shí),在Kinetis Design Studio 3.0集成開發(fā)環(huán)境下,使用恩智浦半導(dǎo)體公司的K64微控制器對該構(gòu)件進(jìn)行測試,將其作為一個(gè)HID設(shè)備與上位機(jī)程序進(jìn)行通信。上位機(jī)軟件在VS 2010環(huán)境下使用C#語言開發(fā),可以動(dòng)態(tài)找到目標(biāo)設(shè)備,實(shí)現(xiàn)快速連接和通信。另外,將該通信系統(tǒng)用于3D打印中,通過對打印產(chǎn)品的紋理進(jìn)行分析,驗(yàn)證本文所開發(fā)的USB構(gòu)件的穩(wěn)定性。

1 USB協(xié)議分析

    USB驅(qū)動(dòng)程序主要完成USB設(shè)備的初始化、枚舉和數(shù)據(jù)傳輸。USB主機(jī)與USB設(shè)備之間有4種數(shù)據(jù)傳輸類型,分別是批量傳輸、中斷傳輸、同步傳輸和控制傳輸,每種傳輸方式執(zhí)行一次需要多個(gè)事務(wù)處理[2]。對于控制傳輸,其只能用于USB設(shè)備枚舉,包括3個(gè)階段,分別為設(shè)置階段、數(shù)據(jù)階段和狀態(tài)階段。設(shè)置階段是一次SETUP事務(wù)處理,數(shù)據(jù)階段是多個(gè)IN或者OUT事務(wù)處理,狀態(tài)階段是一次無數(shù)據(jù)傳輸?shù)腎N或者OUT事務(wù)處理。USB設(shè)備枚舉完成后,將使用其他傳輸方式用于實(shí)際數(shù)據(jù)收發(fā),具體使用哪種方式則取決于設(shè)備的類型。USB設(shè)備連接到PC后,PC便開始對其進(jìn)行枚舉[3]。不同操作系統(tǒng)下枚舉過程可能會有所不同,Windows操作系統(tǒng)下的USB設(shè)備枚舉過程為:

    (1)用戶將USB設(shè)備插入到PC(USB主機(jī))的USB端口上,USB主機(jī)給USB設(shè)備上電,USB設(shè)備獲取100 mA的電流,并處于上電狀態(tài);

    (2)USB主機(jī)檢測USB設(shè)備是全速還是低速設(shè)備,如果D+數(shù)據(jù)線上有高電平則是全速設(shè)備,如果D-數(shù)據(jù)線上有高電平則是低速設(shè)備;

    (3)USB主機(jī)復(fù)位USB設(shè)備,復(fù)位時(shí)間至少10 ms。復(fù)位結(jié)束后USB設(shè)備處于默認(rèn)狀態(tài),并使用默認(rèn)的地址0和端點(diǎn)0與USB主機(jī)進(jìn)行通信;

    (4)USB主機(jī)獲取USB設(shè)備的18 B的設(shè)備描述符,完成一次控制傳輸。這是USB主機(jī)第一次得到設(shè)備描述符,主機(jī)并不會分析各個(gè)字段的含義,只會得到設(shè)備描述符中端點(diǎn)0所支持的最大數(shù)據(jù)包長度(設(shè)備描述符的第8字節(jié));

    (5)USB主機(jī)再一次復(fù)位USB設(shè)備,這一步在USB 2.0協(xié)議中并不要求。另外,對于高速設(shè)備,Windows 8及以上版本會跳過這一步;

    (6)USB主機(jī)給USB設(shè)備分配一個(gè)唯一的地址,USB設(shè)備進(jìn)入地址狀態(tài),之后USB設(shè)備將使用這個(gè)新的地址與USB主機(jī)進(jìn)行通信。只要USB設(shè)備不被移除、復(fù)位或者重新啟動(dòng),那么這個(gè)地址將一直存在;

    (7)USB主機(jī)獲取配置描述符,及其從屬的接口和端點(diǎn)描述符。如果還有字符串描述符,則繼續(xù)獲取。對于HID類設(shè)備,USB主機(jī)還會獲取報(bào)告描述符; 

    (8)獲取以上USB設(shè)備的相關(guān)信息后,USB主機(jī)會為USB設(shè)備分配并加載一個(gè)合適的設(shè)備驅(qū)動(dòng)程序;

    (9)USB主機(jī)對USB設(shè)備進(jìn)行配置,USB設(shè)備進(jìn)入配置狀態(tài)。對于HID類設(shè)備,則初始化一個(gè)上行傳輸IN端點(diǎn)和一個(gè)下行傳輸OUT端點(diǎn),上行傳輸是USB設(shè)備向PC上傳數(shù)據(jù),下行傳輸是PC向USB設(shè)備發(fā)送數(shù)據(jù)[4]。

    枚舉完成后,USB設(shè)備可以和USB主機(jī)進(jìn)行數(shù)據(jù)傳輸。枚舉和枚舉完成后的數(shù)據(jù)傳輸過程中執(zhí)行一次事務(wù)處理就會產(chǎn)生一次中斷。USB中斷包括復(fù)位中斷、令牌中斷、STALL中斷和SOF中斷等,其中令牌中斷包括SETUP令牌中斷、IN令牌中斷和OUT令牌中斷。一次事務(wù)處理由令牌包、數(shù)據(jù)包和握手包組成,令牌包表明此次事務(wù)處理的目的,數(shù)據(jù)包中包含了要傳輸?shù)臄?shù)據(jù),握手包表明此次事務(wù)處理的完成狀態(tài)[5]。圖1是USB設(shè)備枚舉和數(shù)據(jù)收發(fā)的執(zhí)行流程圖。

qrs2-t1.gif

2 USB驅(qū)動(dòng)構(gòu)件設(shè)計(jì)

    驅(qū)動(dòng)構(gòu)件的設(shè)計(jì)應(yīng)滿足可復(fù)用性、可移植性和可維護(hù)性,其中復(fù)用性是設(shè)計(jì)目標(biāo),是軟件成熟的標(biāo)志。軟件的復(fù)用可以降低軟件開發(fā)的難度、減少重復(fù)勞動(dòng)、降低開發(fā)成本、提高開發(fā)效率和軟件質(zhì)量、縮短軟件開發(fā)周期[6]。驅(qū)動(dòng)構(gòu)件由.c源文件和.h頭文件組成。源文件是構(gòu)件的功能函數(shù)實(shí)現(xiàn),函數(shù)分為對外接口函數(shù)和內(nèi)部函數(shù),對外接口函數(shù)供外部調(diào)用,內(nèi)部函數(shù)僅內(nèi)部調(diào)用;頭文件是構(gòu)件的功能描述,其中包含了對外接口函數(shù)聲明、相關(guān)宏定義和類型定義等。在實(shí)際使用時(shí),構(gòu)件應(yīng)滿足兩點(diǎn):無需打開源文件,只要通過讀頭文件就知道如何使用;在不同芯片上使用時(shí),只需要做少量修改或者無需修改。

    K64要作為USB設(shè)備使用,必須初始化USB模塊。上電后需要完成設(shè)備枚舉,設(shè)備枚舉過程需要做很多處理,但是所有USB設(shè)備的枚舉過程基本上是一樣的,因此設(shè)備枚舉可以作為一個(gè)函數(shù)進(jìn)行集中處理。USB總線是輪詢式的,所有的通信都是由USB主機(jī)發(fā)起的,因此設(shè)備不能主動(dòng)向USB主機(jī)發(fā)送數(shù)據(jù),只能將要發(fā)給USB主機(jī)的數(shù)據(jù)準(zhǔn)備好等待USB主機(jī)來取。為了方便向USB主機(jī)發(fā)送數(shù)據(jù),在構(gòu)件中封裝一個(gè)發(fā)送數(shù)據(jù)函數(shù)。如果有數(shù)據(jù)要發(fā)送給USB主機(jī),則調(diào)用該函數(shù)將要發(fā)送的數(shù)據(jù)填入指定的緩沖區(qū)內(nèi)即可,在下一次事務(wù)處理中由USB主機(jī)取出,使得USB設(shè)備可以“主動(dòng)”發(fā)送數(shù)據(jù)?;谝陨戏治觯?USB驅(qū)動(dòng)構(gòu)件將封裝4個(gè)函數(shù),分別是初始化函數(shù)usb_init、枚舉處理函數(shù)usb_enumerate、發(fā)送數(shù)據(jù)函數(shù)usb_send和接收數(shù)據(jù)函數(shù)usb_recv。

2.1 usb_init函數(shù)

    初始化函數(shù)usb_init完成對USB模塊的初始化,主要包括內(nèi)存分配、時(shí)鐘源使能和使能USB中斷等。每一個(gè)USB設(shè)備都有一個(gè)序列號,同VID和PID一起作為設(shè)備的標(biāo)識符,當(dāng)兩個(gè)VID和PID都一樣的USB設(shè)備插入到PC時(shí),序列號可以起到進(jìn)一步區(qū)分的作用。序列號實(shí)際上是一個(gè)字符串描述符,考慮其用于唯一性標(biāo)識USB設(shè)備的作用,將其作為USB設(shè)備的名稱,并傳入初始化函數(shù)中,這樣開發(fā)者就能夠方便命名自己的USB設(shè)備。

2.2 usb_enumerate函數(shù)

    枚舉處理函數(shù)usb_enumerate完成枚舉過程中的控制傳輸,該函數(shù)一般情況下無需改動(dòng)。本驅(qū)動(dòng)構(gòu)件是針對HID設(shè)備的,如果要開發(fā)為其他類型的設(shè)備,在修改描述符后,只需要對該函數(shù)做少量修改即可。以MSD設(shè)備為例,將HID設(shè)備的描述符文件usb_hid_device_descriptor.c替換為MSD設(shè)備的描述符文件usb_msd_device_descriptor.c。比較這兩個(gè)描述符文件,發(fā)現(xiàn)前者比后者多一個(gè)報(bào)告描述符,同時(shí)字符串描述符也不同。為了盡量減少對usb_enumerate函數(shù)代碼的修改,可以將MSD設(shè)備的設(shè)備描述符、配置描述符及其從屬的接口和端點(diǎn)描述符的名稱根據(jù)HID設(shè)備作對應(yīng)修改。這樣,只需要?jiǎng)h除usb_enumerate函數(shù)中對報(bào)告描述符的處理即可。

2.3 usb_send和usb_recv函數(shù)

    發(fā)送數(shù)據(jù)函數(shù)usb_send和接收數(shù)據(jù)函數(shù)usb_recv用于數(shù)據(jù)的收發(fā)。為了方便數(shù)據(jù)的收發(fā),這兩個(gè)函數(shù)都有兩個(gè)參數(shù)。usb_send函數(shù)的兩個(gè)參數(shù)為SendBuff和DataLenght,usb_recv函數(shù)的兩個(gè)參數(shù)為RecvBuff和DataLength。進(jìn)行數(shù)據(jù)發(fā)送時(shí),只要將待發(fā)送數(shù)據(jù)的緩沖區(qū)地址和發(fā)送的數(shù)據(jù)長度傳入發(fā)送數(shù)據(jù)函數(shù)usb_send的SendBuff和DataLength即可,下一次事務(wù)處理結(jié)束后,相應(yīng)緩沖區(qū)中的數(shù)據(jù)就會被發(fā)送出去。接收數(shù)據(jù)和發(fā)送數(shù)據(jù)的執(zhí)行是一樣的,只是接收的數(shù)據(jù)已經(jīng)在本次事務(wù)處理中,只要使用usb_recv函數(shù)從相應(yīng)端點(diǎn)的BD中取出即可,RecvBuff用于存放取出的數(shù)據(jù),DataLength是取出的數(shù)據(jù)長度。

3 上位機(jī)軟件設(shè)計(jì)

    上位機(jī)軟件使用Windows提供的API函數(shù)對HID設(shè)備進(jìn)行訪問,這些API函數(shù)包含在hid.dll、setupapi.dll、kernel32.dll文件中,分別起到與HID設(shè)備通信、尋找與識別設(shè)備、交換數(shù)據(jù)的作用[7],關(guān)于相關(guān)API函數(shù)的介紹可以查看MSDN。

    PC與USB設(shè)備建立連接的第一步就是找到該設(shè)備,上位機(jī)軟件必須時(shí)刻能夠檢測到USB設(shè)備的插入和移除事件,因此必須在相關(guān)窗體句柄創(chuàng)建時(shí)將這些事件通過RegisterDeviceNotification函數(shù)進(jìn)行注冊,該函數(shù)位于user32.dll文件中。

    當(dāng)檢測到一個(gè)新的USB設(shè)備插入或者被移除時(shí),Windows將向應(yīng)用程序發(fā)送一個(gè)WM_DEVICECHANGE消息,該消息宏定義為0x0219。然后由默認(rèn)的消息處理函數(shù)WndProc進(jìn)行處理,程序中對WndProc進(jìn)行了重寫,以滿足尋找目標(biāo)設(shè)備的要求[8]。WndProc函數(shù)首先獲取USB總線上指定類型的設(shè)備列表,通過調(diào)用setupapi.dll文件中函數(shù)SetupDiGetClassDevs實(shí)現(xiàn)。SetupDiGetClassDevs函數(shù)的第一個(gè)參數(shù)是HID GUID,GUID是設(shè)備類型的唯一標(biāo)識符,HID類設(shè)備的GUID可以通過hid.dll文件中的HidD_GetHidGuid函數(shù)獲取,為固定值4d1e55b2-f16f-11cf-88cb-001111000030。該函數(shù)的返回值是當(dāng)前USB總線上所有HID類設(shè)備的信息,并保存于InfoSet隊(duì)列中。為了從InfoSet隊(duì)列中找到目標(biāo)設(shè)備,需要調(diào)用setupapi.dll 文件中的SetupDiEnumDeviceInterfaces函數(shù)遍歷InfoSet隊(duì)列,并將每個(gè)設(shè)備的信息保存于DeviceInterfaceData 結(jié)構(gòu)體變量oInterface中。接著,從oInterface中獲取該設(shè)備的VID和PID,然后和目標(biāo)設(shè)備的VID和PID進(jìn)行匹配檢查,以確定該設(shè)備是否為目標(biāo)設(shè)備[9]。如果匹配則找到了目標(biāo)設(shè)備,否則繼續(xù)調(diào)用SetupDiEnumDeviceInterfaces函數(shù),獲取下一個(gè)設(shè)備的信息并繼續(xù)進(jìn)行匹配檢查,直到找到目標(biāo)設(shè)備或者InfoSet隊(duì)列中的設(shè)備都查找完畢為止。

    如果沒有找到目標(biāo)設(shè)備,則回收InfoSet占用的內(nèi)存。如果目標(biāo)設(shè)備找到,則使用該設(shè)備路徑作為參數(shù)并調(diào)用CreateFile函數(shù)打開該設(shè)備,之后就可以像讀寫文件一樣操作該設(shè)備。圖2是上位機(jī)軟件尋找USB設(shè)備和執(zhí)行數(shù)據(jù)傳輸?shù)牧鞒虉D。

qrs2-t2.gif

4 構(gòu)件測試與分析

    圖3為數(shù)據(jù)和局部波形圖,圖3(a)是獲取設(shè)備描述符時(shí)使用TravelBus協(xié)議分析儀采集的數(shù)據(jù),圖3(b)是對應(yīng)的局部波形。枚舉過程中USB主機(jī)首先獲取USB設(shè)備的設(shè)備描述符。USB主機(jī)向USB設(shè)備發(fā)送一個(gè)SETUP令牌包,然后是DATA0數(shù)據(jù)包,該數(shù)據(jù)包中包含了8個(gè)字節(jié)的十六進(jìn)制數(shù)據(jù)80 06 00 01 00 00 40 00,該8個(gè)字節(jié)的數(shù)據(jù)是獲取設(shè)備描述符的標(biāo)準(zhǔn)設(shè)備請求。USB設(shè)備接收到該請求后開始處理并向USB主機(jī)返回一個(gè)ACK握手包,表明此次SETUP事務(wù)處理是成功的,從而完成控制傳輸?shù)脑O(shè)置階段。隨后USB主機(jī)發(fā)送IN令牌包開始取設(shè)備描述符,但是USB設(shè)備此時(shí)并沒有將設(shè)備描述符準(zhǔn)備好,因此USB設(shè)備直接向USB主機(jī)發(fā)送一個(gè)NACK不確認(rèn)包。

qrs2-t3.gif

    USB主機(jī)繼續(xù)發(fā)送獲取設(shè)備描述符的IN令牌包,USB設(shè)備返回準(zhǔn)備好的18個(gè)字節(jié)的設(shè)備描述符12 01 00 02 00 00 00 40 A2 15 7F 00 01 01 01 02 00 01,其中PID是0x15A2(第9和第10字節(jié)),VID是0x007F(第11和第12字節(jié))。之后,USB主機(jī)向USB設(shè)備發(fā)送一個(gè)ACK確認(rèn)包,完成控制傳輸?shù)臄?shù)據(jù)階段。最后,USB主機(jī)發(fā)送一個(gè)OUT令牌包,再發(fā)送一個(gè)無數(shù)據(jù)的DATA1數(shù)據(jù)包,USB設(shè)備接收到之后返回一個(gè)ACK握手包,從而完成此次控制傳輸?shù)臓顟B(tài)階段[10]。設(shè)備枚舉成功后,PC將USB設(shè)備掛載到設(shè)備列表中。

5 應(yīng)用

    目前使用DLP技術(shù)的3D打印機(jī)需要與PC進(jìn)行通信,通信的實(shí)時(shí)性和穩(wěn)定性至關(guān)重要。將該USB通信系統(tǒng)應(yīng)用于3D打印中,可以提高打印的穩(wěn)定性和實(shí)時(shí)性。打印過程中數(shù)據(jù)丟包率低、實(shí)時(shí)性高,使得所打印的產(chǎn)品紋理的連續(xù)性高(無斷層)、效果逼真。打印成品與局部紋理放大20 000倍效果如圖4所示。

qrs2-t4.gif

6 結(jié)論

    本文在深入分析USB協(xié)議的基礎(chǔ)上,按照構(gòu)件化設(shè)計(jì)思想編寫USB驅(qū)動(dòng)構(gòu)件,同時(shí)以恩智浦半導(dǎo)體公司的K64作為測試對象,并編寫上位機(jī)軟件,實(shí)現(xiàn)與PC之間的USB通信。另外,將該USB通信系統(tǒng)用于實(shí)際項(xiàng)目3D打印中,打印的產(chǎn)品滿足要求。本文所設(shè)計(jì)的USB驅(qū)動(dòng)構(gòu)件封裝簡單合理、設(shè)備枚舉清晰、代碼移植性高、通信穩(wěn)定高效,可以作為驅(qū)動(dòng)程序的開發(fā)模板,同時(shí)對USB驅(qū)動(dòng)程序開發(fā)的規(guī)范性和可移植性具有很高的參考意義。

參考文獻(xiàn)

[1] 龍飛,何欽銘.構(gòu)件化開發(fā)方法在J2EE 項(xiàng)目中的應(yīng)用[J].計(jì)算機(jī)工程與設(shè)計(jì),2007,28(3):591-594.

[2] 黃櫻,劉君,劉卉,等.基于ARM的嵌入式USB主機(jī)系統(tǒng)設(shè)計(jì)[J].微計(jì)算機(jī)信息(嵌入式與SOC),2007,22(2):156-157.

[3] ZHU J,WANG S,ZHANG S Y,et al.Embedded diver system for USB mouse[C].International Conference on Electrical & Control Engineering,2011:180-183.

[4] 侯代文,孫濤,鄧?yán)诿?TMS320VC33與主機(jī)通信的USB接口設(shè)計(jì)[J].電子設(shè)計(jì)工程,2015,23(7):166-170.

[5] 王宜懷,吳璟,蔣銀珍.嵌入式系統(tǒng)原理與實(shí)踐—ARM Cortex-M4 Kinetis微控制器[M].北京:電子工業(yè)出版社,2012.

[6] 呂明琪,薛錦云,胡啟敏.基于軟件體系結(jié)構(gòu)的可復(fù)用構(gòu)件模型[J].計(jì)算機(jī)應(yīng)用研究,2008,25(1):120-122.

[7] 楊晶晶,江春華.USB HID設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)[J].微計(jì)算機(jī)信息(嵌入式與SOC),2006,22(6):140-142.

[8] 郭夏夏.動(dòng)平衡測試系統(tǒng)的關(guān)鍵技術(shù)研究[D].上海:上海交通大學(xué),2014.

[9] WATANABE H,MASAOKA H,OHIGASHI T,et al.Supporting USB devices for the global migration[J].IPSJ International Symposium on Applications & the Internet,2010:153-156.

[10] DONG Z Y,ZHAO H.Data transfer principles and implementation in USB microwave power sensor[C].Seventh International Symposium on Computational Intelligence & Design,2014:76-79.



作者信息:

胡唯唯1,王宜懷1,張  永2

(1.蘇州大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,江蘇 蘇州215006;2.蘇州華祥信息科技有限公司,江蘇 蘇州215006)

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。