stm32 HAL USB虚拟2个逻辑磁盘

最近学习了stm32 HAL 模拟U盘,  但是只能模拟一个逻辑磁盘,  我有一个spi flash, 有一个 sd卡, 我想都在电脑上显示

但是发现很少有人来虚拟2个的,为此我借助特殊通道去看了下多逻辑磁盘的操作

发现很多人只改这个STORAGE_LUN_NBR, 这样是不够的

int8_t STORAGE_GetMaxLun_FS(void)
{
  /* USER CODE BEGIN 8 */
    return (STORAGE_LUN_NBR - 1);
  /* USER CODE END 8 */
}

还需要更改这个描述结构体, 才可以模拟出2个, 以此类推 如果3个,就需要把宏定义和这个描述结构体更改了

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 */
		/* LUN 1*/
	  0x00,
    0x80,
    0x02,
    0x02,
    (STANDARD_INQUIRY_DATA_LEN - 5),
    0x00,
    0x00,
    0x00,
    'S', 'T', 'K', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
    'P', 'r', 'o', 'd', '1', 'c', 't', ' ', /* Product      : 16 Bytes */
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    '0', '.', '0','1'
};

 

文章结尾附上我2个磁盘的代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : usbd_storage_if.c
  * @version        : v1.0_Cube
  * @brief          : Memory management layer.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under Ultimate Liberty license
  * SLA0044, the "License"; You may not use this file except in compliance with
  * the License. You may obtain a copy of the License at:
  *                             www.st.com/SLA0044
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "usbd_storage_if.h"

/* USER CODE BEGIN INCLUDE */

#include "stdio.h"
#include "sdio.h"
#include "driver_spi_flash.h"
#include "bsp_driver_sd.h"

#define MMM_BLOCK_SIZE   4096
//#define USB_USE_SD
#define USB_USE_2_LUN
/* 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 STORAGE_LUN_NBR                  2
#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. */
#ifdef USB_USE_2_LUN
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 */
		/* LUN 1*/
	  0x00,
    0x80,
    0x02,
    0x02,
    (STANDARD_INQUIRY_DATA_LEN - 5),
    0x00,
    0x00,
    0x00,
    'S', 'T', 'K', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */
    'P', 'r', 'o', 'd', '1', 'c', 't', ' ', /* Product      : 16 Bytes */
    ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
    '0', '.', '0','1'
};
#else 
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'
};
#endif
/* 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 */

#ifdef USB_USE_2_LUN
    if(lun==0) {
        *block_num  = hsd.SdCard.BlockNbr ;
        *block_size = hsd.SdCard.BlockSize;
    } else if(lun==1) {
        *block_num = SPI_FLASH_FATFS_SELECTOR_SIZE;
        *block_size = SPI_FLASH_BLOCK_SIZE;
    } else {
    }
#else
#ifdef USB_USE_SD
    *block_num  = hsd.SdCard.BlockNbr ;
    *block_size = hsd.SdCard.BlockSize;
#else
    *block_num = SPI_FLASH_FATFS_SELECTOR_SIZE;
    *block_size = SPI_FLASH_BLOCK_SIZE;
#endif
#endif

    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 */


		//printf("--- usb read lun -- :%d\r\n",lun);
#ifdef USB_USE_2_LUN
    if(lun==0) {
        if(HAL_OK != HAL_SD_ReadBlocks(&hsd,(uint8_t *)buf, blk_addr, blk_len, 1000))
            return USBD_FAIL ;
    } else if(lun==1) {
        SPI_FLASH_BufferRead(buf, blk_addr*MMM_BLOCK_SIZE, blk_len*MMM_BLOCK_SIZE);
    } else {
    }
#else
#ifdef USB_USE_SD
    if(HAL_OK != HAL_SD_ReadBlocks(&hsd,(uint8_t *)buf, blk_addr, blk_len, 1000))
        return USBD_FAIL ;
#else

    SPI_FLASH_BufferRead(buf, blk_addr*MMM_BLOCK_SIZE, blk_len*MMM_BLOCK_SIZE);
#endif
#endif
    return (USBD_OK);
  /* 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 */




#ifdef USB_USE_2_LUN
    if(lun==0) {
        if(HAL_OK != HAL_SD_WriteBlocks(&hsd, (uint8_t *)buf, blk_addr, blk_len, 1000))
            return USBD_FAIL ;
    } else if(lun==1) {
        SPI_FLASH_SectorErase(blk_addr*MMM_BLOCK_SIZE);
        SPI_FLASH_BufferWrite(buf,blk_addr*MMM_BLOCK_SIZE,blk_len*MMM_BLOCK_SIZE);
    } else {
    }
#else
#ifdef USB_USE_SD
    if(HAL_OK != HAL_SD_WriteBlocks(&hsd, (uint8_t *)buf, blk_addr, blk_len, 1000))
        return USBD_FAIL ;
#else
    SPI_FLASH_SectorErase(blk_addr*MMM_BLOCK_SIZE);
    SPI_FLASH_BufferWrite(buf,blk_addr*MMM_BLOCK_SIZE,blk_len*MMM_BLOCK_SIZE);
#endif
#endif
    return (USBD_OK);
  /* 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 */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 HAL库提供了一种方便的方法来实现USB虚拟串口功能。通过使用CubeMX工具生成的代码,可以轻松地配置和初始化USB虚拟串口。\[1\]在生成的代码中,可以找到一个名为"usbd_cdc_if.c"的文件,其中声明了USB管理结构体变量并进行了赋值。此外,还修改了"CDC_Receive_FS"函数,该函数用于接收USB数据并进行处理。\[3\] 通过使用USB虚拟串口,您可以在STM32芯片上模拟一个串口设备,使其能够与计算机或其他串口设备进行通信。例如,您可以通过虚拟串口将数据发送到计算机上的串口终端,并从计算机上的串口终端接收数据。\[2\] 使用STM32 HAL库和USB虚拟串口功能,您可以方便地实现STM32与计算机之间的串口通信,而无需关注USB底层复杂的实现方式。您可以使用HAL函数来发送和接收数据,从而简化了开发过程。 #### 引用[.reference_title] - *1* *2* [【STM32+cubemx】0016 HAL库开发:USB虚拟串口(virtual COM)](https://blog.csdn.net/little_grapes/article/details/121549875)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32HAL----USB模拟串口(VCP)](https://blog.csdn.net/a3748622/article/details/80262395)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值