对于单片机来说,跳转BOOTLOADER一般可以通过自己实现一个BOOTLOADER来实现,同样,RP2040也可以这样来做,不过,如果没有特别的要求,也可以使用更简单的方法。
1、利用bootrom跳转USB boot
RP2040的片上ROM固化了一个Bootloader,这个bootloader可以通过实现一个USB大容量设备来在电脑上加载UF2格式的固件,这个Bootloader是默认上电的时候检查Flash不可用或者Flash中没有可启动的程序的时候会自动跳转。
如果希望在程序中跳转进入Bootloader,可以借用这个自带的Bootloader,对于一些简单应用可以省去很多事情,或者用于用于免下电免调试器下载固件。
为了不用操作RUN这个引脚或者下电之后按住BOOT引脚(FLASH的CS)重新进Bootloader,而是直接在程序内根据触发条件运行,通过代码来实现内部跳转显然是有必要的,实际上官方手册已经给出了详细方法,能够让RP2040可以直接跳转到Bootrom直接进入USB大容量模式来下载UF2固件。
WCH或者STC的单片机,他们默认支持串口下载或者USB下载,跳转到USB或者串口下载模式只需要跳转到ROM指定地址,只需要在代码中添加跳转地址并调用即可。同样,RP2040也是类似。
RP2040的启动顺序见Datasheet. 片上16k rom位于0x00000000地址,不过库函数提供了方法,不需要自己找对应的执行位置。
1.0 实现方法
这个方法在官方例程中没有单独列出,实际上这个功能已经在bootrom.h内实现,而是在数据手册中解释了,可能是实现这个太简单了因此没有单独拿出来说。
只需要在代码中加入下面这部分内容即可,然后每次调用enter_usb_dfu_bootloader()即可进入RP2040自带的Bootloader.
|
reset_usb_boot这一句实际上是实现了重启到指定位置。 这里函数可以传入两个参数。 第一个是IO设置,0是表示禁用,其他数字表示设置单个bit的IO,在USB大容量模式下主机活动的时候,IO会被拉高,说白了进入Bootloader之后可以选用一个下载指示灯,这个可以指定GPIO。 第二个参数是要使用的接口:
- 选0:同时开启了USB大容量模式和USB PICOBOOT接口(与正常的冷启动相同)
- 参数为1:只使用USB PICOBOOT接口
- 参数为2:只使用USB大容量模式。 例如,如果只需要启用USB 大容量储存模式,换成下面这个参数即可:
reset_usb_boot(0, 2);//禁用PICOBOOT模式 |
实际上这个函数就是类似于下面这种方法,跳转地址执行,但是SDK中已经配置好了准确的地址,并能根据参数选择不同配置: (未验证):
void (*bootrom)(void) = (void (*)(void))(0x00000000 + 4); |
这段代码定义了一个指针bootrom
,指向0x00000004的地址,即bootrom的入口地址。然后调用该指针即可跳转到bootrom。需要注意的是,为了确保正确的跳转,必须将指针类型强制转换为void (*)(void)
,但是跳转到BOOTROM并不会直接进入USBBOOT.
tips:如果启用PICOBOOT,Windows下会显示RP2 BOOT的USB设备,显示没有驱动,因为没有WinUSB的MSOS支持,不过依然可以手动加载WINUSB驱动或者使用LIBUSB.
这种方法也就是和RP2040的Arduino框架中使用的相似的方法(arudino大概是基于PICOBOOT传输固件)。
1.1 实际使用
有了这个方法,对于有按键的开发板,可以设置一键进入Bootrom。 例如我买的这个板子上24号引脚用作了用户按键,因此加入引脚配置为输入并上拉:
|
或者使用中断来完成这个功能,可能更方便:
void usr_btn_callback(uint gpio, uint32_t events) { |
1.2 参考来源
- RP2040 Datasheet: 2.8章节说明了bootrom,其中包括有关USB PICOBOOT模式的详细说明和电气特性。(简单来说这是一个基本接口,提供了一些读写擦除RAM、FLASH、重启等简单的调试功能,除了手册上详细的描述,还可以看picoboot.h)
- Raspberry Pi Pico C/C++ SDK: 这里面也对USB PICOBOOT的部分场合做了解释,不过不多,直接搜索即可。
2、实现自己的Bootloader
见 文章 RP2040的自定义Bootloader