请问CH573F使用自定义bootloader的时候如何实现协议栈和app分离?

先交代一下背景:

bootloader为自行实现版本,占据0x00000-0x7FFF,功能为通过USB和UART下载hex文件,已经验证过一切正常。

bootloader本身和BLE协议栈没有任何关联,可以下载任何类型的hex文件。

用户app从0x8000开始,使用BLE\Broadcaster这个demo,修改Link.ld文件,将FLASH起始地址改到0x8000,SRAM起始地址0x4800,长度14kB。

BLE协议栈链接LIBCH57xBLE.a这个文件,将协议栈编译到app中,编译完成使用bootloader直接下载app的hex文件,运行一切正常。

由于每次要下载的hex包含协议栈体积较大,耗时长,因此希望将app和协议栈分离,app按以下步骤修改:

  • 定义全局宏 #define CH57xBLE_ROM,这样会使用CH57xBLE_ROM.h这个头文件

  • 定义全局宏 #define LIB_FLASH_BASE_ADDRESSS   0x50000  BLE所有函数从这个地址开始

  • startup_CH573.S文件将mstatus寄存器改为0x1888(默认是0x88),MPP=3,RISC-V内核一直保持机器模式

  • startup_CH573.S文件在mret指令之前增加 j 0x50000指令,startup文件执行完成退出之前先跳转到协议栈开始地址运行

再次编译BLE\Broadcaster工程,生成的hex文件大大减小,使用bootloader将app下载到器件,使用bootloader将CH57xBLE_ROMx.hex下载到设备,协议栈起始地址为0x50000

app和协议栈分别完成下载以后重新运行,实测app无法正常运行,由于协议栈以二进制方式提供,问题排查比较困难。几个疑问:

1)startup_CH573.S将RISC-V内核设置为机器模式,请问协议栈运行是否强制要求机器模式?

2)用户的startup_CH573.S文件在mret之前通过j 0x50000命令跳转到了协议栈,将CPU控制权交给了协议栈,并且没有保存返回地址,协议栈是如何将控制权交还给用户程序的?

感谢回复。

不要在Broadcaster例程原有的Link.ldstartup_CH573.S中修改,把工程中的Ld文件夹,Stratup文件夹移除,拷贝WCH提供的SDK中EVT>EXAM>BLE>OnlyUpdateApp_Peripheral工程里的LD文件夹和Startup文件夹到Broadcaster工程里,按照你上面的修改即可。

机器模式并不是必须的,OnlyUpdateApp_Peripheral例程也是使用的0x88。



还是我来给个更清晰的回答吧:

APP和协议栈分离以后,预留给了协议栈4kB空间,0x20003800-0x200047FF,用户app中的gp寄存器应该避开这个空间,解决方法是修改Link.ld文件

  • 在Link.ld文件中修改__global_pointer$地址,大约141行,PROVIDE( __global_pointer$ = . + 0x800 );改为PROVIDE( __global_pointer$ = 0x20004800 );

这是个明显的坑,没见到之前有地方提到,希望给其他朋友有个参考,正文移植步骤需要加上这一条。


只有登录才能回复,可以选择微信账号登录