USBX与STM32H7相关资源
ThreadX官方文档
ThreadX代码仓库
STM32Cube MCU包
USBX代码仓库
x-cube-azrtos-h7
USBX移植(仅移植device部分)
首先在USBX代码仓库中下载USBX,将FileX的.\common\core\scr
、.\common\usbx_device_classes\scr
文件夹下的源文件全部添加到工程中,.\port
文件夹下没有源文件,这一部分需要自己实现(STM32提供了相关代码),并添加包含路径.\common\core\inc
、.\ports\cortex_m7\gnu\inc
。
需要注意,有些函数需要使用NetX,将这些文件设置为不编译即可(若直接使用宏定义UX_STANDALONE
会导致运行不正常,目前原因未知)。
移植sd驱动
下载x-cube-azrtos-h7,将一个Projects\STM32H735G-DK\Applications\USBX\Ux_Device_MSC\USBX
下的ux_device_descriptors.c
、ux_device_msc.c
添加到工程中并添加相应头文件,app_usbx_device.c
中有示例实现,也可以添加进来在此基础上修改,将.\Middlewares\ST\USBX\common\usbx_stm32_device_controllers
下的源文件添加进工程,并添加相应的头文件。
修改相关文件
此外,还需要我们实现ux_device_msc.c下的读取储存介质的函数:
/**
* @brief USBD_STORAGE_Read
* This function is invoked to read from media.
* @param storage_instance : Pointer to the storage class instance.
* @param lun: Logical unit number is the command is directed to.
* @param data_pointer: Address of the buffer to be used for reading or
* writing.
* @param number_blocks: number of sectors to read/write.
* @param lba: Logical block address is the sector address to read.
* @param media_status: should be filled out exactly like the media status
* callback return value.
* @retval status
*/
UINT USBD_STORAGE_Read(VOID *storage_instance, ULONG lun, UCHAR *data_pointer,
ULONG number_blocks, ULONG lba, ULONG *media_status)
{
UINT status = UX_SUCCESS;
/* USER CODE BEGIN USBD_STORAGE_Read */
UX_PARAMETER_NOT_USED(storage_instance);
UX_PARAMETER_NOT_USED(lun);
UX_PARAMETER_NOT_USED(number_blocks);
UX_PARAMETER_NOT_USED(media_status);
for (UINT block = 0; block < number_blocks; block++)
{
status = fx_media_read(&sdio_disk, lba + block, data_pointer);
data_pointer += sdio_disk.fx_media_bytes_per_sector;
if(status != UX_SUCCESS)
{
break;
}
}
return status;
}
/**
* @brief USBD_STORAGE_Write
* This function is invoked to write in media.
* @param storage_instance : Pointer to the storage class instance.
* @param lun: Logical unit number is the command is directed to.
* @param data_pointer: Address of the buffer to be used for reading or
* writing.
* @param number_blocks: number of sectors to read/write.
* @param lba: Logical block address is the sector address to read.
* @param media_status: should be filled out exactly like the media status
* callback return value.
* @retval status
*/
UINT USBD_STORAGE_Write(VOID *storage_instance, ULONG lun, UCHAR *data_pointer,
ULONG number_blocks, ULONG lba, ULONG *media_status)
{
UINT status = UX_SUCCESS;
/* USER CODE BEGIN USBD_STORAGE_Write */
UX_PARAMETER_NOT_USED(storage_instance);
UX_PARAMETER_NOT_USED(lun);
UX_PARAMETER_NOT_USED(number_blocks);
UX_PARAMETER_NOT_USED(media_status);
for (UINT block = 0; block < number_blocks; block++)
{
status = fx_media_write(&sdio_disk, lba + block, data_pointer);
data_pointer += sdio_disk.fx_media_bytes_per_sector;
if(status != UX_SUCCESS)
{
break;
}
}
return status;
}
以上是USBD_STORAGE_Read
、USBD_STORAGE_Write
两个函数在FileX基础上实现的
/**
* @brief USBD_STORAGE_GetMediaLastLba
* Get Media last LBA.
* @param none
* @retval last lba
*/
ULONG USBD_STORAGE_GetMediaLastLba(VOID)
{
ULONG LastLba = 0U;
/* USER CODE BEGIN USBD_STORAGE_GetMediaLastLba */
LastLba = (ULONG)(hsd1.SdCard.BlockNbr - 1);
/* USER CODE END USBD_STORAGE_GetMediaLastLba */
return LastLba;
}
/**
* @brief USBD_STORAGE_GetMediaBlocklength
* Get Media block length.
* @param none.
* @retval block length.
*/
ULONG USBD_STORAGE_GetMediaBlocklength(VOID)
{
ULONG MediaBlockLen = 0U;
/* USER CODE BEGIN USBD_STORAGE_GetMediaBlocklength */
MediaBlockLen = (ULONG)hsd1.SdCard.BlockSize;
/* USER CODE END USBD_STORAGE_GetMediaBlocklength */
return MediaBlockLen;
}
USBD_STORAGE_GetMediaBlocklength
、USBD_STORAGE_GetMediaLastLba
是直接读取的HAL库中的结构体得到的。
至此,移植完毕。
可选的配置选项
若要使用ux_user.h
需要宏定义UX_INCLUDE_USER_DEFINE
。
omg,是写单片机的福瑞