赞
踩
STM32 CubeMX 配置USB将STM32设置可以作为存储设备或者IAP升级功能
要注意:stm32f103c8t6内部Flash的1页为1024(1kb)
需要修改两个部分:usbd_storage_if.c文件和user_diskio.c文件
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : usbd_storage_if.c * @version : v2.0_Cube * @brief : Memory management layer. ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "usbd_storage_if.h" /* USER CODE BEGIN INCLUDE */ /* USER CODE END INCLUDE */ /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* USER CODE END PV */ /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY * @brief Usb device. * @{ */ /** @defgroup USBD_STORAGE * @brief Usb mass storage device module * @{ */ /** @defgroup USBD_STORAGE_Private_TypesDefinitions * @brief Private types. * @{ */ /* USER CODE BEGIN PRIVATE_TYPES */ /* USER CODE END PRIVATE_TYPES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Defines * @brief Private defines. * @{ */ #define FLASH_SIZE 128 #define FMC_SECTOR_SIZE 1024 #define FLASH_PAGE_NBR 64 #define FLASH_START_ADDR (0x08000000+((FLASH_SIZE-FLASH_PAGE_NBR)*1024)) #define STORAGE_LUN_NBR 1 #define STORAGE_BLK_NBR 0x10000 #define STORAGE_BLK_SIZ 0x200 /* USER CODE BEGIN PRIVATE_DEFINES */ /* USER CODE END PRIVATE_DEFINES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Macros * @brief Private macros. * @{ */ /* USER CODE BEGIN PRIVATE_MACRO */ /* USER CODE END PRIVATE_MACRO */ /** * @} */ /** @defgroup USBD_STORAGE_Private_Variables * @brief 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 - 5), 0x00, 0x00, 0x00, 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '0', '.', '0' ,'1' /* Version : 4 Bytes */ }; /* USER CODE END INQUIRY_DATA_FS */ /* USER CODE BEGIN PRIVATE_VARIABLES */ /* USER CODE END PRIVATE_VARIABLES */ /** * @} */ /** @defgroup USBD_STORAGE_Exported_Variables * @brief Public variables. * @{ */ extern USBD_HandleTypeDef hUsbDeviceFS; /* USER CODE BEGIN EXPORTED_VARIABLES */ /* USER CODE END EXPORTED_VARIABLES */ /** * @} */ /** @defgroup USBD_STORAGE_Private_FunctionPrototypes * @brief Private functions declaration. * @{ */ 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 */ /* 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 ---------------------------------------------------------*/ /** * @brief Initializes over USB FS IP * @param lun: * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_Init_FS(uint8_t lun) { /* USER CODE BEGIN 2 */ return (USBD_OK); /* USER CODE END 2 */ } /** * @brief . * @param lun: . * @param block_num: . * @param block_size: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ //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 */ //} //修改1 int8_t STORAGE_GetCapacity_FS(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { /* USER CODE BEGIN 3 */ *block_num = FLASH_PAGE_NBR; *block_size = FLASH_PAGE_SIZE; return (USBD_OK); /* USER CODE END 3 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_IsReady_FS(uint8_t lun) { /* USER CODE BEGIN 4 */ return (USBD_OK); /* USER CODE END 4 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ int8_t STORAGE_IsWriteProtected_FS(uint8_t lun) { /* USER CODE BEGIN 5 */ return (USBD_OK); /* USER CODE END 5 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ //int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) //{ // /* USER CODE BEGIN 6 */ // return (USBD_OK); // /* USER CODE END 6 */ //} //修改2 int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { /* USER CODE BEGIN 6 */ if(lun == 0) { memcpy(buf,(uint8_t *)(FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE),blk_len*FLASH_PAGE_SIZE); return USBD_OK; } return USBD_FAIL; /* USER CODE END 6 */ } /** * @brief . * @param lun: . * @retval USBD_OK if all operations are OK else USBD_FAIL */ //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 */ //} //修改3 int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { /* USER CODE BEGIN 7 */ uint16_t i; uint32_t PageError = 0; FLASH_EraseInitTypeDef Flash; if(lun == 0) { HAL_FLASH_Unlock(); Flash.TypeErase = FLASH_TYPEERASE_PAGES; Flash.PageAddress = FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE ; Flash.NbPages = blk_len; HAL_FLASHEx_Erase(&Flash, &PageError); for(i=0;i<blk_len*FLASH_PAGE_SIZE;i+=4) { HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,FLASH_START_ADDR + blk_addr*FLASH_PAGE_SIZE + i , *(uint32_t *)(&buf[i])); } HAL_FLASH_Lock(); return USBD_OK; } return USBD_FAIL; /* USER CODE END 7 */ } /** * @brief . * @param None * @retval . */ int8_t STORAGE_GetMaxLun_FS(void) { /* USER CODE BEGIN 8 */ return (STORAGE_LUN_NBR - 1); /* USER CODE END 8 */ } /* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */ /* USER CODE END PRIVATE_FUNCTIONS_IMPLEMENTATION */ /** * @} */ /** * @} */
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file user_diskio.c * @brief This file includes a diskio driver skeleton to be completed by the user. ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ #ifdef USE_OBSOLETE_USER_CODE_SECTION_0 /* * Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0) * To be suppressed in the future. * Kept to ensure backward compatibility with previous CubeMx versions when * migrating projects. * User code previously added there should be copied in the new user sections before * the section contents can be deleted. */ /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ #endif /* USER CODE BEGIN DECL */ /* Includes ------------------------------------------------------------------*/ #include <string.h> #include "ff_gen_drv.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ /* Disk status */ static volatile DSTATUS Stat = STA_NOINIT; #define FLASH_SIZE 128 #define FMC_SECTOR_SIZE 1024 #define FLASH_PAGE_NBR 64 #define FLASH_START_ADDR (0x08000000+((FLASH_SIZE-FLASH_PAGE_NBR)*1024)) /* USER CODE END DECL */ /* Private function prototypes -----------------------------------------------*/ DSTATUS USER_initialize (BYTE pdrv); DSTATUS USER_status (BYTE pdrv); DRESULT USER_read (BYTE pdrv, BYTE *buff, DWORD sector, UINT count); #if _USE_WRITE == 1 DRESULT USER_write (BYTE pdrv, const BYTE *buff, DWORD sector, UINT count); #endif /* _USE_WRITE == 1 */ #if _USE_IOCTL == 1 DRESULT USER_ioctl (BYTE pdrv, BYTE cmd, void *buff); #endif /* _USE_IOCTL == 1 */ Diskio_drvTypeDef USER_Driver = { USER_initialize, USER_status, USER_read, #if _USE_WRITE USER_write, #endif /* _USE_WRITE == 1 */ #if _USE_IOCTL == 1 USER_ioctl, #endif /* _USE_IOCTL == 1 */ }; /* Private functions ---------------------------------------------------------*/ /** * @brief Initializes a Drive * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ DSTATUS USER_initialize ( BYTE pdrv /* Physical drive nmuber to identify the drive */ ) { /* USER CODE BEGIN INIT */ Stat = STA_NOINIT; return Stat; /* USER CODE END INIT */ } /** * @brief Gets Disk Status * @param pdrv: Physical drive number (0..) * @retval DSTATUS: Operation status */ //DSTATUS USER_status ( // BYTE pdrv /* Physical drive number to identify the drive */ //) //{ // /* USER CODE BEGIN STATUS */ // Stat = STA_NOINIT; // return Stat; // /* USER CODE END STATUS */ //} // 修改1 DSTATUS USER_status ( BYTE pdrv /* Physical drive number to identify the drive */ ) { /* USER CODE BEGIN STATUS */ Stat = STA_NOINIT; Stat &= ~STA_NOINIT; return Stat; /* USER CODE END STATUS */ } /** * @brief Reads Sector(s) * @param pdrv: Physical drive number (0..) * @param *buff: Data buffer to store read data * @param sector: Sector address (LBA) * @param count: Number of sectors to read (1..128) * @retval DRESULT: Operation result */ //DRESULT USER_read ( // BYTE pdrv, /* Physical drive nmuber to identify the drive */ // BYTE *buff, /* Data buffer to store read data */ // DWORD sector, /* Sector address in LBA */ // UINT count /* Number of sectors to read */ //) //{ // /* USER CODE BEGIN READ */ // return RES_OK; // /* USER CODE END READ */ //} //修改2 DRESULT USER_read ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to read */ ) { /* USER CODE BEGIN READ */ uint8_t *s = (uint8_t *)(FLASH_START_ADDR); s+=(sector*FMC_SECTOR_SIZE); for(int i=0; i<count*FMC_SECTOR_SIZE ;i++) { *(buff++) = *(s++ ); } return RES_OK; /* USER CODE END READ */ } /** * @brief Writes Sector(s) * @param pdrv: Physical drive number (0..) * @param *buff: Data to be written * @param sector: Sector address (LBA) * @param count: Number of sectors to write (1..128) * @retval DRESULT: Operation result */ #if _USE_WRITE == 1 //DRESULT USER_write ( // BYTE pdrv, /* Physical drive nmuber to identify the drive */ // const BYTE *buff, /* Data to be written */ // DWORD sector, /* Sector address in LBA */ // UINT count /* Number of sectors to write */ //) //{ // /* USER CODE BEGIN WRITE */ // /* USER CODE HERE */ // return RES_OK; // /* USER CODE END WRITE */ //} //修改3 DRESULT USER_write ( BYTE pdrv, /* Physical drive nmuber to identify the drive */ const BYTE *buff, /* Data to be written */ DWORD sector, /* Sector address in LBA */ UINT count /* Number of sectors to write */ ) { /* USER CODE BEGIN WRITE */ /* USER CODE HERE */ uint16_t i; HAL_FLASH_Unlock(); FLASH_EraseInitTypeDef f; f.TypeErase = FLASH_TYPEERASE_PAGES; f.PageAddress = FLASH_START_ADDR + sector*FLASH_PAGE_SIZE ; f.NbPages = count; uint32_t PageError = 0; HAL_FLASHEx_Erase(&f, &PageError); for(i=0;i<count*FLASH_PAGE_SIZE;i+=4) HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,FLASH_START_ADDR + sector*FLASH_PAGE_SIZE + i , *(uint32_t *)(&buff[i])); HAL_FLASH_Lock(); return RES_OK; /* USER CODE END WRITE */ } #endif /* _USE_WRITE == 1 */ /** * @brief I/O control operation * @param pdrv: Physical drive number (0..) * @param cmd: Control code * @param *buff: Buffer to send/receive control data * @retval DRESULT: Operation result */ #if _USE_IOCTL == 1 //DRESULT USER_ioctl ( // BYTE pdrv, /* Physical drive nmuber (0..) */ // BYTE cmd, /* Control code */ // void *buff /* Buffer to send/receive control data */ //) //{ // /* USER CODE BEGIN IOCTL */ // DRESULT res = RES_ERROR; // return res; // /* USER CODE END IOCTL */ //} //修改4 DRESULT USER_ioctl ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE cmd, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { /* USER CODE BEGIN IOCTL */ DRESULT res = RES_ERROR; switch(cmd) { case CTRL_SYNC : res = RES_OK; break; case CTRL_TRIM: res = RES_OK; break; case GET_BLOCK_SIZE: *(DWORD*)buff = 1; break; case GET_SECTOR_SIZE: *(DWORD*)buff = FMC_SECTOR_SIZE; break; case GET_SECTOR_COUNT: *(DWORD*)buff = FLASH_PAGE_NBR; break; default: res = RES_PARERR; break; } return res; /* USER CODE END IOCTL */ } #endif /* _USE_IOCTL == 1 */
int main(void) { /* USER CODE BEGIN 1 */ char path[4]= {"0:"}; FRESULT FATFS_Status; /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_FATFS_Init(); MX_USB_DEVICE_Init(); /* USER CODE BEGIN 2 */ FATFS_Status = f_mount(&USERFatFS, path, 1); f_mkdir("0:/FW"); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ }
新建一个TXT文档:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。