YTM32的HA系列微控制器启动过程详解

news2024/12/27 11:53:02

YTM32的HA系列微控制器启动过程详解

文章目录

  • YTM32的HA系列微控制器启动过程详解
    • Introduction
    • Pricinple & Machenism
      • HA01的内存地址空间
      • BOOT ROM简介
        • 安全启动Security Boot
        • 快速从Powerdown模式下唤醒
        • 对内核进行例行自检(Structural Core Self-Test,SCST)
        • 配置系统时钟和看门狗
      • BOOT ROM中的Bootloader执行过程
      • BVT的数据结构
    • Practice
      • 源码中关于BVT的设计
      • 在集成开发环境中调试
    • Conclusion
    • Reference

Introduction

HA系列微控制器基于Arm Cortex-M7处理器内核,集成了Security Boot的功能。Security Boot的关键代码集成在BOOT ROM中的bootloader程序中,用户不可见,以确保信息安全的需要。然而,开发者在自行编译固件时,需要配合BOOT ROM中的bootloader,才能正常地引导到用户应用程序,完成启动过程。

本文以HA系列的YTM32B1HA01微控制器(下文简称HA01)为例,将详细介绍BOOT ROMbootloader的运行机制,以及用户程序与之对接的设计要点。

Pricinple & Machenism

HA01的内存地址空间

从RM手册中可以找到HA01的内存地址空间映射表,如图x所示。从表中可以看到,0x0000_0000开始的地址区是一块ITCM存储器(RAM),而存放用户程序的pflash则被安排在0x0200_0000开始的地址区间。在0x0100_0000地址开始的内存空间中,安排了一块ROM。按照芯片内部的硬件设计,芯片上电复位对硬件电路做好初始化后,先进入ROM执行预烧录的bootloader程序,进一步引导至用户应用程序。

在这里插入图片描述

图x HA01的内存地址空间

Arm Cortex-M7架构中,ITCM是专门用来存放程序指令(Instruction),DTCM是专门用来存放数据(Data),至于OCRAM,就对应于普通的SRAM。如果按照以往Arm Cortex-M架构中只区分flashSRAM的用法,DTCMOCRAM都可以当做是SRAM使用,所以用户在常规用例的linker文件中,也可以把DTCMOCRAM连续的地址空间都当做SRAM使用。但实际上,ITCMDTCM都是TCM(Tightly Coupled Memories)存储器,分别通过I-TCMD-TCM总线访问,是等同于Cache存储器的角色,直接同Arm Cortex-M7内核相连,而不同于OCRAM(或者早先Arm Cortex-M架构中的RAM)是通过总线(AXI总线)间接同Arm Cortex-M7内核连通。如此,一般情况下,若没有Cache加持,Cortex-M7内核访问TCM的效率要高于访问OCRAM

对这些不同同种类的内存,可以根据需要灵活配置,以获得最优的访问效率。一种典型的用法:

  • ITCM中存放中断向量表。这也是为什么把ITCM安排到0x0000_0000地址的原因。但需要在执行到pflash中的用户程序之后,由用户程序将存放在pflash中的中断向量表自行搬运到ITCM,然后修改Arm核心的VTOR寄存器重映射到0x0000_0000作为中断向量表的基地址。如果ITCM的空间大于预留的中断向量表占用的空间,剩下的空间用来存放ram code也是不错的。
  • DTCM中存放栈。方便处理器快速地申请和释放。
  • OCRAM中存放堆,以及用户程序中定义的全局变量、缓冲区等。
  • OCRAM可能跟Cache搭配使用,以提高访问效率,但如果处理器内核和DMA进行数据同步,Cache机制可能会引入一些麻烦,此时如果不想繁琐地调整Cache的配置,也可以将需要同步的缓冲区安排到DTCM中。

BOOT ROM简介

HA01上集成的BOOT ROM使用了64KB的存储器。芯片复位后,Cortex-M7内核从ROM里的bootloader开始执行引导程序。其中,将解析存放在pflash开始位置的BVT(Boot Vector Table)。这里的bootloader主要用于实现四个功能:

