一.前言
在上節我們實現了FTP網絡傳輸功能,實現了通過網絡對設備的文件進行讀寫的功能,但是我們要是沒網呢,想要導出數據文件怎麼辦??
首先想到了USB,這次我們通過usb的otg接口,實現一個模擬讀卡器的功能,將設備插入到電腦後,將我們的sdcard作爲一個U盤,我們就可以直接通過電腦進行拷貝了。
此次我們選用了usb-device模式,usb提供的複合設備類型,可以讓給usb添加虛擬串口及讀卡器的功能,這裏只說讀卡器功能。
目前rt-thread的usb組件通過此次的添加,發現還是有一些不穩定的,不過目前實現的功能還是沒有太大問題。
事先說明:此次添加組件,遇到了很多問題,下面會進行記錄和解決方法的說明。
二.usb組件添加
1.添加usb_device
2.
上面的幾個框內容要格外注意:ID,大容量存儲設備 MSC類磁盤名。
注:
如果配置出錯,電腦識別不出來usb,同時注意MSC磁盤名要和自己的對應上。
上面這些報錯,都是配置有問題出現的。
我的用的是sdcard,選用sd0(需要看自己代碼中的定義),自己通過指令查看一下:
如果選擇錯誤,會報錯:no data->disk named sd0(測試時一直都在插着stm32的USB到電腦,導致燒寫完程序後運行時未正常打開USB,要燒寫完成正常運行的時候再把USB插入電腦。還有一點注意的問題,在menuconfig中usb啓用時設備名默認是“flash0”,我的是“sd0”,把這裏修改爲“sd0”,否則提示找不到硬盤設備。)
3.注意還要打開虛擬文件系統,這裏我們之前已經打開過了。(這個是基於之前的文件系統歷程做的)
4.打開stm32h7xx_hal_conf.h
我們是從機,檢查下PCD的是否使能了。作爲主機的時候檢查HCD。
5.
我們做完了上面的幾個步驟可以先下載試一下,發現還是會報錯,提示
disk open error
通過定位發現是mstorage.c文件下rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK出現了報錯,難道是我們的SD卡有問題?
但是我們sd卡是正常的:(確保sd卡可以識別,我之前就是用的特製的sd卡導致異常)
usb設備也註冊上了:
那麼是什麼原因呢??
打開設備失敗?難道是不能二次打開設備??通過在論壇查找答案,確實找到了幾個回答.
https://club.rt-thread.org/ask/question/5651.html
https://club.rt-thread.org/ask/question/428813.html
https://club.rt-thread.org/ask/question/12310.html
這個帖子主要說了模擬U盤和文件系統不能共存的問題,也確實有人回答了block只能被打開一次
其實現在問題已經明確了,上電之後,我們的SD卡已經掛接到文件系統上,供設備使用,這時候usb插入,再次打開出現了報錯。
那麼問題知道了,解決方法也就好說了;
主要有兩種方案;
方案1:當usb插入後,先將sd卡unmount掉,再打開就沒有問題了。
void my_sdcard_unmount(void)
{
_sdcard_unmount();
}
void my_sdcard_mount(void)
{
_sdcard_mount();
}
usb插入後會觸發到這個函數。mstorage.c
static rt_err_t _function_enable(ufunction_t func)
my_sdcard_unmount();//放在開始位置
拔掉後使用哪個函數呢?需要將sdcard掛接回去。
但是發現這個程序能夠正常識別插入,但是拔出識別不是很穩定,有時能夠觸發,有時觸發不了。
static rt_err_t _function_disable(ufunction_t func)
my_sdcard_mount();//函數最後
注:這個方法測試是可以的,但是usb插入能夠檢測到,拔出檢測不到,有網友利用ADC檢測電壓進行插拔檢測
測試:插入usb後會打印如下信息
方案2:usb mstorage.c 的_function_enable函數那裏在open前先做判斷,如果已經open了,則不需要再open了:
if ((data->disk->flag & RT_DEVICE_FLAG_STANDALONE) &&(!(data->disk->open_flag & RT_DEVICE_OFLAG_OPEN)))
{
if(rt_device_open(data->disk, RT_DEVICE_OFLAG_RDWR) != RT_EOK)
{
rt_kprintf("disk open error\n");
return -RT_ERROR;
}
}
一個簡單的判斷,就實現了模擬U盤和文件系統的共存,但是這種方法要考慮互斥問題,測試的時候也發現,修改一方文件,另一方不重啓是刷新不了的,不過好在我們只複製不修改問題,之後再進行優化。
6.此時sd卡能夠正常被電腦識別了,類似讀卡器的功能就實現了。