0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

安芯教育科技 来源: 安德鲁的设计笔记本 2024-07-15 09:24 次阅读

Introduction

Pricinple & Machenism

HA01的内存地址空间

BOOT ROM简介

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 ROM中bootloader的运行机制,以及用户程序与之对接的设计要点。

Pricinple & Machenism

HA01的内存地址空间

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

49d07218-40ac-11ef-b8af-92fbcf53809c.png

图x HA01的内存地址空间

在Arm Cortex-M7架构中,ITCM是专门用来存放程序指令(Instruction),DTCM是专门用来存放数据(Data),至于OCRAM,就对应于普通的SRAM。如果按照以往Arm Cortex-M架构中只区分flash和SRAM的用法,DTCM和OCRAM都可以当做是SRAM使用,所以用户在常规用例的linker文件中,也可以把DTCM和OCRAM连续的地址空间都当做SRAM使用。但实际上,ITCM和DTCM都是TCM(Tightly Coupled Memories)存储器,分别通过I-TCM和D-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 bootloader或OTA)进行认证,这个过程中,利用硬件的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过程中启用或者停用看门狗,以及对应的超时周期(HA01的WDG在默认情况下,使用来自于IPC的SIRC/4作为计数时钟源)

BOOT ROM中的Bootloader执行过程

在HA01的RM手册中,可以找到bootloader执行过程的示意图。如图x所示。

49fbddd6-40ac-11ef-b8af-92fbcf53809c.png

4a2bd842-40ac-11ef-b8af-92fbcf53809c.png

图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所示。

4a56de8e-40ac-11ef-b8af-92fbcf53809c.png

图x 描述BVT的字段信息

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

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

4a7a925c-40ac-11ef-b8af-92fbcf53809c.png

图x Boot Configuration Word的字段描述

这里提供了一个信息,运行bootloader程序使用了FIRC(96MHz)作为时钟源,但可以通过CPDIVS设置1分频或者2分频。

这里还设计了很多功能的开关,例如看门狗、6个核心的独立使能开关,SCST自检功能。

这里还提到了serial security boot mode和normal boot mode,猜测前者可能就是验签的计算过程。

Practice

源码中关于BVT的设计

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

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

...
#defineBVT_HEADER_SEG__attribute__((used))__attribute__((section(".bvt_header")))
...

/*!
*@brieftheBVTstructuretypedefinition
*
*Implements:bvt_header_config_t_Class
*/
typedefstruct{
uint32_tbvt_marker;/*BVTmarker*/
uint32_tboot_config_word;/*Bootconfigurationword*/
uint32_tsbt_config_group_addr;/*securebootstartaddress*/
uint32_tlc_config;/*lifecycleconfiguration*/
uint32_tcm7_0_main_app_addr;/*CM7_0maincorestartaddress*/
uint32_tcm7_0_secondary_app_addr;/*ReservedforCM7_0_SECONDARY_APP_ADDR*/
uint32_tcm7_1_main_app_addr;/*ReservedforCM7_1_MAIN_APP_ADDR*/
uint32_tcm7_1_secondary_app_addr;/*ReservedforCM7_1_SECONDARY_APP_ADDR*/
uint32_tcm7_2_main_app_addr;/*ReservedforCM7_2_MAIN_APP_ADDR*/
uint32_tcm7_2_secondary_app_addr;/*ReservedforCM7_2_SECONDARY_APP_ADDR*/
uint32_tapp_wdg_timeout;/*timeoutsetoftheWDGwatchdogoftheapplicationcore*/
}bvt_header_config_t;

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

#defineBOOT_CONFIG_WORD(BVT_BCW_CPDIVS_SET(1)|CM7_0_M_EN)

/*definethetimeoutofADGwatchdogoftheapplicationmaincore*/
#defineAPP_WDG_TIMEOUT(120000)/*10msrespectto12MHzSIRCasreferenceclock*/
/*Flasherasedstatus*/
#defineRESERVED(0xFFFFFFFF)
/*BVTHeaderconfiguration*/
constbvt_header_config_tbvt_headerBVT_HEADER_SEG={
BVT_VALID_MARK,/*BVTmarker*/
BOOT_CONFIG_WORD,/*Bootconfigurationword*/
(uint32_t)&secure_boot_group,/*securebootstartaddress*/
RESERVED,/*lifecycleconfiguration*/
DEFAULT_START_ADDRESS,/*CM7maincorestartaddress*/
RESERVED,
RESERVED,
RESERVED,
RESERVED,
RESERVED,
APP_WDG_TIMEOUT,/*timeoutsetoftheWDGwatchdogoftheapplicationcore*/
};

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

/*BVTvalidmarker*/
#defineBVT_VALID_MARK(0xA55AA55A)

/*Defaultstartaddress*/
#defineDEFAULT_START_ADDRESS(0x02000800)

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

#definem_bvt_start0x02000000
#definem_bvt_end0x020007FF
#definem_bvt_sizem_bvt_end-m_bvt_start+1

#definem_interrupts_start0x02000800
#definem_interrupts_size0x00000400

。。。