安全启动Security Boot
  • 在信息安全的体系中,Security Boot作为整个安全系统的置信根(Root of Trust),可以使用CMAC授权算法,对用户指定的程序(例如2nd bootloaderOTA)进行认证,这个过程中,利用硬件的HCU外设模块进行计算,其配置信息存放在BVT中。进一步,HCU外设模块使用的密钥,存放在HCU_NVR中,由OEM主机厂或Tier-1预先烧录,用户全程不可见。
  • 如果CMAC验签失败,处理器内核可以继续运行bootloader并引导至用户程序,但HCU将不会导入存放与HCU_NVR中的密钥,一切加密相关的操作将得不到芯片硬件的支持。
快速从Powerdown模式下唤醒
  • 当检测到从Powerdown模式下唤醒而产生的复位,可以跳过Security Boot和内核自检的过程,从而加速启动过程。
  • 可选地启用配置独立的IVT(Interrupt Vector Table)。这需要配合REGFILE中最开始的两个存储字存放配置信息。REGFILE在Powerdown模式下仍能保存数据。
对内核进行例行自检(Structural Core Self-Test,SCST)
  • 这是为了配合实现功能安全等级ASIL-D标准,而进行的运行时测试。
配置系统时钟和看门狗
  • 根据BVT中的配置,在bootlaoder过程中启用或者停用看门狗,以及对应的超时周期(HA01WDG在默认情况下,使用来自于IPCSIRC/4作为计数时钟源)

BOOT ROM中的Bootloader执行过程

HA01的RM手册中,可以找到bootloader执行过程的示意图。如图x所示。
在这里插入图片描述
在这里插入图片描述

图x BOOT ROM中的bootloader运行流程图

从图x中可以看到,芯片从上电启动到用户的main()函数,大体要经历三个阶段:

  • MCU Reset Phase
  • Boot Code Function
  • MCU App run Phase

芯片上电后(POR),根据REGFILE区域中的REG0的配置值,分别进入快速启动流程(Fast Wakeup Boot Mode)或常规启动流程(Normal Boot Mode)。

在快速启动流程中:

  • 解析BVT中预设的参数,以初始化系统时钟。
  • REGFILE->REG1寄存器中获取快速启动流程的应用程序入口地址(同常规启动流程最终引导的应用程序入口地址可能不同)
  • 查看IVT的地址并确保指定IVT的地址空间位于SRAM,后续将在用户自行编写的应用程序初始化阶段存放中断向量表。
  • 跳转到快速启动流程的程序入口
  • 中间过程如果遇到任何异常,都会进入static mode(原地死循环)。

在常规启动流程中:

  • 解析BVT中预设的参数。
  • BVT中配置启用了Security Boot,则执行验签过程。
  • BVT中配置启用了SCST Test,则执行Cortex-M7处理器内核的自检。
  • 根据BVT中的参数,配置看门狗WDG外设模块。
  • 跳转到常规启动流程的程序入口
  • 中间过程如果遇到任何异常,都会进入static mode(原地死循环)。

快速启动流程中不执行Security Boot和SCST Test过程,因此可以缩短启动时间。但注意,快速启动流程的应用程序入口同常规启动的应用程序入口可能不是同一个。

BVT的数据结构

BVT保存了启动过程中的很多关键参数,它本身位于pflash存储区,0x0200_0000开始的一段内存空间,可由用户在编写应用程序时,创建一个结构体,然后在链接过程中将其安排至0x0200_0000地址。BVT的参数占用108个字节,但实际上却需要预留2KB的空间,这是由于pflash的一个sector大小为2KB。用户实际开发过程中,也可以调整linker file,避开0x0200_0000开始的一个sector,如此,可保持最近一次烧写的可用的BVT配置不变。

手册中列写了BVT的字段定义,如图x所示。

在这里插入图片描述

图x 描述BVT的字段信息

