硬汉嵌入式论坛

 找回密码
 立即注册
查看: 458|回复: 9
收起左侧

[USB] STM32H743 USB片内Flash虚拟U盘,初始化可以写入,主程序无法正常写入

[复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2025-8-11 16:50:00 | 显示全部楼层 |阅读模式
初始化状态下可以在虚拟U盘中创建文件,并在文件下能写入数据.但是主程序中通过修改控制使能,重新创建文件并写入新数据时无法写入.为什么没有调用STORAGE_Read_FS()这个函数
1.jpg
2.jpg
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118331
QQ
发表于 2025-8-12 09:16:20 | 显示全部楼层
意思是虚拟U盘的情况下,程序内部FatFS还要继续操作Flash吗?这种不行,会影响电脑USB轮询U胖设备状态。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2025-8-12 13:53:42 | 显示全部楼层
说的很正确,如何实实现实时对虚拟出U盘文件系统操作。为什么重新初始化Usb驱动函数(MX_USB_DEVICE_Init())就可以对Fatfs系统操作,请大侠指点下具体处理方法!
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2025-8-12 13:58:37 | 显示全部楼层
说的很正确,需要实时通过文件系统修改U盘中数据。我测试下,重新调用下MX_USB_DEVICE_Init(),这个函数就可以.但是我肯定这个方法是错误的。请教下大侠们怎么具体处理,谢谢!
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2025-8-12 14:00:10 | 显示全部楼层
说的很正确,需要实时通过文件系统修改U盘中数据。我测试下,重新调用下MX_USB_DEVICE_Init(),这个函数就可以.但是我肯定这个方法是错误的。请教下大侠们怎么具体处理,谢谢!
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118331
QQ
发表于 2025-8-13 09:12:25 | 显示全部楼层
湖北兔八哥 发表于 2025-8-12 13:58
说的很正确,需要实时通过文件系统修改U盘中数据。我测试下,重新调用下MX_USB_DEVICE_Init(),这个函数就可 ...

模拟MTP媒体设备可以解决。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2025-8-13 12:17:59 | 显示全部楼层
eric2013 发表于 2025-8-13 09:12
模拟MTP媒体设备可以解决。

大侠有没有这方面资料,或者移植方法。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118331
QQ
发表于 2025-8-14 09:00:28 | 显示全部楼层
湖北兔八哥 发表于 2025-8-13 12:17
大侠有没有这方面资料,或者移植方法。

这个我们没有
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2025-8-25 10:33:16 | 显示全部楼层
eric2013 发表于 2025-8-12 09:16
意思是虚拟U盘的情况下,程序内部FatFS还要继续操作Flash吗?这种不行,会影响电脑USB轮询U胖设备状态。

硬汉哥,我现在在用QSPI FLASH做虚拟U盘。逻辑扇区大小和簇大小都是4096字节,你之前的例程也是这样做的,USB_MSC里面也是把QSPI FLASH当成逻辑扇区大小为4096的设备,但实际上USB_MSC并不支持逻辑扇区为4096字节的设备。我不知道为什么你的例程还能正常连接电脑,格式化虚拟U盘。我这里的电脑上,显示U盘挂载不正常。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
118331
QQ
发表于 2025-8-26 08:31:37 | 显示全部楼层
pypy921023 发表于 2025-8-25 10:33
硬汉哥,我现在在用QSPI FLASH做虚拟U盘。逻辑扇区大小和簇大小都是4096字节,你之前的例程也是这样做的 ...

我这个配置的4096,使用确实都正常。

[C] 纯文本查看 复制代码
SBD_StorageTypeDef USBD_DISK_fops = {
  STORAGE_Init,
  STORAGE_GetCapacity,
  STORAGE_IsReady,
  STORAGE_IsWriteProtected,
  STORAGE_Read,
  STORAGE_Write,
  STORAGE_GetMaxLun,
  STORAGE_Inquirydata,
};

/* Private functions --------------------------------------------------------- */

/**
  * @brief  Initializes the storage unit (medium)       
  * @param  lun: Logical unit number
  * @retval Status (0 : OK / -1 : Error)
  */
int8_t STORAGE_Init(uint8_t lun)
{
	int8_t ret = -1;
	
	switch (lun)
	{
		case LUN_SPIFLASH:
			//bsp_InitSFlash();
			ret = 0;
			break;

		case LUN_SD:	
			BSP_SD_Init();
			ret = 0;
			break;
		
		case LUN_NAND:
			break;
			
		case LUN_SDRAM:
			break;
	}
	return ret;	
}

/**
  * @brief  Returns the medium capacity.      
  * @param  lun: Logical unit number
  * @param  block_num: Number of total block number
  * @param  block_size: Block size
  * @retval Status (0: OK / -1: Error)
  */
int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t * block_num,
                           uint16_t * block_size)
{
	int8_t ret = -1;
	
	switch (lun)
	{
		case LUN_SPIFLASH:	
			{
				*block_size =  4096;  
				*block_num =  1024*8;  
				ret = 0;
			}
			break;
		
		case LUN_SD:	
			{
				HAL_SD_CardInfoTypeDef info;
				
				if (BSP_SD_IsDetected() != SD_NOT_PRESENT)
				{
					BSP_SD_GetCardInfo(&info);

					*block_num = info.LogBlockNbr - 1;
					*block_size = info.LogBlockSize;
					ret = 0;
				}
			}
			break;
		
		case LUN_NAND:	
			break;
			
		case LUN_SDRAM:
			ret = 0;			
			break;
	}	
	return ret; 
}

