問題描述
客戶反饋,使用STM32F446的高速USB外設(shè),即USB_OTG_HS外設(shè),且使用內(nèi)置全速PHY。客戶的產(chǎn)品USB用做device,自定義HID類,當(dāng)連接帶UOS操作系統(tǒng)的HOST時(shí),會(huì)發(fā)現(xiàn)當(dāng)前數(shù)據(jù)并沒有成功發(fā)送,但是會(huì)發(fā)送上一次的數(shù)據(jù),即發(fā)送數(shù)據(jù)出現(xiàn)”遲滯”現(xiàn)象。但在Windows下卻沒有出現(xiàn)此類問題。另外,客戶同時(shí)還使用了STM32F446上的USB_OTG_FS外設(shè),且此外設(shè)做同樣的事一切正常,目前此問題只出現(xiàn)在USB_OTG_HS外設(shè)上。
問題查找
剛開始猜測(cè)是長(zhǎng)度問題,即發(fā)送最大包長(zhǎng)需要再發(fā)送一次空包。但客戶反饋他們的發(fā)送長(zhǎng)度為62個(gè)字節(jié)。于是去客戶現(xiàn)場(chǎng)使用USB協(xié)議分析儀采數(shù)分析,發(fā)現(xiàn)一切通信正常。
通過查看客戶演示重現(xiàn)問題的過程,發(fā)現(xiàn)在正常時(shí)是一切OK的,只在進(jìn)行USB拔插時(shí)才發(fā)送問題。應(yīng)用程序不斷發(fā)送數(shù)據(jù)的過程中拔掉USB線,然后再次插上,在此過程中應(yīng)用程序一直嘗試發(fā)送數(shù)據(jù)。當(dāng)USB線重新連接上且重新枚舉成功后,“遲滯”現(xiàn)象則重現(xiàn)了,即每次應(yīng)用程序調(diào)用發(fā)送接口實(shí)現(xiàn)發(fā)送的是上一次嘗試發(fā)送的內(nèi)容。
調(diào)試客戶的程序,發(fā)現(xiàn)當(dāng)USB線拔掉后,應(yīng)用程序還會(huì)往USB IP對(duì)應(yīng)的發(fā)送FIFO內(nèi)寫入數(shù)據(jù),這其實(shí)是不對(duì)的。按理USB線拔掉后USB的狀態(tài)應(yīng)該恢復(fù)到默認(rèn)狀態(tài),
即pdev->dev_state=USBD_STATE_DEFAULT. 但實(shí)際上,通過調(diào)試發(fā)現(xiàn)此狀態(tài)在USB線拔掉后是suspend狀態(tài)。
那么為什么會(huì)是這樣的呢?
于是立即想到Vbus sensing功能。馬上與客戶硬件工程師核對(duì),原來客戶產(chǎn)品的USB_OTG_HS的Vbus_sensing腳是懸空的,并沒有連接Vbus,但是客戶的USB_OTG_FS外設(shè)卻又是連接了。于是客戶的產(chǎn)品兩個(gè)USB口,同樣的工作,一個(gè)USB口 正常,另一個(gè)USB口卻會(huì)出現(xiàn)問題。
問題分析
差異找到了,接下來就是分析由此如何造成問題的。
由于USB_OTG_HS并沒有真正實(shí)現(xiàn)Vbus sensing功能(因?yàn)闆]有硬件連接),于是當(dāng)USB線斷開時(shí),應(yīng)用程序并不能準(zhǔn)確地檢測(cè)到斷開事件(Disconnected),只會(huì)出現(xiàn)suspend,應(yīng)用程序是無法直接的區(qū)分真正的suspend和USB線斷開連接的。當(dāng)應(yīng)用程序有數(shù)據(jù)需要通過USB口發(fā)送時(shí),如果當(dāng)前是suspend狀態(tài),那么它會(huì)首先喚醒USB總線然后再發(fā)送數(shù)據(jù):
Figure1
而這樣發(fā)送遠(yuǎn)程喚醒信號(hào)時(shí),device本身會(huì)產(chǎn)生一個(gè)resume中斷,于是在resume中斷回調(diào)函數(shù)內(nèi):
Figure 2
如上所示,程序會(huì)將dev_state錯(cuò)誤地恢復(fù)到上一次狀態(tài),即正常狀態(tài)USBD_STATE_CONFIGURED, 如此一來,程序就錯(cuò)誤地往USB IP的內(nèi)的發(fā)送FIFO寫入數(shù)據(jù)了,即使此時(shí)由于USB線已經(jīng)斷開而導(dǎo)致無法真正發(fā)送成功,但USB IP的內(nèi)置發(fā)送FIFO此時(shí)是有了數(shù)據(jù)的。
通過調(diào)試,查看OTG_DTXFSTS1寄存器相應(yīng)端點(diǎn)1對(duì)應(yīng)的發(fā)送FIFO的剩余空間可知,這個(gè)時(shí)候的發(fā)送FIFO的確實(shí)有數(shù)據(jù)的。接下來是USB線插上重新枚舉,那么為什么USB重新枚舉后還會(huì)再現(xiàn)問題呢?通過設(shè)置斷點(diǎn)發(fā)現(xiàn),在USB成功重新枚舉過后,通過OTG_DTXFSTS1寄存器指示,發(fā)送FIFO內(nèi)容并沒有清空,于是在接下來發(fā)送數(shù)據(jù)時(shí),永遠(yuǎn)都是實(shí)際上發(fā)送的是上一次寫入到FIFO中的數(shù)據(jù)。
問題解決
▼于是解決方法就很容易找到了▼
在USB重新枚舉過后在合適的地方將端點(diǎn)1對(duì)應(yīng)的發(fā)送FIFO清空一下即可。
Figure 3
問題總結(jié)
在客戶的這個(gè)案子中,由于USB_OTG_FS連接了VBUS SENSING腳,當(dāng)USB線拔掉后,會(huì)產(chǎn)生正確的disconnect中斷,USB device的狀態(tài)也會(huì)正確地切換到default狀態(tài),從而過濾掉應(yīng)用程序想要發(fā)送的數(shù)據(jù),因此并不會(huì)出現(xiàn)類似問題,因此,在客戶的產(chǎn)品設(shè)計(jì)中,建議硬件千萬不要忘了連接vbus引腳,即使在想省IO引腳的情況下,這樣容易造成對(duì)軟件的開發(fā)諸多不便.
在USB的狀態(tài)處于非configured狀態(tài)時(shí),最好不要往發(fā)送FIFO寫入數(shù)據(jù),應(yīng)用程序應(yīng)該想辦法將這些數(shù)據(jù)過濾掉。
來源:STM32單片機(jī)
審核編輯:湯梓紅
-
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44992瀏覽量
650580 -
接口
+關(guān)注
關(guān)注
33文章
9005瀏覽量
153769 -
usb
+關(guān)注
關(guān)注
60文章
8190瀏覽量
272996 -
STM32
+關(guān)注
關(guān)注
2293文章
11032瀏覽量
365040
發(fā)布評(píng)論請(qǐng)先 登錄
ESP32-S3 USB CDC虛擬串口發(fā)送數(shù)據(jù)失敗的原因?
STM32 USB數(shù)據(jù)接收與數(shù)據(jù)發(fā)送
stm32 L476 SPI讀取nandflash數(shù)據(jù)通過USB CDC發(fā)送進(jìn)到USB發(fā)送忙狀態(tài)
GPRS發(fā)送數(shù)據(jù)重新嚴(yán)重丟失現(xiàn)象
GPRS數(shù)據(jù)發(fā)送出現(xiàn)丟包現(xiàn)象
SIM900A的GPRS數(shù)據(jù)發(fā)送出現(xiàn)沒有send ok現(xiàn)象
can總線通信出現(xiàn)奇怪現(xiàn)象
請(qǐng)問為什么PDMA發(fā)送的數(shù)據(jù)被替換的現(xiàn)象會(huì)發(fā)生?
TMS320C6748:USB CPPI DMA發(fā)送多組數(shù)據(jù)緩存長(zhǎng)度為4M的數(shù)據(jù),發(fā)送第2組數(shù)據(jù)時(shí)會(huì)出現(xiàn)死機(jī)的現(xiàn)象?。。?!
TMS320C6748:硬件USB 開啟CPPI DMA,多次發(fā)送長(zhǎng)度為4M的數(shù)據(jù)緩存,出現(xiàn)死機(jī)的現(xiàn)象?。。。。?!
CH582發(fā)送數(shù)據(jù)量大時(shí),出現(xiàn)丟包現(xiàn)象的原因是什么?
為什么用DMA發(fā)送串口數(shù)據(jù)時(shí)會(huì)出現(xiàn)數(shù)據(jù)覆蓋的現(xiàn)象呢?
電站的出力特性和響應(yīng)遲滯“拖尾現(xiàn)象”產(chǎn)生的原因

評(píng)論