发新帖本帖赏金 50.00元(功能说明)我要提问
返回列表
打印
[活动]

【APM32F411V Tiny Board测评】pyocd加载固件到SRAM并从sram启动

[复制链接]
3780|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 xhackerustc 于 2024-5-6 00:07 编辑

#申请原创#   @21小跑堂

在日常开发调试过程中,如果固件不是很大能放进sram,其实没必要每次都烧写进flash,一来:flash擦除次数是有限的,改点代码就擦除一次而且总擦除flash头部位置肯定影响flash寿命,虽然几次开发调试用用那点擦除次数不至于,但是完美主义者心里总有点不爽;二来:相比加载进sram,烧写flash速度比较慢。所以这时候比较理想的调试方法是:把固件加载进sram并从sram启动,所有功能调试完毕后再改回用flash统一验证一下。这个测评贴就是来展示pyocd如何加载点灯固件到sram并从sram启动。

APM32F411启动选项
APM32F411通过配置boot1和boot0引脚有三种不同的启动选项,其中boot0和boot1引脚都拉高时,是从内置sram启动,这正是笔者需要启动模式。对应到
APM32F411V Tiny board板子上有boot0和boot1跳线, 板子到手默认都是拉低的,改下跳线即可。


link script的改动
如第一篇测评贴所述,笔者是linux爱好者,开发环境是gcc+vim+pyocd+make,所以这里示例仅以gcc的linkscript为例,MDK、IAR等环境略,它们改动原理是一样的。由笔者第一篇测评贴的Makefile可知APM32F411V Tiny Board默认用的link script位于Libraries/Device/Geehy/APM32F4xx/Source/gcc/APM32F4xxxE_FLASH.ld,改动前复制一份并重命名为Libraries/Device/Geehy/APM32F4xx/Source/gcc/APM32F4xxxE_RAM.ld。需要做如下改动:

1.把FLASH和CCMRAM有关的基地址、大小等定义删除
其实不删除也可以,但完美主义者非删不可也防止留着后面section修改不到位仍然有部分数据/代码还在flash上

2.把放在FLASH中的section放进RAM地址空间中
就是把形如下面这样的代码
  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;
  } >FLASH
最后一行”>FLASH"修改成">RAM",比如上面的.text section就修改为:

  .text :
  {
    . = ALIGN(4);
    *(.text)
    *(.text*)
    *(.glue_7)
    *(.glue_7t)
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;
  } >RAM

3.把VMA是RAM地址空间,LMA是FLASH地址空间的section修改成放入RAM地址空间,也即改成VMA和LMA都是RAM地址空间有些section运行时(虚拟)地址(所谓VMA)和加载地址(所谓LMA)并不一致,典型如.data section,在初始化时由初始化代码从flash拷贝到sram中,所以.data section在link script中都是类似这么写的:
  .data :
  {
    . = ALIGN(4);
    _start_address_data = .;
    *(.data)
    *(.data*)

    . = ALIGN(4);
    _end_address_data = .;
  } >RAM AT> FLASH
对于固件全部加载进sram的情形已经不适用,需要改成如下这种写法:
  .data :
  {
    . = ALIGN(4);
    _start_address_data = .;
    *(.data)
    *(.data*)

    . = ALIGN(4);
    _end_address_data = .;
  } >RAM



Makefile的改动
需要在Makefile中修改链接时所用到link scrpt:
diff --git a/Makefile b/Makefile
index 8a222ed..a7b27cf 100644
--- a/Makefile
+++ b/Makefile
@@ -84,7 +84,7 @@ CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# LDFLAGS
#######################################
# link script
-LDSCRIPT = Libraries/Device/Geehy/APM32F4xx/Source/gcc/APM32F4xxxE_FLASH.ld
+LDSCRIPT = Libraries/Device/Geehy/APM32F4xx/Source/gcc/APM32F4xxxE_RAM.ld

# libraries
LIBS = -lc -lm -lnosys


初始化阶段Vector Table重定位
VTOR是在system_apm32f4xx.c中设置的,笔者观察到每个example都有一份system_apm32f4xx.c,比如Examples/GPIO/GPIO_Toggle/Source/system_apm32f4xx.c。修改它比较简单,apm官方考虑到了sram启动,只要enable一行宏定义即可:
diff --git a/Examples/GPIO/GPIO_Toggle/Source/system_apm32f4xx.c b/Examples/GPIO/GPIO_Toggle/Source/system_apm32f4xx.c
index 16b200c..7ddc4b6 100644
--- a/Examples/GPIO/GPIO_Toggle/Source/system_apm32f4xx.c
+++ b/Examples/GPIO/GPIO_Toggle/Source/system_apm32f4xx.c
@@ -43,7 +43,7 @@
/* #define DATA_IN_ExtSRAM */

/* Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */
-/* #define VECT_TAB_SRAM */
+#define VECT_TAB_SRAM^M

/* Vector Table base offset field. This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET  0x00


pyocd加载固件进sram并启动

pyocd cmd -t apm32f411ve
进入pyocd cmd命令行后,打一些命令如图所示


此时板子上led2/led3开始闪烁,串口也开始有期望的打印,说明这次完全从sram启动运行点灯程序了。

使用特权

评论回复

打赏榜单

Gfan 打赏了 50.00 元 2024-07-17
理由:APM32F411V Tiny测评活动优质测评帖

沙发
xhackerustc|  楼主 | 2024-5-6 00:12 | 只看该作者
刚又测试了一下,可以不用改sp和pc寄存器,即只要loadmem然后reset即可

使用特权

评论回复
板凳
[鑫森淼焱垚]| | 2024-5-6 11:21 | 只看该作者
点赞点赞

使用特权

评论回复
发新帖 本帖赏金 50.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

76

帖子

0

粉丝