[转]使用STM32CubeMX:USB大容量存储设备
原文地址http://qiita.com/mt08/items/fcc925fa47726bfc6c74
概要
- STM32CubeMXを使って、USB MassStorageを使ってみる。
- USBを使うときは、外付けのOscillator/Xtalが必要。(48MHzを作るのに、内部のやつは精度がでない?)
usbd_storage_if.c
だけ変更. 今回は、ReadOnly.
環境
- STM32L1系
- ビルド環境
- Windows7 64bit
- MDK-ARM Lite v5.20
- STM32CubeMX v4.18.0
- ボードが動くくらいの設定(クロックとか、GPIOとか)
- FreeRTOS : [v] Enabled (Lチカにつかった程度)
- USB_DEVICE : Class for FS IP
Mass Storage Class
- USB : [v] Device (FS)
=> コード生成
- Firmware Package for Family STM32L1 v1.6.0
大体の説明
コールバック
ホストに接続すると、コールバックが呼ばれるので、うまく応答すればよい。usbd_storage_if.c- ...
- USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
- {
- STORAGE_Init_FS,
- STORAGE_GetCapacity_FS,
- STORAGE_IsReady_FS,
- STORAGE_IsWriteProtected_FS,
- STORAGE_Read_FS,
- STORAGE_Write_FS,
- STORAGE_GetMaxLun_FS,
- (int8_t *)STORAGE_Inquirydata_FS,
- };
- ...
- ...
ディスクの容量は、
STORAGE_BLK_NBR
にセクタ数定義する。
今回、#define STORAGE_BLK_NBR 0x81000
としたので、
=> 0x81000 * 512bytes/sector = 258MBくらいのディスクコールバックは、だいたい、
STORAGE_Read_FS
で、セクタのデータを要求してくるので、そいつをかえせばいい。- ↓の実装では、
_ReadSector()
に飛ばしている。 _ReadSector()
で、要求されたセクタ番号で、MBR, PBR, FAT, ROOT_DIR, DATAの領域で、処理を分けている。- MBR,PBRは、固定値を用意して、memcpy
- FAT, ROOTDIR, DATAは、Offsetを引いて、処理関数(
handleFatClusterChain
,handleRoot
,handleData
)へ飛ばして、うまくデータを詰める
- ↓の実装では、
実際のコード
もともとのコードの変更箇所
usbd_storage_if.c- ...
- #define STORAGE_LUN_NBR 1
- #define STORAGE_BLK_NBR 0x81000 //##mt08
- #define STORAGE_BLK_SIZ
- ...
- int8_t STORAGE_IsWriteProtected_FS (uint8_t lun)
- {
- /* USER CODE BEGIN 5 */
- return (USBD_FAIL); //##mt08: Read Only
- /* USER CODE END 5 */
- }
- ...
- int8_t STORAGE_Read_FS (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len)
- {
- /* USER CODE BEGIN 6 */
- _ReadSector(buf, blk_addr, blk_len); //##mt08
- return (USBD_OK);
- /* USER CODE END 6 */
- }
- ...
追加コード
型宣言
- #include <stdint.h>
- typedef uint8_t Byte;
- typedef struct MasterBootRecord {
- Byte checkRoutionOnx86[446];
- struct {
- Byte bootDescriptor; /* 0x80: bootable device, 0x00: non-bootable */
- Byte firstPartitionSector[3]; /* 1st sector number */
- Byte fileSystemDescriptor; /* 1:FAT12, 4:FAT16(less than 32MB), 5:Extended-DOS Partition,
- 6:FAT16(more 32MB), 0xb:FAT32(more 2GB),
- 0xc:FAT32 Int32h, 0xe:FAT16 Int32h,
- 0xf:5:Extended-DOS Partition Int32h */
- Byte lastPartitionSector[3];
- Byte firstSectorNumbers[4]; /* first sector number (link to BPB sector) */
- Byte numberOfSectors[4];
- } partitionTable[4];
- Byte sig[2]; /* 0x55, 0xaa */
- } MBRecord;
- typedef struct FAT16BPB_t {
- /* FAT16 or FAT12 BPB */
- Byte jmpOpeCode[3]; /* 0xeb ?? 0x90 */
- Byte OEMName[8];
- /* FAT16 */
- Byte bytesPerSector[2]; /* bytes/sector */
- Byte sectorsPerCluster; /* sectors/cluster */
- Byte reservedSectors[2]; /* reserved sector, beginning with sector 0 */
- Byte numberOfFATs; /* file allocation table */
- Byte rootEntries[2]; /* root entry (512) */
- Byte totalSectors[2]; /* partion total secter */
- Byte mediaDescriptor; /* 0xf8: Hard Disk */
- Byte sectorsPerFAT[2]; /* sector/FAT (FAT32 always zero: see bigSectorsPerFAT) */
- Byte sectorsPerTrack[2]; /* sector/track (not use) */
- Byte heads[2]; /* heads number (not use) */
- Byte hiddenSectors[4]; /* hidden sector number */
- Byte bigTotalSectors[4]; /* total sector number */
- /* info */
- Byte driveNumber;
- Byte unused;
- Byte extBootSignature;
- Byte serialNumber[4];
- Byte volumeLabel[11];
- Byte fileSystemType[8]; /* "FAT16 " */
- Byte loadProgramCode[448];
- Byte sig[2]; /* 0x55, 0xaa */
- } BPBlock; // BIOS Parameter Block
- typedef struct DirEntry_t {
- Byte name[8]; /* file name */
- Byte extension[3]; /* file name extension */
- Byte attribute; /* file attribute
- bit 4 directory flag
- bit 3 volume flag
- bit 2 hidden flag
- bit 1 system flag
- bit 0 read only flag */
- Byte reserved; /* use NT or same OS */
- Byte createTimeMs; /* VFAT 10millsec (0 199) */
- Byte createTime[2]; /* VFAT */
- Byte createDate[2]; /* VFAT */
- Byte accessDate[2]; /* VFAT */
- Byte clusterHighWord[2]; /* FAT32 MSB 16 bits */
- Byte updateTime[2];
- Byte updateDate[2];
- Byte cluster[2]; /* start cluster number */
- Byte fileSize[4]; /* file size in bytes (directory is always zero) */
- } DirEntry;
- #pragma anon_unions
- typedef struct _DirEntTime {
- union {
- uint16_t W;
- struct {
- uint16_t second : 5;
- uint16_t minutes : 6;
- uint16_t hour : 5;
- } B;
- };
- } DirEntTime;
- typedef struct _DirEntDate {
- union {
- uint16_t W;
- struct {
- uint16_t day : 5;
- uint16_t month : 4;
- uint16_t year : 7;
- } B;
- };
- } DirEntDate;
- #pragma no_anon_unions
- #include <stdint.h>
固定値: MBRとか、PBSとか。
(てきとうなUSBフラッシュメモリで、パーティション切って、フォーマットして、ダンプして、必要なとこを入力)- const MBRecord sectMBR = {
- .checkRoutionOnx86 = { 0x00 },
- .partitionTable = {
- {
- .bootDescriptor = 0x00,
- .firstPartitionSector = { 0x02, 0x21, 0x00 },
- .fileSystemDescriptor = 0x06, //FAT16
- .lastPartitionSector = { 0xC2, 0x22, 0x20 },
- .firstSectorNumbers = { 0x00, 0x08, 0x00, 0x00 },
- .numberOfSectors = { 0x00, 0x00, 0x08, 0x00 },
- },//[0]
- { 0 },//[1]
- { 0 },//[2]
- { 0 },//[3]
- },
- .sig = { 0x55, 0xAA },
- };
- const BPBlock sectBPB = {
- .jmpOpeCode = { 0xEB, 0x00, 0x90 },
- .OEMName = { ' ',' ',' ',' ',' ',' ',' ',' ' },
- .bytesPerSector = { 0x00, 0x02 },
- .sectorsPerCluster = 0x08, // 4KB/sectors
- .reservedSectors = { 0x08, 0x00 },
- .numberOfFATs = 0x02,
- .rootEntries = { 0x00, 0x02 },
- .totalSectors = { 0x00, 0x00 },
- .mediaDescriptor = 0xF8, // HDD
- .sectorsPerFAT = { 0x00, 0x01 },
- .sectorsPerTrack = { 0x3F,0x00 },
- .heads = { 0xFF,0x00 },
- .hiddenSectors = { 0x00, 0x08, 0x00, 0x00 },
- .bigTotalSectors = { 0x00,0x00,0x08, 0x00 },
- .driveNumber = 0x80,
- .unused = 0,
- .extBootSignature = 0x29,
- .serialNumber = { 0x78,0x56,0x34,0x12 },
- .volumeLabel = { 'N','O',' ','N','A','M','E',' ',' ',' ',' ' },
- .fileSystemType = { 'F','A','T','1','6',' ',' ',' ' },
- .loadProgramCode = { 0 },
- .sig = { 0x55, 0xAA },
- };
- #define SECTOR_MBR (0x0000)
- #define SECTOR_PBR (0x0800)
- #define SECTOR_FAT1 (0x0808)
- #define SECTOR_FAT2 (0x0908)
- #define SECTOR_ROOT (0x0A08)
- #define SECTOR_DATA (0x0A28)
- const MBRecord sectMBR = {
セクタ読み出しで、それっぽいデータをわたすとこ。
- void _handleFatClusterChain(uint32_t sect_offset, uint8_t *buf)
- {
- uint16_t *bufW = (uint16_t *)&buf[0];
- if (sect_offset == 0)
- {
- bufW[0] = 0xfff8;
- bufW[1] = 0xffff;
- bufW[2] = 0xffff; //最初のファイル. 1クラスタでおわり.
- }
- }
- void _handleRoot(uint32_t sect_offset, uint8_t *buf)
- {
- // 1 sector(512bytes) has 16 entries
- DirEntry *pDir = (DirEntry *)buf;
- if (sect_offset == 0)
- {
- memset(pDir, 0x00, sizeof(DirEntry));
- sprintf((char *)pDir->name, "TEXT_123");
- pDir->extension[0] = 'T';
- pDir->extension[1] = 'X';
- pDir->extension[2] = 'T';
- pDir->attribute = 0x00;
- {
- DirEntTime *pT = (DirEntTime *)&pDir->updateTime[0];
- DirEntDate *pD = (DirEntDate *)&pDir->updateDate[0];
- pT->B.hour = 12;
- pT->B.minutes = 34;
- pT->B.second = 56 / 2;
- pD->B.year = 2017 - 1980;
- pD->B.month = 1;
- pD->B.day = 12;
- }
- *(uint16_t*)&pDir->cluster = 0x0002;
- *(uint32_t*)&pDir->fileSize = 123;
- }
- }
- void _handleData(uint32_t sect_offset, uint8_t *buf)
- {
- memset(buf, 'A', 512);
- sprintf((char *)buf, "Hello World!\r\n");
- buf[14]='>';
- }
- uint32_t _ReadSector(uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
- {
- switch (blk_addr)
- {
- case SECTOR_MBR:
- memcpy(buf, (const void *)§MBR, 512);
- break;
- case SECTOR_PBR:
- memcpy(buf, (const void *)§BPB, 512);
- break;
- default:
- memset(buf, 0x00, 512);
- //FAT cluster chain
- if ((SECTOR_FAT1 <= blk_addr) && (blk_addr < SECTOR_ROOT))
- {
- if (blk_addr >= SECTOR_FAT2) { blk_addr -= (SECTOR_FAT2 - SECTOR_FAT1); }
- _handleFatClusterChain(blk_addr - SECTOR_FAT1, buf);
- }
- else if ((SECTOR_ROOT <= blk_addr) && (blk_addr < SECTOR_DATA))
- {
- _handleRoot(blk_addr - SECTOR_ROOT, buf);
- }
- else if (SECTOR_DATA <= blk_addr)
- {
- _handleData(blk_addr - SECTOR_DATA, buf);
- }
- break;
- }
- return 0;
- }
その他
- 4KB/clusterにしてるのは、STM32の内蔵FLASHが4KB/sectorなので。
で、256MBくらいのパーティションで、FAT16フォーマットすると、4KB/clusterになる。
(ファイルシステムのクラスタサイズと、フラッシュメモリの物理セクタサイズがちがうと、管理が大変だよね...;_;
) - EEPROMにファイル情報(ROOTDIRに入るような情報=>FATチェーン生成)、FLASHにデータのみ、という感じで使用しようかと。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
好了现在我们动手吧。现在只要修改usbd_storage_if.C文件
- /**
- ******************************************************************************
- * @file : usbd_storage_if.c
- * @brief : Memory management layer
- ******************************************************************************
- * This notice applies to any and all portions of this file
- * that are not between comment pairs USER CODE BEGIN and
- * USER CODE END. Other portions of this file, whether
- * inserted by the user or by software development tools
- * are owned by their respective copyright owners.
- *
- * Copyright (c) 2017 STMicroelectronics International N.V.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted, provided that the following conditions are met:
- *
- * 1. Redistribution of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of other
- * contributors to this software may be used to endorse or promote products
- * derived from this software without specific written permission.
- * 4. This software, including modifications and/or derivative works of this
- * software, must execute solely and exclusively on microcontroller or
- * microprocessor devices manufactured by or for STMicroelectronics.
- * 5. Redistribution and use of this software other than as permitted under
- * this license is void and will automatically terminate your rights under
- * this license.
- *
- * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
- * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
- * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
- /* Includes ------------------------------------------------------------------*/
- #include "usbd_storage_if.h"
- /* USER CODE BEGIN INCLUDE */
- /* USER CODE END INCLUDE */
- /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
- * @{
- */
- /** @defgroup USBD_STORAGE
- * @brief usbd core module
- * @{
- */
- /** @defgroup USBD_STORAGE_Private_TypesDefinitions
- * @{
- */
- /* USER CODE BEGIN PRIVATE_TYPES */
- /* USER CODE END PRIVATE_TYPES */
- /**
- * @}
- */
- /** @defgroup USBD_STORAGE_Private_Defines
- * @{
- */
- #define STORAGE_LUN_NBR 1
- #define STORAGE_BLK_NBR 0x81000
- #define STORAGE_BLK_SIZ 0x200
- /* USER CODE BEGIN PRIVATE_DEFINES */
- /* USER CODE END PRIVATE_DEFINES */
- /**
- * @}
- */
- /** @defgroup USBD_STORAGE_Private_Macros
- * @{
- */
- /* USER CODE BEGIN PRIVATE_MACRO */
- /* USER CODE END PRIVATE_MACRO */
- /**
- * @}
- */
- /** @defgroup USBD_STORAGE_IF_Private_Variables
- * @{
- */
- /* USER CODE BEGIN INQUIRY_DATA_FS */
- /* USB Mass storage Standard Inquiry Data */
- const int8_t STORAGE_Inquirydata_FS[] = /* 36 */
- {
- /* LUN 0 */
- 0x00,
- 0x80,
- 0x02,
- 0x02,
- (STANDARD_INQUIRY_DATA_LEN - ),
- 0x00,
- 0x00,
- 0x00,
- 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
- 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */
- ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
- '', '.', '' ,'', /* Version : 4 Bytes */
- };
- /* USER CODE END INQUIRY_DATA_FS */
- /* USER CODE BEGIN PRIVATE_VARIABLES */
- /* USER CODE END PRIVATE_VARIABLES */
- /**
- * @}
- */
- /** @defgroup USBD_STORAGE_IF_Exported_Variables
- * @{
- */
- extern USBD_HandleTypeDef hUsbDeviceFS;
- /* USER CODE BEGIN EXPORTED_VARIABLES */
- /* USER CODE END EXPORTED_VARIABLES */
- /**
- * @}
- */
- /** @defgroup USBD_STORAGE_Private_FunctionPrototypes
- * @{
- */
- static int8_t STORAGE_Init_FS (uint8_t lun);
- static int8_t STORAGE_GetCapacity_FS (uint8_t lun,
- uint32_t *block_num,
- uint16_t *block_size);
- static int8_t STORAGE_IsReady_FS (uint8_t lun);
- static int8_t STORAGE_IsWriteProtected_FS (uint8_t lun);
- static int8_t STORAGE_Read_FS (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len);
- static int8_t STORAGE_Write_FS (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len);
- static int8_t STORAGE_GetMaxLun_FS (void);
- /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
- #include <stdint.h>
- typedef uint8_t Byte;
- typedef struct MasterBootRecord
- {
- Byte checkRoutionOnx86[];
- struct
- {
- Byte bootDescriptor; /* 0x80: bootable device, 0x00: non-bootable */
- Byte firstPartitionSector[]; /* 1st sector number */
- Byte fileSystemDescriptor; /* 1:FAT12, 4:FAT16(less than 32MB), 5:Extended-DOS Partition,
- 6:FAT16(more 32MB), 0xb:FAT32(more 2GB),
- 0xc:FAT32 Int32h, 0xe:FAT16 Int32h,
- 0xf:5:Extended-DOS Partition Int32h */
- Byte lastPartitionSector[];
- Byte firstSectorNumbers[]; /* first sector number (link to BPB sector) */
- Byte numberOfSectors[];
- } partitionTable[];
- Byte sig[]; /* 0x55, 0xaa */
- } MBRecord;
- typedef struct FAT16BPB_t
- {
- /* FAT16 or FAT12 BPB */
- Byte jmpOpeCode[]; /* 0xeb ?? 0x90 */
- Byte OEMName[];
- /* FAT16 */
- Byte bytesPerSector[]; /* bytes/sector */
- Byte sectorsPerCluster; /* sectors/cluster */
- Byte reservedSectors[]; /* reserved sector, beginning with sector 0 */
- Byte numberOfFATs; /* file allocation table */
- Byte rootEntries[]; /* root entry (512) */
- Byte totalSectors[]; /* partion total secter */
- Byte mediaDescriptor; /* 0xf8: Hard Disk */
- Byte sectorsPerFAT[]; /* sector/FAT (FAT32 always zero: see bigSectorsPerFAT) */
- Byte sectorsPerTrack[]; /* sector/track (not use) */
- Byte heads[]; /* heads number (not use) */
- Byte hiddenSectors[]; /* hidden sector number */
- Byte bigTotalSectors[]; /* total sector number */
- /* info */
- Byte driveNumber;
- Byte unused;
- Byte extBootSignature;
- Byte serialNumber[];
- Byte volumeLabel[];
- Byte fileSystemType[]; /* "FAT16 " */
- Byte loadProgramCode[];
- Byte sig[]; /* 0x55, 0xaa */
- } BPBlock; // BIOS Parameter Block
- typedef struct DirEntry_t
- {
- Byte name[]; /* file name */
- Byte extension[]; /* file name extension */
- Byte attribute; /* file attribute
- bit 4 directory flag
- bit 3 volume flag
- bit 2 hidden flag
- bit 1 system flag
- bit 0 read only flag */
- Byte reserved; /* use NT or same OS */
- Byte createTimeMs; /* VFAT 10millsec (0 199) */
- Byte createTime[]; /* VFAT */
- Byte createDate[]; /* VFAT */
- Byte accessDate[]; /* VFAT */
- Byte clusterHighWord[]; /* FAT32 MSB 16 bits */
- Byte updateTime[];
- Byte updateDate[];
- Byte cluster[]; /* start cluster number */
- Byte fileSize[]; /* file size in bytes (directory is always zero) */
- } DirEntry;
- #pragma anon_unions
- typedef struct _DirEntTime
- {
- union
- {
- uint16_t W;
- struct
- {
- uint16_t second : ;
- uint16_t minutes : ;
- uint16_t hour : ;
- } B;
- };
- } DirEntTime;
- typedef struct _DirEntDate
- {
- union
- {
- uint16_t W;
- struct
- {
- uint16_t day : ;
- uint16_t month : ;
- uint16_t year : ;
- } B;
- };
- } DirEntDate;
- #pragma no_anon_unions
- const MBRecord sectMBR =
- {
- .checkRoutionOnx86 = { 0x00 },
- .partitionTable = {
- {
- .bootDescriptor = 0x00,
- .firstPartitionSector = { 0x02, 0x21, 0x00 },
- .fileSystemDescriptor = 0x06, //FAT16
- .lastPartitionSector = { 0xC2, 0x22, 0x20 },
- .firstSectorNumbers = { 0x00, 0x08, 0x00, 0x00 },
- .numberOfSectors = { 0x00, 0x00, 0x08, 0x00 },
- },//[0]
- { },//[1]
- { },//[2]
- { },//[3]
- },
- .sig = { 0x55, 0xAA },
- };
- const BPBlock sectBPB =
- {
- .jmpOpeCode = { 0xEB, 0x00, 0x90 },
- .OEMName = { ' ',' ',' ',' ',' ',' ',' ',' ' },
- .bytesPerSector = { 0x00, 0x02 },
- .sectorsPerCluster = 0x08, // 4KB/sectors
- .reservedSectors = { 0x08, 0x00 },
- .numberOfFATs = 0x02,
- .rootEntries = { 0x00, 0x02 },
- .totalSectors = { 0x00, 0x00 },
- .mediaDescriptor = 0xF8, // HDD
- .sectorsPerFAT = { 0x00, 0x01 },
- .sectorsPerTrack = { 0x3F,0x00 },
- .heads = { 0xFF,0x00 },
- .hiddenSectors = { 0x00, 0x08, 0x00, 0x00 },
- .bigTotalSectors = { 0x00,0x00,0x08, 0x00 },
- .driveNumber = 0x80,
- .unused = ,
- .extBootSignature = 0x29,
- .serialNumber = { 0x78,0x56,0x34,0x12 },
- .volumeLabel = { 'N','O',' ','N','A','M','E',' ',' ',' ',' ' },
- .fileSystemType = { 'F','A','T','','',' ',' ',' ' },
- .loadProgramCode = { },
- .sig = { 0x55, 0xAA },
- };
- #define SECTOR_MBR (0x0000)
- #define SECTOR_PBR (0x0800)
- #define SECTOR_FAT1 (0x0808)
- #define SECTOR_FAT2 (0x0908)
- #define SECTOR_ROOT (0x0A08)
- #define SECTOR_DATA (0x0A28)
- void _handleFatClusterChain(uint32_t sect_offset, uint8_t *buf)
- {
- uint16_t *bufW = (uint16_t *)&buf[];
- if (sect_offset == )
- {
- bufW[] = 0xfff8;
- bufW[] = 0xffff;
- bufW[] = 0xffff; //结束第一个文件。1簇。
- }
- }
- void _handleRoot(uint32_t sect_offset, uint8_t *buf)
- {
- // 1 sector(512bytes) has 16 entries
- DirEntry *pDir = (DirEntry *)buf;
- if (sect_offset == )
- {
- memset(pDir, 0x00, sizeof(DirEntry));
- sprintf((char *)pDir->name, "TEXT_123");
- pDir->extension[] = 'T';
- pDir->extension[] = 'X';
- pDir->extension[] = 'T';
- pDir->attribute = 0x00;
- {
- DirEntTime *pT = (DirEntTime *)&pDir->updateTime[];
- DirEntDate *pD = (DirEntDate *)&pDir->updateDate[];
- pT->B.hour = ;
- pT->B.minutes = ;
- pT->B.second = / ;
- pD->B.year = - ;
- pD->B.month = ;
- pD->B.day = ;
- }
- *(uint16_t*)&pDir->cluster = 0x0002;
- *(uint32_t*)&pDir->fileSize = ;
- }
- }
- void _handleData(uint32_t sect_offset, uint8_t *buf)
- {
- memset(buf, 'A', );
- sprintf((char *)buf, "Hello World!\r\n");
- buf[]='>';
- }
- uint32_t _ReadSector(uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)
- {
- switch (blk_addr)
- {
- case SECTOR_MBR:
- memcpy(buf, (const void *)§MBR, );
- break;
- case SECTOR_PBR:
- memcpy(buf, (const void *)§BPB, );
- break;
- default:
- memset(buf, 0x00, );
- //FAT cluster chain
- if ((SECTOR_FAT1 <= blk_addr) && (blk_addr < SECTOR_ROOT))
- {
- if (blk_addr >= SECTOR_FAT2)
- {
- blk_addr -= (SECTOR_FAT2 - SECTOR_FAT1);
- }
- _handleFatClusterChain(blk_addr - SECTOR_FAT1, buf);
- }
- else if ((SECTOR_ROOT <= blk_addr) && (blk_addr < SECTOR_DATA))
- {
- _handleRoot(blk_addr - SECTOR_ROOT, buf);
- }
- else if (SECTOR_DATA <= blk_addr)
- {
- _handleData(blk_addr - SECTOR_DATA, buf);
- }
- break;
- }
- return ;
- }
- /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
- /**
- * @}
- */
- USBD_StorageTypeDef USBD_Storage_Interface_fops_FS =
- {
- STORAGE_Init_FS,
- STORAGE_GetCapacity_FS,
- STORAGE_IsReady_FS,
- STORAGE_IsWriteProtected_FS,
- STORAGE_Read_FS,
- STORAGE_Write_FS,
- STORAGE_GetMaxLun_FS,
- (int8_t *)STORAGE_Inquirydata_FS,
- };
- /* Private functions ---------------------------------------------------------*/
- /*******************************************************************************
- * Function Name : STORAGE_Init_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_Init_FS (uint8_t lun)
- {
- /* USER CODE BEGIN 2 */
- return (USBD_OK);
- /* USER CODE END 2 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_GetCapacity_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_GetCapacity_FS (uint8_t lun, uint32_t *block_num, uint16_t *block_size)
- {
- /* USER CODE BEGIN 3 */
- *block_num = STORAGE_BLK_NBR;
- *block_size = STORAGE_BLK_SIZ;
- return (USBD_OK);
- /* USER CODE END 3 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_IsReady_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_IsReady_FS (uint8_t lun)
- {
- /* USER CODE BEGIN 4 */
- return (USBD_OK);
- /* USER CODE END 4 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_IsWriteProtected_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_IsWriteProtected_FS (uint8_t lun)
- {
- /* USER CODE BEGIN 5 */
- return (USBD_OK);
- /* USER CODE END 5 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_Read_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_Read_FS (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len)
- {
- /* USER CODE BEGIN 6 */
- _ReadSector(buf, blk_addr, blk_len);
- return (USBD_OK);
- /* USER CODE END 6 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_Write_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_Write_FS (uint8_t lun,
- uint8_t *buf,
- uint32_t blk_addr,
- uint16_t blk_len)
- {
- /* USER CODE BEGIN 7 */
- return (USBD_OK);
- /* USER CODE END 7 */
- }
- /*******************************************************************************
- * Function Name : STORAGE_GetMaxLun_FS
- * Description :
- * Input : None.
- * Output : None.
- * Return : None.
- *******************************************************************************/
- int8_t STORAGE_GetMaxLun_FS (void)
- {
- /* USER CODE BEGIN 8 */
- return (STORAGE_LUN_NBR - );
- /* USER CODE END 8 */
- }
- /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */
- /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */
- /**
- * @}
- */
- /**
- * @}
- */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
[转]使用STM32CubeMX:USB大容量存储设备的更多相关文章
- 控制器没有足够的带宽可利用为USB大容量存储设备的解决方法
伴随网盘时代的没落,最近刚入手了一个移动硬盘.现在的移动硬盘都是USB3.0,传输速度比USB2.0要快很多.但是链接笔记本电脑后发现传输速度在20MB/s左右,跟USB2.0速度差不多,并不能达到传 ...
- 弹出USB大容量存储设备时出问题的解决方法
我的计算机->管理->系统工具->事件查看器->自定义视图->Kernel-Pnp->详情->进程ID 然后在任务管理器里找到该进程(任务管理器->查看 ...
- win10突然不能使用usb大容量存储设备(移动硬盘)的解决方法
昨天开始使用usb硬盘,发现一块无法识别,一块识别好了以后不能打开. 可能是之前一次系统更新有bug,但是一直也没有用移动硬盘,所以没有发现. 开始尝试各种方案,已经尝试过并且无效的有以下几个: 1, ...
- [未完] Linux 4.4 USB —— spiflash模拟usb大容量存储设备 调试记录 Gadget Mass Stroage
linux 4.4 USB Gadget Mass Stroage 硬件平台: licheepi nano衍生 调试记录 驱动信息 │ This driver is a replacement for ...
- 【转】弹出USB大容量存储设备时出问题的解决方法
原文链接 如下图所示,这个问题,相信很多人都有遇到过,而且经常难以解决,试了很多方法都无效.到最后,只能抱着侥幸的心理直接拔出,如果运气好,可能没有事,如果运气不好,你的U盘或者移动硬盘就要从此报废了 ...
- 教你开启红米的USB大容量存储选项,全网首发哦
教你开启红米的USB大容量存储选项,全网首发哦 http://bbs.7to.cn/thread-10732-1-1.html 发表于 2014-4-29 110643 红米note入手也有两天了.各 ...
- 如何查找Mac上的USB存储设备使用痕迹
最近刚好有个案子的证物主机是MBP, OS X版本为El Capitan,案况与营业秘密外泄有关,当中要找有关USB存储设备的使用痕迹. 要提醒大家的是,不同版本的OS X,各种迹证的存放文件名称及路 ...
- C# 访问USB(HID)设备
原文:C# 访问USB(HID)设备 二话不说,直接给代码,如果您真想做这方面的东西,还是稍微研究下,没有现成的好类用,就需要自己了解其原理 //引用空间 using System; using Sy ...
- android usb Host模式下与usb Hid 设备的通信
做android 与USB HID设备的通信有段时间了,总结一下遇到的问题和解决方法: 1,第一次遇到的问题:android 版本低不支持usb hid, 被要求做相关项目的时候,就从mUsbMana ...
随机推荐
- 【springboot】之整合ActiveMQ
1.引入依赖的jar <parent> <groupId>org.springframework.boot</groupId> <artifactId> ...
- HEAD插件安装
简介 是一个HTML5编写的集群操作和管理工具,可以对集群进行傻瓜式操作,Head插件中可以显示集群的拓扑结构,执行索引和节点级别等操作,同时也可以输入RESTful命令和Elasticsearch交 ...
- MySQL mysqlbinlog企业案例
内容待补充 案例文字说明: 7.3 故障时间点: 周四上午10点,开发人员误删除了一个表,如何恢复? 7.4 思路: 1.停业务,避免数据的二次伤害 2.找一个临时库,恢复周三23:00全备 3.截取 ...
- scheduler定时器相关
定时器官网: http://www.quartz-scheduler.org/
- ~Vue实现简单答题功能,主要包含单选框和复选框
内容 实现简单答题效果 环境 Vue,webpack(自行安装) 实现方式 页面将答题列表传递给调用组件,组件将结果返回给调用页面(其它模式也ok,这只是例子) ------------------- ...
- linux命令之vi文本编辑器
vi filename :打开或新建文件,并将光标置于第一行首 按i,开始输入(insert) d删除整行 u 撤销上一步的操作Ctrl+r 恢复上一步被撤销的操作 ESC退出输入 按ESC键 跳 ...
- angular的常见问题
ng-if 跟 ng-show/hide 的区别有哪些? 第一点区别是,ng-if 在后面表达式为 true 的时候才创建这个 dom 节点,ng-show 是初始时就创建了,用 display:bl ...
- 《C++数据结构-快速拾遗》 基础常识
1.命名空间函数 namespace wjy { void print() { cout<<"; } int load(int num) { return num; } } us ...
- install
程序包:GNU coreutils 语法: 类似于“cp”,复制文件后默认具有执行权限(755). 选项: 包含公共选项 -d,创建目录. -m,指定复制后的权限设定(默认设定755). -o,指定 ...
- Webpack配置及使用
##如何将js模块化 ### module.exports() ### module.require() ### 自定义文件,进入时需要./ ### npm下载得到文件,不需要./ ##如果使用第三方 ...