久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 20830|回復: 1
打印 上一主題 下一主題
收起左側

STM32 OTG 模塊做U盤主機的兼容性問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:98618 發表于 2015-12-8 03:52 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
作者:milershao
剛好幾天前有個客戶STM32F105的OTG模塊操作U盤,發現個別U盤電腦能正常使用,而STM32F105OTG模塊無法識別。ST官方相關FAE有做相關應用筆記,借花獻佛并致謝,轉過來與大家分享之。

問題回顧:

有客戶使用 STM32F2的 OTG 庫中的 U 盤主機例程在連接U盤時,有些 U 盤不能識別,甚至出現操作死機的情況,F就針對版本ST官方提供的 V2.1.0 的 USB 主機庫中的 MSC Host 例程做一些修改,以能夠兼容更U 盤。


問題調研:

1、有些 U 盤在收到 BOT_RESET 這個 MSC 類相關命令時,就不再有反應了:設備一直對后續主機發來的 IN 令牌回復 NAK 通過對 BOT_RESET 命令的調查得知,USB 規范為大容量設備定義了兩種類型的復位:USB 端口復位和大容量設備BOT 復位。

然而USB 規范并未規定這兩種復位對應到 SCSI 命令中是做什么操作。通常設備把 USB端口復位映射成 SCSI 的硬復位;有些設備把 BOT復位映射到設備的 hard reset,有的僅是映射成邏輯單元復位。該條命令通常用于主機對在 BOT 通信中出錯的設備進行復位恢復。但是需要指出的是,有些 U 盤并沒有完全遵守大容量規范,比如不實現對 BOT_RESET 命令的支持。在這種情況下,設備一般會回復 STALL,那么主機需要發送 Set Port Feature(PORT_RESET)來復位設備所連的 Hub 端口。但是這個 U 盤并沒有回復 STALL,且 U 盤是直接連在 STM32 USB 主機上的,并沒有接 Hub。于是,參照該 U 盤在 Window 下的連接操作的過程文件(tracer file),發現在 枚舉完成后,Windows 并沒有發送 BOT_RESET 命令,而是直接就發送 GET_Max_Lun 命令來獲取 U 盤的邏輯盤符個數。

于是在STM32 的 USB Host 例程中注釋掉 BOT_RESET 命令,果然可以正確操作了。修改代碼如下:

USBH_MSC_Handle()

