再開一貼,USB卡死找到原因,求解決思路

原帖:

http://www.findthetime.net/bbs/thread-113014-1.html


微軟的RNDIS USB虛擬網(wǎng)卡協(xié)議和微軟一樣臃腫,用到4個端點,恨不得把device累死,nnd

1:SETUP 端點0? OUT 0x21 00 00 00 00 00 xx xx 發(fā)送數(shù)據(jù)到device,device通過SETUP 0xA1 01 ..... 返回到host

windows每隔 3秒 就會poll一次,交換一次數(shù)據(jù),保持網(wǎng)絡連接,就是這個3秒的保持連接造成的USB卡死,但真正原因是OUT3大批量數(shù)據(jù)占的時間過長,SETUP無法響應造成的


2:IN1中斷傳輸,一有變化就需要發(fā)1次8byte消息,既然用到中斷上傳消息,為什么還用SETUP 發(fā)消息保持連接,多此一舉,nnd,微軟家有錢,就這樣豪橫,左手一個洛基亞,右手一個摩托羅拉,愛怎么玩就怎么玩


3:IN2 bulk傳輸,device網(wǎng)數(shù)據(jù)加RNDIS頭 批量上傳到windows

4:OUT3 bulk傳輸,host網(wǎng)絡數(shù)據(jù)加RNDIS頭 批量下發(fā)到device


這樣一套組合拳下來,device的OUT3最忙,頻繁中斷,有可能沒有退出中斷,Windows下發(fā)SETUP OUT 0x21 00 ...,得不到響應,造成USB卡死

以上原因只是猜測,因為測試過,如果OUT3只是copy數(shù)據(jù),出錯的機會大大減小,如果多加幾行判斷代碼,出錯機會增加。數(shù)據(jù)量小,基本不會出錯,比如ping,ping幾小時都正常


CH579的RB_UC_INT_BUSY初始化已加入,在中斷期間中斷標志未清除前自動返回NAK,搞不懂SETUP 0x21會暫停幾秒鐘,再怎么樣OUT3中斷里面也達不到秒級別,OUT3中斷里面最多26ms,一般1.2ms左右


幫忙分析分析原因

有什么思路可以解決OUT3怎樣和SETUP OUT沖突問題


?

您好,提供代碼邏輯的修改建議。

根據(jù)http://www.findthetime.net/bbs/thread-113014-1.html中提供的代碼。

image.png

①如圖修改點1,是針對控制傳輸?shù)男薷摹?/p>

進了中斷服務函數(shù)的端點0的OUTcase下,一般是表示主機在控制傳輸?shù)臄?shù)據(jù)階段下發(fā)的數(shù)據(jù),579成功收到了,接下來579根據(jù)情況判斷是否需要在狀態(tài)階段中返回0長度包。

以主機下發(fā)指令為例:

控制傳輸?shù)臓顟B(tài)階段,579回復0長度的包,表示控制傳輸?shù)臄?shù)據(jù)階段,USB主機下發(fā)的數(shù)據(jù),579可以識別處理,是代碼可以正常運行的情況。

如果說控制傳輸?shù)臄?shù)據(jù)階段,USB主機下發(fā)的指令數(shù)據(jù),579識別不了或者找不到對應的處理代碼,需要直接返回STALL包,而非回復0長度數(shù)據(jù)包。

②如圖修改點2,針對批量傳輸數(shù)據(jù)量大的情況,可以做如下代碼邏輯修改。

Ⅰ.快進快出中斷服務函數(shù),Ⅱ.創(chuàng)建軟件隊列,令牌包信息和待處理數(shù)據(jù)排列進隊列,在主函數(shù)中處理數(shù)據(jù)。

在USB傳輸完成中斷中,僅做memcpy和關鍵變量的拷貝,數(shù)據(jù)處理的代碼不要放在中斷服務函數(shù)中執(zhí)行,快進快出,具體處理放在主函數(shù)中執(zhí)行。主函數(shù)中用隊列的方式,依次處理緩存隊列,這樣能避免中斷服務函數(shù)的長時間占用。

您可以發(fā)送郵件到zhaiyw@wch.cn,給您提供CH571的做了隊列處理的例程。


最終發(fā)現(xiàn)是IN無法上傳造成的問題,不是OUT3頻繁下發(fā)造成的

我最終沒有用隊列,基本解決了,還不完美, 不完美得地方:1小時內,偶爾會SUSPEND,但usb會立刻恢復正常,時間是ms級。不再堵塞

打算換ECM協(xié)議重新來過,放棄惡心的RNDIS


解決方法:

我后來仔細想了一下,即使OUT3超出1ms處理時間,但是USB核會自動NAK,host會暫停下發(fā)數(shù)據(jù),按道理不應該OUT0會出問題,于是我打開了SOF,然后把串口打印調到1Mbps,呵呵,速度咱們得跟上? :)

在SOF里面打印一些消息,R8_USB_INT_ST=2A,R8_USB_INT_FG=12 頻繁出現(xiàn),01是SOF,2是端點2,端點2是IN Bulk,但很明顯我的端點2使用很少,百思不得其解,為什么端點2會這么頻繁,只要一卡死,SOF出現(xiàn)10,端點0出現(xiàn),因此判斷是端點2堵塞的,可是我怎么關IN2,都關不掉端點IN2,SOF里面一直頻繁出現(xiàn),萬般無奈只能main loop面和進入OUT3立馬關閉端點2IN, 端點2 OUT沒有用到,順帶也關閉它 ,于是滿世界就是下面這行代碼:

R8_UEP2_CTRL?=?UEP_R_RES_NAK?|?UEP_T_RES_NAK

但SOF里面還是頻繁出現(xiàn)12,讓我百思不得其解, 除了OUT3上傳0包,然后ARP,ping,udp回復host,我其他地方并沒有類似下面ACK的代碼

R8_UEP2_CTRL?=?UEP_R_RES_NAK?|?UEP_T_RES_ACK

即使上傳后,在IN2中斷里面也會關閉(見下),而且很少有數(shù)據(jù)IN2到host, 按道理SOF里面不太可能頻繁出現(xiàn)12. 但事實就是這樣, 知道原因了, 就是想辦法規(guī)避IN2.? 只要上傳的地方就關閉IN2,只要SETUP關閉IN2,? "大面積"關閉IN2. 就這樣好了.

不要問我為什么, 我也不知道, 也許天知道, 要說就是帶bug的可以正常跑起來的程序...


初始化:
R8_UEP2_CTRL?=?UEP_R_RES_NAK?|?UEP_T_RES_NAK?|?RB_UEP_AUTO_TOG;	//NAK


中斷:
//-----------------IN2?數(shù)據(jù)上傳----------------------------------------
case?UIS_TOKEN_IN?|?2:	//端點2?In?/?RNDIS?64byte?USB->PC
????R8_UEP2_T_LEN?=?0;	
????R8_UEP2_CTRL?=?(R8_UEP2_CTRL?&?~MASK_UEP_T_RES)?|?UEP_T_RES_NAK;	//默認應答NAK			
????usb_in_busy?=?0;	//清除發(fā)送忙標志
break;
//--------------------end?IN2-------------------------------------------





只有登錄才能回復,可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频