|
最近一直在學(xué)習(xí)USB,總算是稍微有點(diǎn)懂了。現(xiàn)在自己寫的PC端USB驅(qū)動(dòng)程序和應(yīng)用程序終于可以成功實(shí)現(xiàn)STM32的BULK /INT傳輸和有數(shù) 據(jù)/無(wú)數(shù)據(jù)傳輸控制請(qǐng)求等功能(STM32固件的程序我是用STM32 USB開(kāi)發(fā)工具包中的UART范例進(jìn)行的修改)。應(yīng)用程序與STM32通訊測(cè)試基 本沒(méi)啥問(wèn)題了,就是有關(guān)傳輸速度的問(wèn)題一直比較困惑。 STM32的USB接口是USB1.1的全速接口,進(jìn)行BULK傳輸?shù)臅r(shí)候,端點(diǎn)最 大的包大小按照USB規(guī)范是64個(gè)字節(jié),并且按照USB1.1FULLSPEED的規(guī)范,USB數(shù)據(jù)的傳輸是基于令牌的,也就是說(shuō)假如設(shè)備打算要向主機(jī)發(fā) 送數(shù)據(jù),必須先由主機(jī)發(fā)送一個(gè)IN的令牌,設(shè)備收到令牌后,緊接著在其第二階段送出要發(fā)送的數(shù)據(jù),如此完成一個(gè)數(shù)據(jù)的IN操作。 而規(guī)范上 定義令牌發(fā)送的間隔是1毫秒,這樣就意味著如果按照BULK傳輸最大64字節(jié)的規(guī)定,則最大傳輸速率是64字節(jié)*(1/1毫秒)=64K字節(jié)/秒。不過(guò)規(guī) 范上也說(shuō)到一個(gè)令牌后面可以跟多個(gè)USB傳輸事務(wù),也就是個(gè)令牌(1幀)最大可以跟15個(gè)64字節(jié)的數(shù)據(jù),1毫秒的間隔,這樣可以達(dá)到64字 節(jié)*15*1000 = 960K字節(jié)/秒的理論最大傳輸速度。 現(xiàn)在假如我有一個(gè)4KB的數(shù)據(jù)要傳輸,現(xiàn)在我是分成多個(gè)64字節(jié)的請(qǐng)求進(jìn) 行傳輸?shù)?,在BUS HOUND5上看到傳輸?shù)乃俣却蠹s只有40KB/S不到,顯然這個(gè)速度很不理想。我的問(wèn)題是怎樣才能在傳輸?shù)臅r(shí)候在一幀內(nèi)連續(xù)傳輸 15個(gè)事務(wù)使STM32傳輸速度最快?在STM32的USB開(kāi)發(fā)包中具體如何實(shí)現(xiàn)?有沒(méi)有這樣的程序范例能供學(xué)習(xí)下,還請(qǐng)大家不吝賜教,謝謝! ---------------------------------------------------------------------------------------------- 要想真正提高USB的傳輸速度,必須在驅(qū)動(dòng)中連續(xù)傳輸64字節(jié)的 也就是說(shuō),應(yīng)用程序必須將較大的數(shù)據(jù)包交給驅(qū)動(dòng)程序,由驅(qū)動(dòng)程序把這個(gè)較大的數(shù)據(jù)包拆成多個(gè)64字節(jié)的數(shù)據(jù)包并發(fā)送出去;同理接收時(shí),USB驅(qū)動(dòng)程序必須先把多個(gè)64字節(jié)的數(shù)據(jù)包組合成較大的數(shù)據(jù)包,再交給應(yīng)用程序處理。 關(guān)鍵的因素是應(yīng)用程序與驅(qū)動(dòng)程序的數(shù)據(jù)交換和調(diào)用轉(zhuǎn)換是非常耗時(shí)的! ---------------------------------------------------------------------------------------------- STM32進(jìn)行USB傳輸時(shí)提高傳輸速度-建議 首先,使用BULK傳輸來(lái)保證無(wú)差錯(cuò)的傳輸,這點(diǎn)應(yīng)該沒(méi)有疑義-已經(jīng)做了。 其次,建議把STM32的USB模擬成 Mass Storage的設(shè)備,從而自己可以不用寫驅(qū)動(dòng)程序,而借用M$的現(xiàn)成驅(qū)動(dòng)。 第三,STM32的Firmware端可以借用ST提供的參考代碼-U盤的那個(gè)代碼,從而可以模擬出來(lái)U盤。 第四,PC端的應(yīng)用程序可以自己編程,也可以使用ST提供的動(dòng)態(tài)鏈接庫(kù)(記得是storeacc.dll),該鏈接庫(kù)在ST-LINK/ST-LINK2的驅(qū)動(dòng)程序里面可以找到。假如PC端的應(yīng)用程序自己編程也不難,可以用DeviceIOControl來(lái)做。 目標(biāo)是:速度接近USB Full speed的U盤的速度,800kB估計(jì)可以做到。 ---------------------------------------------------------------------------------------------- 簡(jiǎn)易示波器暫停了,主要是聽(tīng)取大家的建議,要把STM32的USB功能用起來(lái),所以就開(kāi)始學(xué)USB啦,等把USB搞明白之后再繼續(xù)了。USB搞起來(lái)的難度可真不小,又是驅(qū)動(dòng)程序的編寫要學(xué),又是固件編程,到現(xiàn)在也沒(méi)搞明白。好在編程是件快樂(lè)的事情,哈哈~ 剛才又實(shí)驗(yàn)了下,現(xiàn)在驅(qū)動(dòng)程序方面的速度瓶頸已經(jīng)解決了。主要還是這個(gè)PipeMaxTransferSize的關(guān)系,這個(gè)值越大速度越快。晚上注意到這個(gè)值很多USB設(shè)備的驅(qū)動(dòng)程序都是設(shè)的很大的,連HID設(shè)備都設(shè)成4096,我的一個(gè)U盤也是4096,KEIL的ULINK設(shè)置成65535,幾乎所有USB設(shè)備驅(qū)動(dòng)的端點(diǎn)0都是設(shè)成65535。晚上測(cè)試了下,這個(gè)值不會(huì)影響數(shù)據(jù)傳輸,這個(gè)最大值不管怎么設(shè)實(shí)際USB設(shè)備管道每次接收的數(shù)據(jù)該64字節(jié)還是64字節(jié),應(yīng)該是WINDOWS核心驅(qū)動(dòng)層收到來(lái)自USB驅(qū)動(dòng)的IRP后會(huì)自動(dòng)拆包成與設(shè)備固件定義的大?。?4字節(jié))進(jìn)行發(fā)送的。 做了下速度對(duì)比 pipemaxtranfer:64---33KB/S pipemaxtranfer:512--265KB/S pipemaxtranfer:1024--349KB/S pipemaxtranfer:4096--457KB/S pipemaxtranfer:65535--506KB/S 又試著在STM32的固件上做了個(gè)改動(dòng) EP3_OUT的回調(diào)函數(shù)把緩沖拷貝的部分先注釋掉,如下: /******************************************************************************* * Function Name : EP3_IN_Callback * Description : * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP3_OUT_Callback(void) { //count_out = GetEPRxCount(ENDP3); //PMAToUserBufferCopy(buffer_out, ENDP3_RXADDR, count_out); SetEPRxValid(ENDP3); }這2句先注釋掉,使得STM32的EP3收到數(shù)據(jù)后不拷貝,直接發(fā)送接收有效,以測(cè)試最大速度,測(cè)試驅(qū)動(dòng)程序pipemaxtranfer設(shè)置4096情況下USB最大寫速度上升到822KB/S,在65535情況下998KB/S!。這樣看起來(lái)應(yīng)該驅(qū)動(dòng)程序應(yīng)該沒(méi)啥問(wèn)題了。 接下來(lái)還得再研究STM32的USB固件,估計(jì)做下優(yōu)化可能可以提高速度,比方說(shuō)拷貝采用DMA方式,采用其他更加優(yōu)化的端點(diǎn)緩沖方式等。因?yàn)槲矣玫氖荢TM32 USB開(kāi)發(fā)包中那個(gè)USART-USB的例子進(jìn)行的修改,應(yīng)該是先天不足還有不少可以優(yōu)化的地方吧。另外大家所說(shuō)的Mass Storage那個(gè)例子應(yīng)該速度在端點(diǎn)設(shè)置緩沖機(jī)制等等方面有值得借鑒的地方吧,打算晚上好好看看。另外在固件優(yōu)化方面還請(qǐng)大家繼續(xù)多出出主意啊:) ---------------------------------------------------------------------------------------------- USB要提速 1、使用自定義的Bulk傳輸 2、增加驅(qū)動(dòng)的Buffer ---------------------------------------------------------------------------------------------- 又熱心幫助大家,我也是從中學(xué)習(xí)了不少知識(shí),實(shí)在是感激:) 昨天晚上大致看了下Mass Storage的例子以及STM32的技術(shù)參考手冊(cè),晚上睡覺(jué)的時(shí)候仔細(xì)想了下(呵呵,發(fā)現(xiàn)好像睡覺(jué)的時(shí)候能安靜思考)。 主機(jī)向STM32發(fā)送數(shù)據(jù)的時(shí)候,傳輸?shù)乃俣仁?57KB/S,而當(dāng)我把STM32 用于接收的EP3_OUT回調(diào)函數(shù)中PMAToUserBufferCopy這2句話去掉的話速度就上升到了822KB/S,想來(lái)還是USB固件的處理速度限制了USB傳輸?shù)奶嵘吘怪鳈C(jī)是每發(fā)送64字節(jié)就等待USB設(shè)備回應(yīng),當(dāng)USB設(shè)備沒(méi)有完成相應(yīng)的操作時(shí)狀態(tài)始終是NAK,于是主機(jī)就一直重發(fā),一直到設(shè)備完成相應(yīng)的操作將端口置VALID后主機(jī)才能接著發(fā)下一個(gè)64字節(jié)。從457KB/S到822KB/S(當(dāng)然這個(gè)速度是純粹的傳輸速度實(shí)際上接收后是還要處理的)速度差別還是很大的,應(yīng)該還有辦法提升的。 上面幾位說(shuō)到改用MASS STORAGE的例子,大致看了下其實(shí)也是一樣的,在BULK傳輸時(shí)候,都是采用一樣的EP 單向BULK操作,64字節(jié)的管道尺寸,我現(xiàn)在的固件也是這樣用的,沒(méi)什么不同。問(wèn)題不在于用哪個(gè)例程哪個(gè)設(shè)備類型,而應(yīng)該在于怎么去提高BULK傳輸?shù)奶幚硭俣壬习伞?br> 昨天在看STM32技術(shù)參考手冊(cè)的時(shí)候18.5.3提到了雙緩沖端點(diǎn),實(shí)現(xiàn)所謂PING-PONG機(jī)制,可以應(yīng)用在同步和批量傳輸,我想把現(xiàn)有的EP傳輸方式改成雙緩沖機(jī)制,應(yīng)該能提高BULK的傳輸速度吧。剛剛找了下資料 普通單緩沖機(jī)制的OUT過(guò)程: 1、主機(jī)發(fā)出OUT 2、設(shè)備接收該OUT包,檢測(cè)緩沖區(qū),當(dāng)緩沖區(qū)由MPU占據(jù)時(shí)一直置NAK,主機(jī)不斷重發(fā)數(shù)據(jù)包 3、當(dāng)MPU放棄緩沖區(qū)占有(完成了相應(yīng)的操作)后,置ACK,可接收下一個(gè)OUT包 4、主機(jī)發(fā)送下一個(gè)OUT包 ---------------------------------------------------------------------------------------------- 單緩沖模式就跟單線程一樣, 一個(gè)一個(gè)排隊(duì)依次順序執(zhí)行,因此速度受緩沖區(qū)占用情況的嚴(yán)重影響,尤其當(dāng)單片機(jī)處理速度慢時(shí)更嚴(yán)重。 雙緩沖端點(diǎn)機(jī)制:雙緩沖機(jī)制有兩塊緩沖區(qū)在一個(gè)時(shí)間點(diǎn)上可分別由USB端點(diǎn)和MCU來(lái)占有 1、主機(jī)發(fā)送OUT1包 2、設(shè)備接收OUT1包并寫入空閑的Buffer1,并置ACK,可以接收下一個(gè)OUT1包,同時(shí)buffer1的控制權(quán)可以交給MCU完成處理。 3、主機(jī)發(fā)送下一個(gè)OUT2包,設(shè)備將OUT2放入空閑的buffer2包,并置ACK,通知主機(jī)可以發(fā)送下一個(gè)OUT3包。 同時(shí)MCU繼續(xù)完成上上一個(gè)OUT1包的處理后,釋放BUFFER1的控制權(quán),可以接下來(lái)占有buffer2進(jìn)行處理 4、主機(jī)發(fā)送OUT3包,此時(shí)由于buffer1已經(jīng)由MCU完成處理釋放了控制器,設(shè)備接收OUT3包并放入BUFFER1中,置ACK,再通知主機(jī)可以發(fā)送下一個(gè)OUT4包 ... 由此可見(jiàn)雙緩沖機(jī)制,依次交換2個(gè)緩沖區(qū)的所有權(quán),看起來(lái)就類似與雙線程一樣,USB端點(diǎn)接收和MCU數(shù)據(jù)包處理是同時(shí)在進(jìn)行的,減少了傳輸時(shí)候等待MCU完成接收包處理的等候,大大地提高了傳輸?shù)男省?br> 現(xiàn)在打算把BULK改成雙緩沖試試,看看對(duì)速度能有多大改善。遺憾的是在MASS_STORAGE沒(méi)有采用雙緩沖機(jī)制。原理是了解了,不過(guò)還不清楚固件該怎么具體怎么編程,哪里有BULK雙緩沖傳輸?shù)睦涌梢詫W(xué)習(xí)一下? ---------------------------------------------------------------------------------------------- 來(lái)自(http://bbs./forum-126-1.html) |
|
|