LR_m_textm_bvt_start
{;loadregionsize_region
ER_m_text_2m_bvt_startFIXEDm_bvt_size
{
.ANY(.bvt_header)
.ANY(.sb_config_group)
.ANY(.sb_config_section)
.ANY(.sb_cmac)
}

//vectors.
VECTOR_ROMm_interrupts_startFIXEDm_interrupts_size
{
*(RESET+First)
}

//code.
ER_m_textm_text_startFIXEDm_text_size
{
*(InRoot$$Sections)
.ANY(+RO)
}
。。。

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

4ab6b8ae-40ac-11ef-b8af-92fbcf53809c.png

图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。

4adeb872-40ac-11ef-b8af-92fbcf53809c.png

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

4b0401c2-40ac-11ef-b8af-92fbcf53809c.png

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 微控制器
    +关注

    关注

    48

    文章

    7311

    浏览量

    149785
  • 处理器
    +关注

    关注

    68

    文章

    18875

    浏览量

    226803
  • 内核
    +关注

    关注

    3

    文章

    1336

    浏览量

    40060

原文标题:YTM32的HA系列微控制器启动过程详解

文章出处:【微信号:Ithingedu,微信公众号:安芯教育科技】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    详解STM32启动过程

    本章教程主要跟大家讲STM32H7的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的部分。
    发表于 11-14 11:24 1750次阅读

    YTM32的LIN通信协议引擎LinFlexD外设模块详解

    YTM32微控制器的LINFlexD外设模块,实现了LIN协议控制器的功能,可以支持LIN总线协议的主机和从机功能。
    的头像 发表于 10-08 11:15 1556次阅读
    <b class='flag-5'>YTM32</b>的LIN通信协议引擎LinFlexD外设模块<b class='flag-5'>详解</b>

    YTM32的模数转换ADC外设模块详解

    YTM32的ADC转换外设最多可以集成32个输入通道,最高12b转换精度,最快可以支持2M Sps的12b采样。
    的头像 发表于 10-09 16:35 1562次阅读
    <b class='flag-5'>YTM32</b>的模数转换<b class='flag-5'>器</b>ADC外设模块<b class='flag-5'>详解</b>

    YTM32的增强型定时eTMR外设模块简介

    YTM32微控制器上集成的eTMR模块,是一个定时外设,下辖多至8个通道
    的头像 发表于 10-31 14:18 930次阅读
    <b class='flag-5'>YTM32</b>的增强型定时<b class='flag-5'>器</b>eTMR外设模块简介

    s3c2440启动过程详解

    s3c2440启动过程详解
    发表于 08-20 18:30

    讲STM32H7的启动过程

    第13章 STM32H7启动过程详解本章教程主要跟大家讲STM32H7的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的
    发表于 08-03 06:15

    STM32F429启动过程详解

    第13章 STM32F429启动过程详解本章教程主要跟大家讲STM32F429的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入
    发表于 08-03 06:15

    STM32H7启动过程详解

    第13章 STM32H7启动过程详解本章教程主要跟大家讲STM32H7的启动过程,这里的启动过程是指从CPU上电复位执行第1条指令开始(汇编文件)到进入C程序main()函数入口之间的
    发表于 08-03 06:41

    Linux启动过程详解

    1、Linux 基础安装Linux操作系统 Linux文件系统 Linux常用命令 Linux启动过程详解 熟悉Linux服务能够独立安装Linux操作系统 能够熟练使用Linux系统的基本命
    发表于 11-02 07:01

    Windows XP 启动过程详解

    我们每天都在和 Windows 打交道,很多人可能每天都要面对多次 Windows 的启动过程,可是您知道在 Windows 的启动过程背后,隐藏着什么秘密吗?在这一系列过程中都用到了
    发表于 11-10 18:24 11次下载

    Linux基础命令之Linux启动过程详解

    2.2 Linux启动过程详解 在了解了Linux的常见命令之后,下面详细讲解Linux的启动过程。Linux的启动过程包含了Linux工作原理的精髓,而且在嵌入式开发
    发表于 10-18 14:17 2次下载
    Linux基础命令之Linux<b class='flag-5'>启动过程</b><b class='flag-5'>详解</b>

    详解bootloader的执行流程与ARM Linux启动过程分析

    RM Linux启动过程分析是本文要介绍的内容,嵌入式 Linux 的可移植性使得我们可以在各种电子产品上看到它的身影。对于不同体系结构的处理来说Linux的启动过程也有所不同。 本文以
    的头像 发表于 12-21 09:24 1w次阅读
    <b class='flag-5'>详解</b>bootloader的执行流程与ARM Linux<b class='flag-5'>启动过程</b>分析

    stm32启动过程

    一次性搞定stm32启动模式与启动过程一、stm32启动模式二、从flash启动过程2.1 数据在堆栈中存储方式2.2 stm32的正常启动过程
    发表于 12-16 16:57 8次下载
    stm32<b class='flag-5'>启动过程</b>

    RL78启动过程详解

    RL78启动过程详解
    的头像 发表于 09-28 16:39 1185次阅读
    RL78<b class='flag-5'>启动过程</b><b class='flag-5'>详解</b>

    stm32启动过程详解

    STM32启动过程详解 近年来,STM32微控制器在嵌入式系统中的应用越来越广泛。STM32微控制器具有高性能、低功耗、易扩展和丰富的外设接口等优势。而要让STM32
    的头像 发表于 12-08 15:47 1137次阅读