STM32移植说明

介绍

由于ST官方的STM32CubeMX能自动生成初始化芯片的代码,因此 XWOS中STM32的 架构描述层(ADL)CPU描述层(CDL)SOC描述层(SDL) 的代码几乎 是一致的,唯一区别是 链接脚本

链接脚本

STM32的链接脚本也是按照可复用的方式设计的,分为两部分:

  • SDL中的链接脚本:描述各个段如何分布在镜像文件中
    • STM32F0:XWOS/xwcd/soc/arm/v7m/m0/stm32/f0.lds
    • STM32G0:XWOS/xwcd/soc/arm/v7m/m0p/stm32/g0.lds
    • STM32F1:XWOS/xwcd/soc/arm/v7m/m3/stm32/f1.lds
    • STM32L1:XWOS/xwcd/soc/arm/v7m/m3/stm32/l1.lds
    • STM32F4:XWOS/xwcd/soc/arm/v7m/m4/stm32/f4.lds
    • STM32L4:XWOS/xwcd/soc/arm/v7m/m4/stm32/l4.lds
    • STM32F7:XWOS/xwcd/soc/arm/v7m/m7/stm32/f7.lds
    • STM32H7:XWOS/xwcd/soc/arm/v7m/m7/stm32/h7.lds
    • 其他SOC还在持续增加中…
  • 电路板目录中的链接脚本:只描述内存区域
  • WeActMiniStm32H750工程: XWOS/xwbd/WeActMiniStm32H750/cfg/brd.lds
  • WeActMiniStm32H750Bootloader工程: XWOS/xwbd/WeActMiniStm32H750Bootloader/cfg/brd.lds
  • 其他电路板还在持续增加中…

不同的电路板工程,只有Board中链接脚本中的Memory区域不同。

lds的基本语法

定义存储器区域

名字 (属性): org = xxx, len = xxx
  • o , org , ORIGIN : 表示定义存储器的起始地址
  • l , len , LENGTH : 表示定义存储器长度
  • ORIGIN(x) : 表示取存储器x的起始地址
  • LENGTH(x) : 表示取存储器x的长度
  • 属性: r 表示读, w 表示写, a 表示可申请, x 表示可执行

xxx_ivt_lmr & xxx_ivt_vmr

XWOS的中断向量表区域,其中 LMR 表示中断向量的加载地址区域, 也即是中断向量在Flash中的存储位置,VMR表示中断向量的运行地址区域, 也即是上电运行时的中断向量的地址。

  • 如果 LMRVMR 都指向Flash,且起始地址(org)与大小(len)完全一致,表示加载地址 就是运行地址,XWOS在初始化阶段不会对中断向量执行拷贝操作;
  • 如果 VMR 指向RAM的某个地址,XWOS会在初始化阶段把Flash中的中断向量表拷贝到 VMR 指定的RAM内,并设置ARM的VTOR寄存器;
  • 需要注意ARM的VTOR寄存器低7位(0~6)必须保持为0,因此VMR的起始地址也必须满足 此规则。

firmware_info_mr

此段中包含镜像文件的一些基本信息,例如起始位置,结尾标志位置等,可用在升级固件功能中。

code_mr

存放代码和常量的地方。

xwos_data_mr

存放xwos全局数据的地方,这些变量在定义时带有修饰符: __xwos_data ,此段可以 不存在,若不存在,需要在SDL中的链接脚本中将此段的数据放到 data_mr 中。

data_mr

存放全局变量的地方。当连接器ld安排完全局变量后,剩余的部分会交给XWOS 的默认的内核内存分配器进行管理,用于为动态创建内核对象的API提供动态内存申请的接口。

xwos_stk_mr

XWOS内核的栈内存,XWOS内核处理中断时会使用此内存作为函数的栈。

SOC的初始化

STM32CubeMX生成的初始化代码,分别由 stm32cube_lowlevel_init()stm32cube_init() 执行, 这两个函数在 启动流程中分别 被 xows_preinitxwos_postinit() 调用。

STM32CubeMX

STM32CubeMX工程是以 玄武模块 中的 电路板模块 的方式进行集成的, 详细可参考 构建系统

各个工程的STM32CubeMX工程如下(可在STM32CubeMX中打开):

  • WeActMiniStm32H750工程: XWOS/xwbd/WeActMiniStm32H750/bm/stm32cube/WeActMiniStm32H750.ioc
  • WeActMiniStm32H750Bootloader工程: XWOS/xwbd/WeActMiniStm32H750Bootloader/bm/stm32cube/WeActMiniStm32H750Bootloader.ioc

中断优先级

  • XWOS对中断优先级的要求:
切换上下文的中断为系统中最低优先级中断
切换上下文的中断 <= 滴答定时器的中断 <= 调度器服务中断
  • NVIC设置
    • 设置 3 个抢占优先级位和 1 个子优先级位;
    • SVC中断设置成 最高 优先级,即 Preemption Priority0
    • PendSV中断设置成 最低 优先级,即 Preemption Priority7
    • Systick中断设置成 最低 优先级,即 Preemption Priority7
    • 系统Fault的优先级设置为 0
    • 其他中断的优先级只可在 1~6 之间。

中断向量表

STM32CubeMX生成的代码中断向量表是放在 startup.s 中,XWOS并不使用这个文件,因此需要 另外增加中断向量表。STM32型号太多,一个一个编辑工作量巨大,但观察STM32寄存器定义的 头文件(例如: stm32h750xx.h ),可以发现 IRQn_Type 这个枚举类型,其中列举了 所有的中断号,因此可使用脚本自动生成中断向量表的代码。

本项目中提供了一个Emacs-Lisp脚本 XWOS/xwbd/WeActMiniStm32H750/bm/stm32cube/Tools/stm32ivt/stm32ivt.el 来完成这项工作, 用法:

cd XWOS/xwbd/WeActMiniStm32H750/bm/stm32cube
stm32ivt/stm32ivt.el
  • 脚本执行完成后,会生成 Core/Src/ivt.c

xwac

电路板模块 xwac 是适配性质的代码,是连接BSP与XWOS的纽带。 文件夹名中的 acAdaptation Code 的缩写。

  • fatfs :fatfs底层设备驱动
  • lua :lua的内存池
  • newlib :为标准C库newlib提供底层的支持
    • mem.cmalloc() 系列函数的内存池
    • stdio.c :定义 stdin 的输入设备, stdoutstderr 的输出设备
  • picolibc :为标准C库picolibc提供底层的支持
    • mem.cmalloc() 系列函数的内存池
    • stdio.c :定义 stdin 的输入设备, stdoutstderr 的输出设备
  • xwds :STM32的设备栈
  • xwlib :为XWOS通用库提供底层硬件支持,例如使用硬件CRC模块加速CRC运算、定义Log的输出设备等
  • xwos :XWOS内核的Hook函数
  • xwrust :Rust的内存池