/**
  * @brief  Checks whether the medium is ready.  
  * @param  lun: Logical unit number
  * @retval Status (0: OK / -1: Error)
  */
int8_t STORAGE_IsReady(uint8_t lun)
{
	int8_t ret = -1;
	switch (lun)
	{
		case LUN_SPIFLASH:
			ret = 0;
			break;
		
		case LUN_SD:	
			{
				static int8_t prev_status = 0;

				if (BSP_SD_IsDetected() != SD_NOT_PRESENT)
				{
					if (prev_status < 0)
					{
						BSP_SD_Init();
						prev_status = 0;
					}

					if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
					{
						ret = 0;
					}
				}
				else if (prev_status == 0)
				{
					prev_status = -1;
				}
			}
			break;

		case LUN_NAND:
			ret = 0;
			break;
		
		case LUN_SDRAM:
			ret = 0;
			break;
	}
	return ret;
}

/**
  * @brief  Checks whether the medium is write protected.
  * @param  lun: Logical unit number
  * @retval Status (0: write enabled / -1: otherwise)
  */
int8_t STORAGE_IsWriteProtected(uint8_t lun)
{
  return 0;
}

/**
  * @brief  Reads data from the medium.
  * @param  lun: Logical unit number
  * @param  blk_addr: Logical block address
  * @param  blk_len: Blocks number
  * @retval Status (0: OK / -1: Error)
  */
int8_t STORAGE_Read(uint8_t lun, uint8_t * buf, uint32_t blk_addr,
                    uint16_t blk_len)
{
	int8_t ret = -1;
	switch (lun)
	{
		case LUN_SPIFLASH:
		    QSPI_ReadBuffer(buf, blk_addr << 12, blk_len<<12);
			ret = 0;
			break;
		
		case LUN_SD:	
			{
				if (BSP_SD_IsDetected() != SD_NOT_PRESENT)
				{
					BSP_SD_ReadBlocks((uint32_t *) buf, blk_addr, blk_len, 1000);

					/* Wait until SD card is ready to use for new operation */
					while (BSP_SD_GetCardState() != SD_TRANSFER_OK)
					{
					}

					ret = 0;
				}
			}
			break;

		case LUN_NAND:
			break;
			
		case LUN_SDRAM:
			break;
	}
	return ret;
}

/**
  * @brief  Writes data into the medium.
  * @param  lun: Logical unit number
  * @param  blk_addr: Logical block address
  * @param  blk_len: Blocks number
  * @retval Status (0 : OK / -1 : Error)
  */
int8_t STORAGE_Write(uint8_t lun, uint8_t * buf, uint32_t blk_addr,
                     uint16_t blk_len)
{
	int8_t ret = -1;
	uint32_t addr;
	uint16_t i;
	uint8_t *p;
	switch (lun)
	{
		case LUN_SPIFLASH:
			p = (uint8_t *)buf;
			for(i = 0; i < blk_len; i++)
			{
				addr = (blk_addr + i) << 12;
				QSPI_EraseSector(addr);

				QSPI_WriteBuffer(p + 256*0, addr + 256*0, 256);
				QSPI_WriteBuffer(p + 256*1, addr + 256*1, 256);
				QSPI_WriteBuffer(p + 256*2, addr + 256*2, 256);
				QSPI_WriteBuffer(p + 256*3, addr + 256*3, 256);	
				
				QSPI_WriteBuffer(p + 256*4, addr + 256*4, 256);
				QSPI_WriteBuffer(p + 256*5, addr + 256*5, 256);
				QSPI_WriteBuffer(p + 256*6, addr + 256*6, 256);
				QSPI_WriteBuffer(p + 256*7, addr + 256*7, 256);	
				
				QSPI_WriteBuffer(p + 256*8,  addr + 256*8, 256);
				QSPI_WriteBuffer(p + 256*9,  addr + 256*9, 256);
				QSPI_WriteBuffer(p + 256*10, addr + 256*10, 256);
				QSPI_WriteBuffer(p + 256*11, addr + 256*11, 256);	
				
				QSPI_WriteBuffer(p + 256*12, addr + 256*12, 256);
				QSPI_WriteBuffer(p + 256*13, addr + 256*13, 256);
				QSPI_WriteBuffer(p + 256*14, addr + 256*14, 256);
				QSPI_WriteBuffer(p + 256*15, addr + 256*15, 256);	
				
				p += 4096;					
			}
			ret = 0;
			break;
		
		case LUN_SD:	
			{
				if (BSP_SD_IsDetected() != SD_NOT_PRESENT)
				{
					BSP_SD_WriteBlocks((uint32_t *) buf, blk_addr, blk_len, 1000);

					/* Wait until SD card is ready to use for new operation */
					while (BSP_SD_GetCardState() != SD_TRANSFER_OK)
					{
					}

					ret = 0;
				}
			}
			break;

		case LUN_NAND:		
			break;
			
		case LUN_SDRAM:
			break;
	}
	return ret;
}

/**
  * @brief  Returns the Max Supported LUNs.   
  * @param  None
  * @retval Lun(s) number
  */
int8_t STORAGE_GetMaxLun(void)
{
  return (STORAGE_LUN_NBR - 1);
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-9-26 16:44 , Processed in 0.048689 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表