{......

{ switch(USBH_MSC_BOTXferParam.MSCState)

{ case USBH_MSC_BOT_INIT_STATE:

USBH_MSC_Init(pdev);

//USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;

break;

case…

2、還有些 U 盤在收到 Get_Max_Lun 命令返回 STALL,但是 U 抓到的 tracer 文件如圖 盤主機就走不下去了。


經查閱,有些只包含一個邏輯盤符的 U 盤可以對該命令回復數值 0 或者直接回復 STALL。 那么對于 USB 主機來說,在收到了該條命令的 STALL 回復后就應該第一:認為該 U 盤僅包含 一個邏輯盤符;第二:對 STALL 應答進行處理,然后繼續下面的命令流程。

通過 USB2.0 協議規范(章節 9.2.7),我們得知在控制傳輸(Control Transfer)過程中,當設備收到的命令自己不支持或者不適合設備當前的設置,就認為是命令出錯。那么設備通過在接 下來的數據階段或者狀態階段回復 STALL 應答來告知主機這個錯誤。這種“協議 STALL”是 控制傳輸特有的;這樣 STALL 的狀態,會在下一個控制傳輸(Setup 令牌)的到來而解除。

我們看看 Windows 對 U 盤這樣的回復是怎么處理,tracer 文件抓圖如下:主機通過 Clear Feature 命令,參數 EP_Halt(這是一個控制傳輸)來把設備方端點的 Halt feature 清除掉。


從代碼里可以看到,例程是有做這方面的處理的:

如果主機發送的 Get_Max_Lun 命令不被設 備支持,則將 MSCState 狀態設定成 CTRL_ERROR_STATE,發送Clear Feature 的命令,以及隨后 的 Test_Unit_Ready 命令。

USBH_MSC_Handle()

......

{ switch(USBH_MSC_BOTXferParam.MSCState)

{ case USBH_MSC_GET_MAX_LUN:

/* Issue GetMaxLUN request */

status = USBH_MSC_GETMaxLUN(pdev, phost);

if(status == USBH_OK )

{

MSC_Machine.maxLun = *(MSC_Machine.buff) ;

/* If device has more that one logical unit then it is not supported */

if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))

{

maxLunExceed = TRUE;

pphost->usr_cb->DeviceNotSupported();

break;

}

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY;

}

if(status == USBH_NOT_SUPPORTED )

{

/* If the Command has failed, then we need to move to Next State, after

STALL condition is cleared by Control-Transfer */

USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;

/* a Clear Feature should be issued here */

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;

}

break;

……

但是從抓到的 tracer 文件卻看不到主機走到了發送 Test_Unit_Ready 的命令。經過調試、代碼跟蹤,終于定位在 USBH_HandleControl()中。對 CTRL_DATA_IN_WAIT 的處理,當收到 URB_STALL 的應答后,沒有給 phost 的 Control.state 賦值成 CTRL_STALLED!



USBH_HandleControl( )

{

......

switch (phost->Control.state)

{

case CTRL_DATA_IN_WAIT:

URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);

/* check is DATA packet transfered successfully */

if (URB_Status == URB_DONE)

{

phost->Control.state = CTRL_STATUS_OUT;

}

/* manage error cases*/

if (URB_Status == URB_STALL)

{

/* In stall case, return to previous machine state*/

phost->gState = phost->gStateBkp;

phost->Control.state = CTRL_STALLED; //

}

else if ......


3、還有一點需要注意的是:本版的 U 盤主機例程,暫時不支持多盤符 U 盤。 剛好幾天前有個客戶STM32F105的OTG模塊操作U盤,發現個別U盤電腦能正常使用,而STM32F105OTG模塊無法識別。ST官方相關FAE有做相關應用筆記,借花獻佛并致謝,轉過來與大家分享之。

問題回顧:

有客戶使用 STM32F2的 OTG 庫中的 U 盤主機例程在連接U盤時,有些 U 盤不能識別,甚至出現操作死機的情況。現就針對版本ST官方提供的 V2.1.0 的 USB 主機庫中的 MSC Host 例程做一些修改,以能夠兼容更U 盤。


問題調研:

1、有些 U 盤在收到 BOT_RESET 這個 MSC 類相關命令時,就不再有反應了:設備一直對后續主機發來的 IN 令牌回復 NAK 。通過對 BOT_RESET 命令的調查得知,USB 規范為大容量設備定義了兩種類型的復位:USB 端口復位和大容量設備BOT 復位。

然而USB 規范并未規定這兩種復位對應到 SCSI 命令中是做什么操作。通常設備把 USB端口復位映射成 SCSI 的硬復位;有些設備把 BOT復位映射到設備的 hard reset,有的僅是映射成邏輯單元復位。該條命令通常用于主機對在 BOT 通信中出錯的設備進行復位恢復。但是需要指出的是,有些 U 盤并沒有完全遵守大容量規范,比如不實現對 BOT_RESET 命令的支持。在這種情況下,設備一般會回復 STALL,那么主機需要發送 Set Port Feature(PORT_RESET)來復位設備所連的 Hub 端口。但是這個 U 盤并沒有回復 STALL,且 U 盤是直接連在 STM32 USB 主機上的,并沒有接 Hub。于是,參照該 U 盤在 Window 下的連接操作的過程文件(tracer file),發現在 枚舉完成后,Windows 并沒有發送 BOT_RESET 命令,而是直接就發送 GET_Max_Lun 命令來獲取 U 盤的邏輯盤符個數。

于是在STM32 的 USB Host 例程中注釋掉 BOT_RESET 命令,果然可以正確操作了。修改代碼如下:

USBH_MSC_Handle()

{......

{ switch(USBH_MSC_BOTXferParam.MSCState)

{ case USBH_MSC_BOT_INIT_STATE:

USBH_MSC_Init(pdev);

//USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOT_RESET;

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_GET_MAX_LUN;

break;

case…

2、還有些 U 盤在收到 Get_Max_Lun 命令返回 STALL,但是 U 抓到的 tracer 文件如圖 盤主機就走不下去了。


經查閱,有些只包含一個邏輯盤符的 U 盤可以對該命令回復數值 0 或者直接回復 STALL。 那么對于 USB 主機來說,在收到了該條命令的 STALL 回復后就應該第一:認為該 U 盤僅包含 一個邏輯盤符;第二:對 STALL 應答進行處理,然后繼續下面的命令流程。

通過 USB2.0 協議規范(章節 9.2.7),我們得知在控制傳輸(Control Transfer)過程中,當設備收到的命令自己不支持或者不適合設備當前的設置,就認為是命令出錯。那么設備通過在接 下來的數據階段或者狀態階段回復 STALL 應答來告知主機這個錯誤。這種“協議 STALL”是 控制傳輸特有的;這樣 STALL 的狀態,會在下一個控制傳輸(Setup 令牌)的到來而解除。

我們看看 Windows 對 U 盤這樣的回復是怎么處理,tracer 文件抓圖如下:主機通過 Clear Feature 命令,參數 EP_Halt(這是一個控制傳輸)來把設備方端點的 Halt feature 清除掉。


從代碼里可以看到,例程是有做這方面的處理的:

如果主機發送的 Get_Max_Lun 命令不被設 備支持,則將 MSCState 狀態設定成 CTRL_ERROR_STATE,發送Clear Feature 的命令,以及隨后 的 Test_Unit_Ready 命令。

USBH_MSC_Handle()

......

{ switch(USBH_MSC_BOTXferParam.MSCState)

{ case USBH_MSC_GET_MAX_LUN:

/* Issue GetMaxLUN request */

status = USBH_MSC_GETMaxLUN(pdev, phost);

if(status == USBH_OK )

{

MSC_Machine.maxLun = *(MSC_Machine.buff) ;

/* If device has more that one logical unit then it is not supported */

if((MSC_Machine.maxLun > 0) && (maxLunExceed == FALSE))

{

maxLunExceed = TRUE;

pphost->usr_cb->DeviceNotSupported();

break;

}

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_TEST_UNIT_READY;

}

if(status == USBH_NOT_SUPPORTED )

{

/* If the Command has failed, then we need to move to Next State, after

STALL condition is cleared by Control-Transfer */

USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_TEST_UNIT_READY;

/* a Clear Feature should be issued here */

USBH_MSC_BOTXferParam.MSCState = USBH_MSC_CTRL_ERROR_STATE;

}

break;

……

但是從抓到的 tracer 文件卻看不到主機走到了發送 Test_Unit_Ready 的命令。經過調試、代碼跟蹤,終于定位在 USBH_HandleControl()中。對 CTRL_DATA_IN_WAIT 的處理,當收到 URB_STALL 的應答后,沒有給 phost 的 Control.state 賦值成 CTRL_STALLED!



USBH_HandleControl( )

{

......

switch (phost->Control.state)

{

case CTRL_DATA_IN_WAIT:

URB_Status = HCD_GetURB_State(pdev , phost->Control.hc_num_in);

/* check is DATA packet transfered successfully */

if (URB_Status == URB_DONE)

{

phost->Control.state = CTRL_STATUS_OUT;

}

/* manage error cases*/

if (URB_Status == URB_STALL)

{

/* In stall case, return to previous machine state*/

phost->gState = phost->gStateBkp;

phost->Control.state = CTRL_STALLED; //

}

else if ......


3、還有一點需要注意的是:本版的 U 盤主機例程,暫時不支持多盤符 U 盤。

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:230640 發表于 2017-9-3 07:18 | 只看該作者
你好,我遇到類似問題,想請教一下,我的QQ是20767248,方便的時候聯系一下吧,謝謝
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美日韩18 | 在线免费观看黄网 | www.黄色在线观看 | 蜜桃视频一区二区三区 | av在线免费观看网站 | 91免费在线看 | 精品亚洲一区二区 | 国产一区二区三区在线免费观看 | 欧美一级二级视频 | 偷派自拍 | 久草精品视频 | 日本精品视频一区二区三区四区 | 欧美日韩综合视频 | 男女羞羞视频在线免费观看 | 成人av电影免费在线观看 | 久久高清 | 国产极品粉嫩美女呻吟在线看人 | 亚洲精品在 | 99精品国产一区二区三区 | 鲁一鲁资源影视 | 精品视频一区二区三区在线观看 | 99精品网| 国产成人精品高清久久 | 天天躁日日躁狠狠很躁 | 欧美精品久久 | 中文字幕日韩欧美一区二区三区 | 夜夜操天天操 | 久久久久久久久久久一区二区 | 永久av| 精品视频一区二区三区 | 成人免费一级 | 美国一级黄色片 | 精品综合久久久 | 黄色片在线免费看 | 成人在线免费看 | 欧美激情一区二区三区 | 欧美精品福利 | 午夜免费视频 | 99精品视频免费在线观看 | 狠狠av | 欧美一区二区三区大片 |