从这里可以窥到一个有趣的设计,竟然提到了有CM7_0CM7_1CM7_2三个Cortex-M7处理器核心,并且每个核心有mainsecondary两个核心。从描述上看,这描述的是一对锁步核(lockstep),并且每个核心都可以有独立的应用起始地址(application start address),将来用于全并行地分别执行不同的应用程序。实际上,目前的HA01使用的是一个不可拆开的单锁步核,故只有CM7_0_main可用。可以想见,在后续的产品规划中,可能会出现最多3对锁步核,如果进一步将锁步核拆开,可以设计最多6个独立的Cortex-M7核心。

BVT中0x4偏移地址上的Boot Configuration Word中进一步定义了启动相关的配置项,如图x中的表格所示。

在这里插入图片描述

图x Boot Configuration Word的字段描述
  • 这里提供了一个信息,运行bootloader程序使用了FIRC(96MHz)作为时钟源,但可以通过CPDIVS设置1分频或者2分频。
  • 这里还设计了很多功能的开关,例如看门狗、6个核心的独立使能开关,SCST自检功能。
  • 这里还提到了serial security boot modenormal boot mode,猜测前者可能就是验签的计算过程。

Practice

源码中关于BVT的设计

用户从SDK中导出的样例工程,就有关于对BVT的定义,以及在链接脚本中专门分配的代码段。

hello_world工程为例,其中的secure_boot_YTM32B1HA0.h文件中有关于BVT类型的定义:

...
#define BVT_HEADER_SEG         __attribute__((used)) __attribute__((section (".bvt_header")))
...

/*!
 * @brief the BVT structure type definition
 *
 * Implements : bvt_header_config_t_Class
 */
typedef struct{
    uint32_t bvt_marker;                /* BVT marker */
    uint32_t boot_config_word;          /* Boot configuration word */
    uint32_t sbt_config_group_addr;     /* secure boot start address */
    uint32_t lc_config;                 /* lifecycle configuration */
    uint32_t cm7_0_main_app_addr;       /* CM7_0 main core start address */
    uint32_t cm7_0_secondary_app_addr;  /* Reserved for CM7_0_SECONDARY_APP_ADDR */
    uint32_t cm7_1_main_app_addr;       /* Reserved for CM7_1_MAIN_APP_ADDR */
    uint32_t cm7_1_secondary_app_addr;  /* Reserved for CM7_1_SECONDARY_APP_ADDR */
    uint32_t cm7_2_main_app_addr;       /* Reserved for CM7_2_MAIN_APP_ADDR */
    uint32_t cm7_2_secondary_app_addr;  /* Reserved for CM7_2_SECONDARY_APP_ADDR */
    uint32_t app_wdg_timeout;           /* timeout set of the WDG watchdog of the  application core */
} bvt_header_config_t;

而在secure_boot_YTM32B1HA0.c文件中,有定义具体的结构体实例:

#define BOOT_CONFIG_WORD  (BVT_BCW_CPDIVS_SET(1) | CM7_0_M_EN)

/* define the timeout of ADG watchdog of the application main core */
#define APP_WDG_TIMEOUT  (120000)    /* 10ms respect to 12MHz SIRC as reference clock*/
/* Flash erased status */
#define RESERVED                        ( 0xFFFFFFFF )
/* BVT Header configuration */
const bvt_header_config_t bvt_header BVT_HEADER_SEG = {
    BVT_VALID_MARK,                 /* BVT marker */
    BOOT_CONFIG_WORD,               /* Boot configuration word */
    (uint32_t)&secure_boot_group,   /* secure boot start address */
    RESERVED,                       /* lifecycle configuration */
    DEFAULT_START_ADDRESS,          /* CM7 main core start address */
    RESERVED,
    RESERVED,
    RESERVED,
    RESERVED,
    RESERVED,
    APP_WDG_TIMEOUT,                /* timeout set of the WDG watchdog of the  application core */
};

此处注意,定义的bvt_header结构体将位于BVT_HEADER_SEG数据段内。其中DEFAULT_START_ADDRESS定义了同应用软件约定的启动地址,具体位于0x0200_0800。位于secure_boot_YTM32B1HA0.h文件中。

