7. USBメモリ(初級編)
目標
- USBメモリにファイルを作成することができるようになる
- 作成したファイルに文字を書きこむことができるようになる
CubeMXの設定
-
使用するピンを選択する
今回は
PA11をUSB_OTG_FS_DMに,PA12をUSB_OTG_FS_DPに設定する
-
USB_OTG_FSの設定
modeをHost_Onlyにする
-
USB_HOSTの有効化と設定
Middleware and Software PacksからUSB_HOSTを選択Class for FS IPをMass Storage Host Classに設定NO_SW_VBUS_DRIVE_FSにチェックを入れる
-
FATFSの有効化と設定
modeはUSB Diskを選択Set DefinesのPhysical Drive ParametersにあるMAX_SSを4096にMIN_SSを512にする
-
Clock周りの問題解決
Clock Configurationを開くとエラーメッセージが出るのでYesを選択Resolve Clock issuesを実行
期待される動作
USBメモリを挿した後しばらくしてからLEDが点灯する. LED点灯後にUSBメモリを取り外してUSBメモリの中身を確認する. USBメモリに書き込みたい内容の文章が書き込まれていたら成功.
マイコンとUSB端子の接続
- USBのメス端子の
D+にマイコンのUSB_OTG_FS_DPをD-にUSB_OTG_FS_DMを接続 - USBのメス端子のVbusには5Vを供給
プログラミング
今回はwrapper.hppやwrapper.cppは作らない.
USBメモリの初回接続時にはUSB_Init()が呼び出される.
USB_Init()内で呼び出されるUSBH_UserProcess()内に処理を書くことでユーザー定義の処理を行うことができる.
FATFSについての解説
FATFSとはファイルシステムを扱う際にハードウェアとソフトウェアの間でいい感じにしてくれるミドルウェアであり,USBメモリやSDカードを扱うことが可能である.
FATFSについての詳細やここで紹介しきれない関数群についてはこちらをご覧ください.
FATFSの公式ドキュメントには日本語版アプリケーションノートや日本語版関数まとめもあるが英語版に比べて情報がやや古く,関数の引数が異なるなど重大な問題を抱えている.
f_mount(FATFS* fs, const TCHAR* path, BYTE opt)
FATFSでは1つのドライブに対して1つのワークエリアを必要とするため,この関数を用いてワークスペースの登録,削除を行う.
第3引数ではオプションを指定できるがおそらく基本0で良いと思われる.詳しくはこちらをご覧ください.
f_open(FIL* fp, const TCHAR* path, BYTE mode)
C言語のf_open()とほとんど同じ.
第3引数のモードの指定はC言語と若干異なるのでこちらの表を参照
f_write(FIL* fp, const void* buff, UINT btw, UINT* bw)
C言語のf_write()とほとんど同じ.
第3引数で書きこむデータのサイズを渡す.
第4引数で書き込んだ文字数を記録するための関数のポインタを渡す.
f_close(FIL* fp)
C言語のf_close()とほとんど同じ.
この関数が実行されるまではフラッシュメモリのファイルに書き込むデータ類はキャッシュにあり,この関数が実行されることでフラッシュメモリに実際にデータが書き込まれる.
この関数を実行した後に同じファイルへ操作を行う際には再びf_open()を呼び出す必要がある.
なお、次に紹介するf_sync()を用いればその限りではない.
f_sync(FIL* fp)
上で紹介したf_close()のうちフラッシュメモリへのデータの書き込みのみを抽出した関数.
これを用いることでフラッシュメモリにデータを書き込みつつf_open()を用いずに同じファイルへの操作を継続できる.
サンプルコード
include
usb_host.cの28行目でfatfs.hをインクルードする
/* USER CODE BEGIN Includes */
# include "fatfs.h"
/* USER CODE END Includes */
USBH_UserProcess
USBH_UserProcessはUSb_Host/App/usb_host.cの116行目にある.
fatfs.hによって導入される関数の引数(FATFS型の構造体やFIL型の構造体など)はfatfs.hで定義されている
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
break;
case HOST_USER_DISCONNECTION:
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
Appli_state = APPLICATION_READY;
f_mount(&USBHFatFS, (TCHAR *)USBHPath, 0);
f_open(&USBHFile, "test.txt", FA_CREATE_ALWAYS | FA_WRITE);
char text[]="You succeeded in writing text on USB-Memory\n";
f_write(&USBHFile, text, sizeof(text), (void *)&byteswritten);
f_close(&USBHFile);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin,GPIO_PIN_SET);
break;
case HOST_USER_CONNECTION:
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}