> 文档中心 > 【MM32F5270开发板试用】一、移植 TencentOS 到 PLUS-F5270

【MM32F5270开发板试用】一、移植 TencentOS 到 PLUS-F5270


本篇文章来自极术社区与灵动组织的MM32F5270开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:Red

感谢有这次机会试用 PLUS-F5270 开发板,我计划在使用这个开发板实现一个 SmartSensor 项目,这个项目我放在了仓库SmartSensor。会逐渐记录开发的进度。
本篇会分为两个部分:

  1. 修改 openocd 支持链接 STAR-MC1 处理器,并提交了一个 pr 正在 reviewtarget/arm: Add support with identify STAR-MC1,在此基础上使用 stm32f1x 的 flash 驱动目前可以烧录程序到芯片的内置 flash
  2. 移植 TOS 到 PLUS-F5270

在 Linux 使用 openocd 链接 PLUS-F5270

如果需要使用 openocd 链接 STAR-MC1,需要打上这个 pr

diff --git a/src/target/cortex_m.c b/src/target/cortex_m.cindex aeaeb1829..1bb37797a 100644--- a/src/target/cortex_m.c+++ b/src/target/cortex_m.c@@ -91,6 +91,12 @@ static const struct cortex_m_part_info cortex_m_parts[] = {  .arch = ARM_ARCH_V8M,  .flags = CORTEX_M_F_HAS_FPV5,     },+    {+ .partno = START_MC1_PARTNO,+ .name = "START-MC1",+ .arch = ARM_ARCH_V8M,+ .flags = CORTEX_M_F_HAS_FPV5,+    },     {  .partno = CORTEX_M35P_PARTNO,  .name = "Cortex-M35P",diff --git a/src/target/cortex_m.h b/src/target/cortex_m.hindex 69368a919..89dfd6669 100644--- a/src/target/cortex_m.h+++ b/src/target/cortex_m.h@@ -44,6 +44,7 @@ enum cortex_m_partno {     CORTEX_M0P_PARTNO  = 0xC60,     CORTEX_M23_PARTNO  = 0xD20,     CORTEX_M33_PARTNO  = 0xD21,+    START_MC1_PARTNO   = 0x132,     CORTEX_M35P_PARTNO = 0xD31,     CORTEX_M55_PARTNO  = 0xD22, };

如果还要通过 openocd 下载程序到 flash, 还需要再打下 patch:

diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.cindex 455a06a9b..8721c1278 100644--- a/src/flash/nor/stm32f1x.c+++ b/src/flash/nor/stm32f1x.c@@ -761,6 +761,7 @@ static int stm32x_get_property_addr(struct target *target, struct stm32x_propert  addr->flash_size = 0x1FFFF7E0;  return ERROR_OK;     case CORTEX_M_PARTNO_INVALID:+    case START_MC1_PARTNO:  /* Check for GD32VF103 with RISC-V CPU */  if (strcmp(target_type_name(target), "riscv") == 0   && target_address_bits(target) == 32) {@@ -771,6 +772,12 @@ static int stm32x_get_property_addr(struct target *target, struct stm32x_propert      addr->flash_size = 0x1FFFF7E0;      return ERROR_OK;  }+ else+ {+     addr->device_id = 0x40007080;+     addr->flash_size = 0x1FFFE920;+     return ERROR_OK;+ }  /* fallthrough */     default:  LOG_ERROR("Cannot identify target as a stm32x");@@ -869,6 +876,7 @@ static int stm32x_probe(struct flash_bank *bank)  stm32x_info->can_load_options = true;  break;     case 0x410: /* stm32f1x medium-density */+    case 0x800: /* mm32f527x medium-density */  page_size = 1024;  stm32x_info->ppage_size = 4;  max_flash_size_in_kb = 128;@@ -882,6 +890,7 @@ static int stm32x_probe(struct flash_bank *bank)     because of unexpected active hardware watchog. */  switch (rev_id) {  case 0x1303: /* gd32f1x0 */+ case 0x4d4d: /* mm32f527x */      stm32x_info->user_data_offset = 16;      stm32x_info->option_offset = 6;      max_flash_size_in_kb = 64;

还有两个 cfg 配置文件板级的 mmplus.cfg:

#adapter listsource [find interface/jlink.cfg]transport select swdadapter speed 100#jink configsource [find mm32f5270.cfg]proc mmd { pos } {    if { $pos == 0 } { reset; halt; flash write_image erase TencentOS_tiny.bin 0x8000000; reset; echo "mmd down firm 2 internal flash success"    } else { echo "mmd down firm 2 spi flash"    }}

和平台级的 mm32f5270.cfg:

source [find target/swj-dp.tcl]#source [find mem_helper.tcl]if { [info exists CHIPNAME] } {set _CHIPNAME $CHIPNAME} else {set _CHIPNAME mm32f5270}set FLASH_SIZE 0x40000# Allow overriding the Flash bank sizeif { [info exists FLASH_SIZE] } {    set _FLASH_SIZE $FLASH_SIZE} else {    # autodetect size    set _FLASH_SIZE 0}# ONLY use ENDIAN with targets that can change it.if { [info exists ENDIAN] } {set _ENDIAN $ENDIAN} else {set _ENDIAN little}if { [info exists CPUTAPID ] } {set _CPUTAPID $CPUTAPID} else {#set _CPUTAPID 0x1be12aebset _CPUTAPID 0x1aeb0015}set _TARGETNAME $_CHIPNAME.cpu#swj_newdap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0xf -ignore-version -expected-id $_CPUTAPIDswj_newdap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPIDdap create $_CHIPNAME.dap -chain-position $_TARGETNAMEtarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap -ap-num 0# 定义一块内存区域用来烧录程序到 flash 临时使用# 定义一块内存区域的起始地址,在 MMU 未开启时使用$_TARGETNAME configure -work-area-phys 0x30000000 -work-area-size 0x4000set _FLASHNAME $_CHIPNAME.flashflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME#flash bank $_FLASHNAME mm32f527x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAMEproc mm32f5270_reset_init {} {    # 配置 PLL 时钟    # mww}$_TARGETNAME configure -event reset-init { mm32f5270_reset_init }cortex_m reset_config sysresetreq#$CHIPNAME init

至此就可以正常连接 STAR-MC1 了

移植 TOS 到 PLUS-F5270

花费了好几天的时间完成了 TOS 在 PLUS-F5270 上的部署,移植过程中发现在执行到函数port_sched_startLDMFD SP!, {R4 - R11}这句话的时候就会进入到 HardFault.经过多番排查,定位到是ARMv8-M指令集的stack limit功能导致的。该功能具体描述是:

官方的代码在 Reset_Handler 中赋值了 msplim 和 psplim 寄存器,所以在线程调度的时候,当使用线程栈指针时,超过了 stack limit 导致系统异常。其中 psplim 是检查 thread mode 的栈指针即 psp,msplim 检查的是 handler mode 的栈指针即 msp。特别地,在异常(handler mode)中一直使用的是 msp,异常一般被当作内核态,在 thread mode 时候,会根据CONTROL.nPRIV determines whether execution in Thread mode is unprivileged确定使用的是特权还是非特权。特权使用的是 msp, 非特权则是 psp 指针。

ldr      r0, =__STACK_LIMITmsr      msplim, r0msr      psplim, r0

为了避免这个问题可以有多种方案:

  1. 关闭 stack limit 检查,CCR, Configuration and Control Register寄存器的 bit 10

修改该 bit 位为 1

  1. 在线程调度过程中更新 psplim,目前我看 RT-Thread 使用的是这种方法,但是这个 psplim 实际一直是 0(所以也可以认为并没有使用硬件进行 stack limit 检查).
  2. 直接设置 msplim 和 psplim 为 0

解决这个问题后,就可以正常运行 TOS 了。有关这部分移植工作,我提交了一个 prAdd support with PLUS-F5270 Board #351