/* BVT valid marker */
#define BVT_VALID_MARK                  ( 0xA55AA55A )

/* Default start address */
#define DEFAULT_START_ADDRESS           ( 0x02000800 )

同时,在YTM32B1HA01_flash.sct文件中,也相应指定了BVT所占用的存储空间(预留在0x0200_00000x0200_07FF,和应用程序的起始地址0x0200_0800

#define m_bvt_start                    0x02000000
#define m_bvt_end                      0x020007FF
#define m_bvt_size                     m_bvt_end - m_bvt_start + 1

#define m_interrupts_start             0x02000800
#define m_interrupts_size              0x00000400

。。。

LR_m_text m_bvt_start
{ ; load region size_region
  ER_m_text_2 m_bvt_start FIXED m_bvt_size
  {
    .ANY (.bvt_header)
    .ANY (.sb_config_group)
    .ANY (.sb_config_section)
    .ANY (.sb_cmac)
  }

  // vectors.
  VECTOR_ROM m_interrupts_start FIXED m_interrupts_size
  {
    *(RESET +First)
  }

  // code.
  ER_m_text m_text_start FIXED m_text_size
  {
    *(InRoot$$Sections)
    .ANY (+RO)
  }
 。。。

当下载程序后,可以在memory的视图中可以看到,0x0200_0000开始的位置,有存放关于BVT的配置信息。如图x所示。

在这里插入图片描述

图x 下载到HA01芯片中的BVT配置数据

在集成开发环境中调试

BOOT ROM + BVT相互配合,在HA01芯片内部实现了一个bootloader,但程序的起始地址也不再是常规默认的0x0000_0000,如此,当在集成开发环境中调试程序时,可能会需要指定一个程序入口点。实际上,bootloader的存在并不影响在载入调试环境时自动将程序断点到main()函数:

  • 在调试环境中,下载程序到芯片后复位,如果不显式地执行入口程序地址,芯片会自动从bootloader开始执行,然后从BVT中取得用户应用程序入口地址后,跳转到用户应用程序。确切地说,是进入到用户程序的Reset_Handler函数,然后进入到main()函数。
  • 大多数集成调试环境,会“智能”地在main()函数开始的位置打一个断点,作为调试程序的开始,等待开发者发起进一步的调试动作。
  • 这类似于以往开发者在有用户自定义的bootloader的环境下开发application

无论是Keil还是IAR,在集成开发环境内部启动调试时,都可以自动执行上述流程至main()函数的断点。但是,当使用Segger Ozone调试可执行文件时,由于默认会显式指定一个入口地址,如果没有合适的配置,默认从0x0000_0000开始,就会出现错误。如图x。

在这里插入图片描述

图x 在ozone中配置程序入口点

在这里插入图片描述

图x 默认配置下载入调试出错

从图x中可以看到,Ozone默认从固件程序的开始,0x0200_0000,读到了初始的PC和SP值,但这里的数据其实是BVT的内容,不是中断向量表的项目。故会报错。

此时,在配置初始载入点时,有几种可行的配置,都可以实现正常调试:

  • Initial PC -> Read from Location -> 0x0100_0004, Initial Stack Pointer -> Read from Location -> 0x0100_0000。这种设置是从BOOT ROM中的bootloader开始启动,然后引导到用户应用程序。
  • Initial PC -> Read from Location -> 0x0200_0804, Initial Stack Pointer -> Read from Location -> 0x0200_0800。这种设置是跳过BOOT ROM中的bootloader启动,直接从用户应用程序启动。
  • Initial PC -> Do not set, Initial Stack Pointer -> Do not set。这种设置是软件工具不要多做,让芯片的硬件机制起作用。此时芯片从BOOT ROM中的bootloader开始启动,然后引导到用户应用程序。

建议使用第三种方式,充分利用硬件机制,确保对芯片有最完整的初始化过程,也是最接近在芯片正常上电启动的运行情况。

Conclusion

YTM32B1HA系列微控制器基于Arm Cortex-M7处理器内核,集成了BOOT ROM,并重新划分了地址空间中的内存分配,这使得芯片上电之后的引导过程和用户应用程序的存放地址发生了一些变化,对应地,使用调试软件工具也需要做相应的适配操作,以避免出现异常的情况。

无论如何,BOOT ROM中的bootloaderBVT的配置,为应用带来了一些新的功能,例如基于硬件计算引擎进行加速和加密的安全启动过程、对多核心运行的管理等等。这为支持复杂的片上系统的奠定了一定的基础,也是设计多核心SoC的启动过程的一种可行的尝试。

Reference

  • YTM32B1HA0x_RM_v1.1.pdf
    https://yt-sdk.oss-accelerate.aliyuncs.com/YTM32B1HA0/document/Reference%20Manuals/YTM32B1HA0x_RM_v1.1.pdf
  • 强大CORTEX M7中TCM
    https://www.nxpic.org.cn/module/forum/thread-600826-1-1.html
  • 了解i.MXRT1xxx系列里负责动态分配ITCM/DTCM/OCRAM大小的FlexRAM模块
    https://www.cnblogs.com/henjay724/p/12098657.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1883371.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python容器 之 字符串--下标和切片

1.下标(索引) 一次获取容器中的一个数据 1, 下标(索引), 是数据在容器(字符串, 列表, 元组)中的位置, 编号 2, 一般来说,使用的是正数下标, 从 0 开始 3, 作用: 可以通过下标来获取具体位置的数据. 4, 语法: 容器[下标] 5, Python 中是支持…

SuperMap GIS基础产品FAQ集锦(20240701)

一、SuperMap iDesktopX 问题1:对于数据提供方提供的osgb格式的数据,如何只让他生成一个s3mb文件呢?我用倾斜入库的方式会生成好多个s3mb缓存文件 11.1.1 【解决办法】不能控制入库后只生成一个s3mb文件;可以在倾斜入库的时候设…

基于Java实现图像浏览器的设计与实现

图像浏览器的设计与实现 前言一、需求分析选题意义应用意义功能需求关键技术系统用例图设计JPG系统用例图图片查看系统用例图 二、概要设计JPG.javaPicture.java 三、详细设计类图JPG.java UML类图picture.java UML类图 界面设计JPG.javapicture.java 四、源代码JPG.javapictur…

Leetcode.1735 生成乘积数组的方案数

题目链接 Leetcode.1735 生成乘积数组的方案数 rating : 2500 题目描述 给你一个二维整数数组 q u e r i e s queries queries ,其中 q u e r i e s [ i ] [ n i , k i ] queries[i] [n_i, k_i] queries[i][ni​,ki​] 。第 i i i 个查询 q u e r i e s [ i …

Esxi硬件日志告警

原创作者:运维工程师 谢晋 Esxi硬件日志告警 故障描述故障处理 故障描述 主机报错硬件对象状态告警 在Esxi监控硬件内发现Systemctl Manager Module 1 Event log 0报警,该报警是Esxi事件日志保存空间满了,需要清理空间。 故障处理 开启…

整除分块的题目

链接 思路: 求1到n中的因数个数和等价于求,设x为因子,就是求x在1到n里出现了几次,求1到n里是x的倍数的数有几个,即n/x。需要用整除分块,n/i的值是分块分部的,右端点是n/(n/i)。 代…

相机网线RJ45连接器双端带线5米8芯绿色网线注塑成型

相机网线RJ45连接器双端带线5米8芯绿色网线注塑成型,这款网线采用了环保的绿色材质,线长5米,足够满足大多数拍摄场景的需求。更重要的是,它采用了8芯设计,保证了数据传输的稳定性和高速性。在接口方面,它采…

转转回收的持久层架构演进

1 前言 我们在大部分开发场景下,对持久层的建设基于单库单表其实就可以实现当前的产品需求。但是随着业务发展越来越久,数据量、请求量也在不断的增加,只是单库单表可能不足以支撑系统的稳定运行,本文主要给大家分享一下笔者在项…

mac安装达梦数据库

参考:mac安装达梦数据库​​​​​​ 实践如下: 1、下载达梦Docker镜像文件 同参考链接 2、导入镜像 镜像可以随便放在某个目录,相当于安装包,导入后就没有作用了。 查找达梦镜像名称:dm8_20240613_rev229704_x86…

EHS管理系统避坑指南!这几个关键点需要注意!

在企业管理中,环境、健康和安全(EHS)占据着举足轻重的地位,而EHS管理系统则是推动EHS管理走向高效与规范的核心工具。因此,选择一个与企业需求相契合的EHS管理系统,对于维护员工健康、保护环境安全以及提升…

C#——Property属性详情

属性 属性(Property)是类(class)、结构体(structure)和接口(interface)的成员,类或结构体中的成员变量称为字段,属性是字段的扩展,使用访问器&am…

算法实验2.2、2.3

2.2主要内容 比较快速排序&#xff0c;归并排序以及堆排序算法的时间效率。了解影响算法执行时间的 主要因素以及如何降低算法的执行时间。 #include<iostream> using namespace std; #include<stdio.h> #include<malloc.h> #include<stdlib.h> #inc…

Gradle学习-4 创建二进制插件工程

二进制插件工程创建有两种方式&#xff1a; 创建独立的工程&#xff0c;调试的时候&#xff0c;需要手动发布成一个二进制插件jar包&#xff0c;给其他工程里面引用&#xff0c;进行功能测试。这种方式是比较麻烦的。创建buildSrc子工程&#xff0c;它是一个大工程中的子工程&…

C语言之线程的学习

线程属于某一个进程 共同点&#xff1a;都能并发 线程共享变量&#xff0c;进程不共享。 多线程任务中&#xff0c;其中某一个线程调用了exit了&#xff0c;其他线程会跟着一起退出 如果是特定的线程就调用pthread_exit 失败返回的是错误号 下面也是

基于JSP技术的校园餐厅管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对校园餐厅管理系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。我的联系方式在文末&#xff0c;期待与您交流&#xff01; 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#x…

Redis 中的通用命令(命令的返回值、复杂度、注意事项及操作演示)

Redis 中的通用命令(高频率操作) 文章目录 Redis 中的通用命令(高频率操作)Redis 的数据类型redis-cli 命令Keys 命令Exists 命令Expire 命令Ttl 命令Type命令 Redis 的数据类型 Redis 支持多种数据类型&#xff0c;整体来说&#xff0c;Redis 是一个键值对结构的&#xff0c;…

深入解析 androidx.databinding.Bindable 注解

在现代 Android 开发中&#xff0c;数据绑定 (Data Binding) 是一个非常重要的技术。它使得我们能够简化 UI 和业务逻辑之间的连接&#xff0c;从而提高代码的可读性和维护性。在数据绑定中&#xff0c;Bindable 注解是一个关键部分&#xff0c;它帮助我们实现双向数据绑定和自…

什么是脏读、幻读、不可重复读

数据库事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作&#xff0c;这些操作要么全部成功执行&#xff0c;要么全部失败回滚&#xff0c;以保持数据库的一致性和完整性。在多线程或多用户同时操作时&#xff0c;难免会出现错乱与冲突&#xff0c;这就需要引入事务的…

零成本、高效率:免费可视化工具的魅力所在

在如今这个数据驱动的时代&#xff0c;免费可视化工具越来越受到人们的欢迎。这些工具不仅降低了数据分析的门槛&#xff0c;还为用户提供了强大的功能和极高的灵活性&#xff0c;使得各行各业的人们都能够轻松地利用数据做出明智的决策。首先&#xff0c;免费可视化工具的零成…

SpringBoot学习06-[SpringBoot与AOP、SpringBoot自定义starter]

SpringBoot自定义starter SpringBoot与AOP SpringBoot与AOP 使用AOP实现用户接口访问日志功能 添加AOP场景启动器 <!--添加AOP场景启动器--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</…