11.RT-thread項目實戰--usb_device 模擬讀卡器

一.前言

在上節我們實現了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卡能夠正常被電腦識別了,類似讀卡器的功能就實現了。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章