开始之前

ART-Pi 2 搭载了 STM32H7R7x 芯片,这是 ST 推出的一款自带 Internal HS PHY 的 MCU。目前论坛里资料较少,故尝试在 RT-Thread Studio 中移植 CherryUSB,本文从创建工程开始,事无巨细地记录了移植的全过程。

移植过程

1. 新建工程

image-20250419020115734

image-20250419020207053

如图示,新建基于 ART-Pi 2 开发板的项目。

工程的目录结构如下:

image-20250419020410693

2. 添加CherryUSB的package

image-20250419020518831

image-20250419020553232

在工程中一键添加CherryUSB的包,按下 Ctrl+S 保存设置,自动开始下载 CherryUSB,这里要注意网络畅通,因为要从 Github 上拉取 最新的 release,成功后控制台信息如下:

image-20250419021305634

3. 配置CherryUSB

在软件包里找到 CherryUSB 的配置项,我们以usb_device为例,进行如下配置,不要忘记保存:

image-20250419020815020

将 ./packages/CherryUSB-v1.4.3/cherryusb_config_template.h 拷贝到 ./board/port 里面,并命名为 usb_config.h,如下图:

image-20250419021711309

然后刷新工程,即可找到新添加的文件。

Screenshot 2025-04-19 022134

打开 usb_config.h,修改以下宏

1
2
#include "rtthread.h"
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)

USB IP 相关的 config 需要自己根据芯片实际情况修改,这里实现下面的宏

1
2
3
4
5
6
7
8
9
10
11
#define CONFIG_USBDEV_EP_NUM 8
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (64 / 4)
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (64 / 4)

修改 ./board/board.c,在最后实现下面函数(我们这里就用 hid_mouse 的 demo)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void usb_dc_low_level_init(uint8_t busid) {
add something...
}

void OTG_HS_IRQHandler(void) {
extern void USBD_IRQHandler(uint8_t busid);
USBD_IRQHandler(0);
}

int usbd_init(void)
{
extern void hid_mouse_init(uint8_t busid, uintptr_t reg_base);
hid_mouse_init(0, USB_OTG_HS_PERIPH_BASE);
return 0;
}

INIT_APP_EXPORT(usbd_init);

关于上面 void usb_dc_low_level_init(uint8_t busid) 函数怎么实现,请参阅我的另一个帖子:在STM32G4上移植CherryUSB协议栈(usb_device),这里主要就是用CubeMX新建一个工程,然后打开USB_HS_OTG和中断,然后在生成的代码里面找到初始化 USB 时钟和中断的代码复制过来,就OK了,下面附上我的实现,可以直接拿去用:

1
2
3
4
5
6
7
8
9
10
void usb_dc_low_level_init(uint8_t busid) {
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USBPHYC;
PeriphClkInit.UsbPhycClockSelection = RCC_USBPHYCCLKSOURCE_HSE;
HAL_PWREx_EnableUSBVoltageDetector();
__HAL_RCC_USB_OTG_HS_CLK_ENABLE();
__HAL_RCC_USBPHYC_CLK_ENABLE();
HAL_NVIC_SetPriority(OTG_HS_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
}

做完以上所有步骤后,编译烧录一气呵成没有报错:

image-20250419023353355

在终端里面可以看到已经识别正确:

image-20250419023159824

且给USB-HS插到电脑上可以正确枚举:

image-20250419023532794

3. 收尾

在 ./applications/main.c 中,添加 CherryUSB 的 hid_mouse 的线程,如图:

image-20250419023807276

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static rt_thread_t hid_thread = RT_NULL;

static void hid_mouse_thread_entry(void *parameter)
{
rt_kprintf("USB HID Mouse thread started\n");
while(1){
extern void hid_mouse_test(uint8_t busid);
hid_mouse_test(0);
}
}

int main(void)
{
...
hid_thread = rt_thread_create("hid_mouse", hid_mouse_thread_entry,
RT_NULL, 1024, 20, 5);
if (hid_thread != RT_NULL)
{
rt_thread_startup(hid_thread);
}
...
}

然后再次编译烧录,发现鼠标不出所料地开始转圈了:)

至此移植结束,再次感谢 sakumisu 的贡献。

附录

附一些图片

355652e85715a278f290de8799c94dc

2f0488a99281d2249a52e645f95fcaf

3043ee331dae5b84d8902f62195a9d7

示例代码

https://github.com/MDLZCOOL/CherryUSB_ART_Pi2