为什么我不能将 CubeMX USB MSC 代码集成到默认的端节点 I-CUBE-LRWAN 项目中?
Why can't I integrate the CubeMX USB MSC code into the default end-node I-CUBE-LRWAN project?
我想为我的 Murata B-L072Z-LRWAN1 开发板添加 USB MSC(大容量存储 Class,也就是 USB 存储驱动器)功能。为此,我使用了最新的 I-CUBE-LRWAN 端节点项目并生成了 USB MSC 代码。我过去曾为旧版本的 I-CUBE-LRWAN(2018 年发布)做过此操作并使其正常工作。但是,如果我现在这样做,我会得到两种行为:
- 刷新电路板,连接它,然后我重置电路板。什么都没发生。没有闪烁灯,调试串行输出,没有 USB 也没有 LoRaWAN。
- 刷新电路板,连接它,然后启动调试器会话,我让它 运行 自由地没有任何断点:完全运行,灯工作,调试串行工作,USB 显示自己和 windows说它需要格式化驱动器。 (这是正确的,因为大多数准系统版本没有添加任何存储接口)
我无法解释这个。为什么代码在附加调试器时有效,但在未附加时完全锁定?至于 I-CUBE-LRWAN 新旧版本之间的变化:它们已经从 systick 更改为基于 RTC 的计时设置。但是我无法弄清楚这与调试器有何关系。
移除 USB 设备电缆不会生成代码 运行。
当我注释掉对 MX_USB_DEVICE_Init
的调用时,windows 看到一个无法识别的 USB 设备,但代码的 none 有效(例如,没有调试 UART 输出)。当我取消注释时 MX_USB_DEVICE_Init
没有任何反应,没有 USB 连接。
我正在使用 Keil uVision 作为我的 IDE。编译器版本:“默认编译器版本 6”
要复制这个,您需要一个 B-L072Z-LRWAN1(经过修改以启用 USB 引脚)或带有 USB 端口的 Murata 芯片。完整的最小可重现示例是从 I-CUBE-LRWAN 中获取端节点项目并在 STM32CubeMX 中生成 USB MSC 代码。 (目标 MCU 是 STM32L072CZTx)。然后将所有 USB MSC 文件添加到端节点项目,并在项目中添加以下内容:
将 USB_IRQHandler 添加到 stm32l0xx_it.c
:
extern PCD_HandleTypeDef hpcd_USB_FS;
/**
* @brief This function handles USB event interrupt / USB wake-up interrupt through EXTI line 18.
*/
void USB_IRQHandler(void)
{
HAL_PCD_IRQHandler(&hpcd_USB_FS);
}
将以下时钟配置附加到SystemClock_Config
:
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
while(!LL_RCC_HSI48_IsReady());
/*USB clock initialization */
PeriphClkInit.PeriphClockSelection |= RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
并添加包含的 #include usb_device.h
并在 main.c
中调用 MX_USB_DEVICE_Init();
关于我的旧代码,当我将它闪存到我的板上时,USB 确实可以与其他所有东西(LED、LoRaWAN、调试 UART)一起工作。
运行 USB MSC 代码在它自己的作品中。 运行 LoRaWAN 代码在它自己的作品中。问题只体现在这两个合并上。
问题是 printf
被调用是因为 usbd_conf.h
中的以下定义。
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
* @brief Defines for configuration of the Usb device.
* @{
*/
/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES 1
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION 1
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ 512
/*---------- -----------*/
#define USBD_SUPPORT_USER_STRING 0
/*---------- -----------*/
#define USBD_DEBUG_LEVEL 3
/*---------- -----------*/
#define USBD_SELF_POWERED 1
/*---------- -----------*/
#define MSC_MEDIA_PACKET 512
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros
* @brief Aliases.
* @{
*/
/* Memory management macros */
/** Alias for memory allocation. */
#define USBD_malloc (uint32_t *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset /* Not used */
/** Alias for memory copy. */
#define USBD_memcpy /* Not used */
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_UsrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 1)
#define USBD_ErrLog(...) printf("ERROR: ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_ErrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 2)
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_DbgLog(...)
#endif
所以这个版本的I-CUBE-LRWAN的解决方案是将USBD_DEBUG_LEVEL
的值设置为0
。另一种选择是通过将 printf
更改为 APP_PRINTF
.
来解决此问题
还有一个问题就是sequencer中的sleep函数导致了问题。在 sys_conf.h
中将定义 LOW_POWER_DISABLE
设置为 1
会禁用停止模式。
如果在 USB 操作期间需要更精细的控制,那么在正确的设置和取消设置模式下调用此行将使其工作:
UTIL_LPM_SetStopMode((1 << CFG_LPM_APPLI_Id), UTIL_LPM_DISABLE);
(低功耗在 sys_app.c:96
中处理。
我想为我的 Murata B-L072Z-LRWAN1 开发板添加 USB MSC(大容量存储 Class,也就是 USB 存储驱动器)功能。为此,我使用了最新的 I-CUBE-LRWAN 端节点项目并生成了 USB MSC 代码。我过去曾为旧版本的 I-CUBE-LRWAN(2018 年发布)做过此操作并使其正常工作。但是,如果我现在这样做,我会得到两种行为:
- 刷新电路板,连接它,然后我重置电路板。什么都没发生。没有闪烁灯,调试串行输出,没有 USB 也没有 LoRaWAN。
- 刷新电路板,连接它,然后启动调试器会话,我让它 运行 自由地没有任何断点:完全运行,灯工作,调试串行工作,USB 显示自己和 windows说它需要格式化驱动器。 (这是正确的,因为大多数准系统版本没有添加任何存储接口)
我无法解释这个。为什么代码在附加调试器时有效,但在未附加时完全锁定?至于 I-CUBE-LRWAN 新旧版本之间的变化:它们已经从 systick 更改为基于 RTC 的计时设置。但是我无法弄清楚这与调试器有何关系。
移除 USB 设备电缆不会生成代码 运行。
当我注释掉对 MX_USB_DEVICE_Init
的调用时,windows 看到一个无法识别的 USB 设备,但代码的 none 有效(例如,没有调试 UART 输出)。当我取消注释时 MX_USB_DEVICE_Init
没有任何反应,没有 USB 连接。
我正在使用 Keil uVision 作为我的 IDE。编译器版本:“默认编译器版本 6”
要复制这个,您需要一个 B-L072Z-LRWAN1(经过修改以启用 USB 引脚)或带有 USB 端口的 Murata 芯片。完整的最小可重现示例是从 I-CUBE-LRWAN 中获取端节点项目并在 STM32CubeMX 中生成 USB MSC 代码。 (目标 MCU 是 STM32L072CZTx)。然后将所有 USB MSC 文件添加到端节点项目,并在项目中添加以下内容:
将 USB_IRQHandler 添加到 stm32l0xx_it.c
:
extern PCD_HandleTypeDef hpcd_USB_FS;
/**
* @brief This function handles USB event interrupt / USB wake-up interrupt through EXTI line 18.
*/
void USB_IRQHandler(void)
{
HAL_PCD_IRQHandler(&hpcd_USB_FS);
}
将以下时钟配置附加到SystemClock_Config
:
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
while(!LL_RCC_HSI48_IsReady());
/*USB clock initialization */
PeriphClkInit.PeriphClockSelection |= RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
并添加包含的 #include usb_device.h
并在 main.c
MX_USB_DEVICE_Init();
关于我的旧代码,当我将它闪存到我的板上时,USB 确实可以与其他所有东西(LED、LoRaWAN、调试 UART)一起工作。
运行 USB MSC 代码在它自己的作品中。 运行 LoRaWAN 代码在它自己的作品中。问题只体现在这两个合并上。
问题是 printf
被调用是因为 usbd_conf.h
中的以下定义。
/** @defgroup USBD_CONF_Exported_Defines USBD_CONF_Exported_Defines
* @brief Defines for configuration of the Usb device.
* @{
*/
/*---------- -----------*/
#define USBD_MAX_NUM_INTERFACES 1
/*---------- -----------*/
#define USBD_MAX_NUM_CONFIGURATION 1
/*---------- -----------*/
#define USBD_MAX_STR_DESC_SIZ 512
/*---------- -----------*/
#define USBD_SUPPORT_USER_STRING 0
/*---------- -----------*/
#define USBD_DEBUG_LEVEL 3
/*---------- -----------*/
#define USBD_SELF_POWERED 1
/*---------- -----------*/
#define MSC_MEDIA_PACKET 512
/****************************************/
/* #define for FS and HS identification */
#define DEVICE_FS 0
/**
* @}
*/
/** @defgroup USBD_CONF_Exported_Macros USBD_CONF_Exported_Macros
* @brief Aliases.
* @{
*/
/* Memory management macros */
/** Alias for memory allocation. */
#define USBD_malloc (uint32_t *)USBD_static_malloc
/** Alias for memory release. */
#define USBD_free USBD_static_free
/** Alias for memory set. */
#define USBD_memset /* Not used */
/** Alias for memory copy. */
#define USBD_memcpy /* Not used */
/** Alias for delay. */
#define USBD_Delay HAL_Delay
/* DEBUG macros */
#if (USBD_DEBUG_LEVEL > 0)
#define USBD_UsrLog(...) printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_UsrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 1)
#define USBD_ErrLog(...) printf("ERROR: ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_ErrLog(...)
#endif
#if (USBD_DEBUG_LEVEL > 2)
#define USBD_DbgLog(...) printf("DEBUG : ") ;\
printf(__VA_ARGS__);\
printf("\n");
#else
#define USBD_DbgLog(...)
#endif
所以这个版本的I-CUBE-LRWAN的解决方案是将USBD_DEBUG_LEVEL
的值设置为0
。另一种选择是通过将 printf
更改为 APP_PRINTF
.
还有一个问题就是sequencer中的sleep函数导致了问题。在 sys_conf.h
中将定义 LOW_POWER_DISABLE
设置为 1
会禁用停止模式。
如果在 USB 操作期间需要更精细的控制,那么在正确的设置和取消设置模式下调用此行将使其工作:
UTIL_LPM_SetStopMode((1 << CFG_LPM_APPLI_Id), UTIL_LPM_DISABLE);
(低功耗在 sys_app.c:96
中处理。