APP下载

微控制器的BootROM设计及验证

2022-10-18龚华王一鸣

微处理机 2022年5期
关键词:微控制器特征值命令

龚华,王一鸣

(中国电子科技集团公司第四十七研究所,沈阳 110000)

1 引言

BootROM是嵌入式控制器芯片内的一小块掩膜ROM或写保护闪存,它包含控制器在上电或复位时执行的第一个代码BootLoader。BootLoader是在用户应用程序启动之前运行的一段小程序,通过这段小程序,对硬件设备和软件环境初始化,从而将系统的软硬件环境带到一个合适的工作状态,以便执行某些特定的功能[1-2]。BootLoader的功能一般来说就是用来升级程序、引导系统或操作系统等。如果没有BootLoader,硬件启动成功后,将直接运行用户应用程序;如果有BootLoader,其启动代码(Startup Code)将先被执行,进行一系列的初始化操作后,根据预先设定的条件(如某些引脚的配置),它可以决定从哪里加载要执行的代码的下一部分,是选择执行用户应用程序(Application)或是升级控制程序(Updater),以及如何或是否验证其正确性或有效性。BootROM是微控制器芯片能正常工作的前提,BootROM的设计及验证是整个微控制器芯片设计的关键部分。本研究以一款国产化主流微控制器为例,探讨BootROM的设计与验证。

2 BootROM代码逻辑分析

选用某型国产化微控制器芯片,它是一款自主设计、基于ARM架构的32位微控制器,片上集成10位ADC、10位DAC、定时器、看门狗、USB控制器、以太网MAC控制器、LCD控制器、EMC控制器、SD/MMC存储卡接口,以及UART、CAN、I2C、I2S、SPI、SSP等通信接口。

2.1 基础功能分析

通过分析BootROM binary代码可知,BootROM完成的主要工作包括:在开机时映射为0,实现CRP(代码读取保护),ISP(在系统编程),允许通过UART上传和刷新代码。如果有效的用户代码在FLASH中(需要具有适当的校验和),则将其映射到0并跳转到它。BootROM的一部分仍然映射,以提供IAP(在应用编程)和一些其他服务。

微控制器BootROM binary分为两部分:BOOT_BLOCK(Base Address:0x7FFFE000)和BOOT_FLASH(Base Address:0x7FFEE000)。

BOOT_BLOCK即上电启动的代码入口,是真正意义上的BootROM,整个ISP功能的初始化和交互响应的代码逻辑全部都在BOOT_BLOCK中,而涉及到控制EFSH Controller的部分,则须跳转到BOOT_FLASH执行。

BOOT_FLASH是512kB Embbeded FLASH最高8kB地址块部分(Base Address:0x0007E000,FLASH其余memory部分称为User FLASH),在启动上电初始化EFSH Controller之后,BOOT_FLASH会被映射到高段地址0x7FFEE000,并与BOOT_BLOCK保持0x10000(64kB)的距离。

EFSH Controller初始化完成之后,Embbeded Flash Memory是可直接寻址读访问的[3-4]。读访问FLASH的命令包括:ISP Read Memory命令、ISP/IAP Compare命令、ISP Go命令,都可在BOOT_BLOCK中实现。其他访问FLASH命令有:ISP/IAP Prepare for Write命令、ISP/IAP Copy RAM to FLASH命令、ISP/IAP Erase FLASH Sectors命令、ISP/IAP Blanck Check FLASH Sectors命令,它们则由BOOT_FLASH提供核心的EFSH Controller配置逻辑。

2.2 BOOT_BLOCK代码分布

微控制器在上电或硬件复位时,按MEMMAP寄存器默认为Bootloader mode(0x0)的状态,将BOOT_BLOCK的前64 Byte映射到零地址位(0x00000000)。BOOT_BLOCK或是选择进入ISP/IAP待命状态,或是运行User FLASH零地址上的应用程序,其判断流程如图1所示。

图1 BOOT_BLOCK的Address Map

阻止微控制器进入ISP mode的条件有:CRP的取值,WDT的WDMOD寄存器中bit[2]==1(watchdog time out),以及FIO2[16]==1。依据调试实践可知,JLink连接JTAG口即通过设置FIO2[16]来加载控制逻辑,给BootROM发送IAP命令,实现JTAG下装程序并且启动调试。

JTAG调试还会涉及BOOT_BLOCK中很重要的一部分代码逻辑,统一称为BOOT_BLOCK Real Monitor。Real Monitor的入口函数为固定地址的0x7FFFF90(bb1f90_rm_init_entry),其提供了一个完整的异常中断向量表,并封装了一系列功能单元,通过查询DBGDIDR、修改DBGDRAR/DBGDSAR等,来实现自定义Debug处理流程,如图2所示。

图2 BOOT_FLASH的Address Map

2.3 BOOT_FLASH代码分布

在BOOT_FLASH的最底端有一个直接跳转至BOOT_BLOCK(Address:0x7FFFE000)的保护函数:bf0000_Boot_Flash_Entry()。其作用有两个:

①保护BOOT_BLOCK_ROM内的数据。这些数据标明了微控制器的一系列硬件参数,可以实现一套BOOT_BLOCK源码+指定芯片的BOOT_FLASH_ROM参数+指定芯片的BOOT_FLASH_CODE控制逻辑,支持一系列芯片。当用户程序误跳转至此处,芯片即刻回到启动初始化状态,保护其后数据不会被擦除修改。

②允许某些模式下启动入口为BOOT_FLASH(Address:0x7FFEE000)。虽然MEMMAP寄存器并不支持此地址映射为0,但从BOOT_FLASH跳转回BOOT_BLOCK的方式,允许为其他系列芯片提供了另一个入口选择。

观察BOOT_BLOCK_ROM内的数据,可发现外界通过ISP/IAP查询芯片的特征值,均在此列:

CHIP_ID,BOOT_VERSION,CHIP_VERSION,

SRAM_BASE/SRAM_END,FLASH_SEC_NUM,

FLASH_BASE/FLASH_END,

DEFAULT_EFSH_CLOCK等。

因这些特征值被放置在FLASH High Sector中,研究中尝试生成只携带了BOOT_BLOCK的FPGA Bitfile,发现FPGA EINT0+nRESET复位启动后,并不能正常响应ISP/IAP命令。据分析,原因在于ISP/IAP代码逻辑在获取BOOT_BLOCK_ROM内的数据时,空白Embedded FLASH Memory会导致发生Data Abort Exception异常。依此便可推断:BOOT_BLOCK和BOOT_FLASH一定是同时嵌入芯片中的,任何一块都不能单独工作。

为BOOT_FLASH_ROM预留了176 Byte(0x00 0000B0)的空间,后面的BOOT_FLASH_CODE部分,在最底端放置了两个FLASH Sectors Address数组,数组内Sector个数严格受限于BOOT_BLOCK_ROM内的FLASH_SEC_NUM参数,该值为27(0x1B)。

数组内Sector的上边界也受限于BOOT_BLOCK_ROM内的FLASH_END参数,该值为504kB(0x7D FFF)。在此无法看到有关于BOOT_FLASH本身所在FLASH High Sector的描述。这两个数组及一些Sys IP Config常量值之后,是IAP Commands的处理逻辑。

读写访问Embedded FLASH Memory前都要通过bf025c_check_sectors(start_sector_id,end_sector_id)函数验证参数是有效的FLASH Sector。有效域并不包括FLASH High Sector。结合前述BOOT_FLASH_ROM内的芯片特征值也限定了ISP/IAP命令的查询结果,可得出互为一体的BOOT_BLOCK和BOOT_FLASH完全杜绝了读写访问FLASH High Sector的可能性。

配置FSHC以驱动EFSH Controller开始Erase/Program工作之前,或是切换为Prepare for Write状态之前,都要把写配置EFSH Controller的代码块拷贝到SRAM上,拷贝完成后跳转过去执行。在配置EFSH Controller的过程中,任何读/写访问Embedded Flash Memory的动作都应暂停(包括CPU的prefech行为,Debug时会一直存在)。

3 FlashMagic的ISP控制流

FlashMagic是一款微控制器ISP命令控制的PC端软件。要实现微控制器ISP功能,就需要分析ISP命令格式。

鉴于ISP命令本质上是一系列规则化的串口数据,在研究中通过串口抓包软件AccessPort分析ISP命令及响应的数据格式,可得出FlashMagic ISP命令数据规律。

FlashMagic每完成一组ISP命令动作,都立即关闭串口连接。因此每次发起ISP命令任务前,都要顺次发出两个命令:

命令1:“?”。查询芯片是否已完成Auto-Baudrate并处于Waiting for ISP Command状态。若为真,串口将收到同样的字符“?”,否则需要交互收发数据完成固定的握手过程,如图3所示。

图3 握手过程

命令2:“J ”。查询芯片的型号,将返回BOOT_FLASH_ROM中的特征值CHIP_ID:0x1701FF35,以十进制字符串表示:“386006837 ”。

FlashMagic可将HEX文件下装至User Flash,并正常跳转至下装程序处开始执行,也可以下装到SRAM并正常跳转。下装过程中只占用SRAM共1024Byte的空间做为中转站,即每次把HEX里的有效bin数据以1024Byte为单位预先保存至SRAM(0x40000200~0x400005FF),不足1024Byte的后部补零,然后配置FSHC将SRAM数据存入Embedded FLASH Memory。

FlashMagic发起Verify任务的方式并不是发起ISP Compare命令“M”让芯片硬件去完成比对,而是读取FLASH内容到PC的内存中,再与SRAM上的HEX文件有效bin数据进行比对。当HEX下装到SRAM时,Verify的方式仍然需要读取SRAM的下装内容到PC内存,再与SRAM上的HEX文件有效bin数据进行比对。

FlashMagic的诸如ISP Read、Erase、Program以及Blankcheck FLASH等功能均不支持访问FLASH High Sector。FlashMagic支持通过RS232口的DTR/RTS连线产生Reset信号,不需要手动硬件复位(EI NT0+nRESET)。ISP命令交互过程中的运行地址分布如图4所示。

图4 ISP命令交互过程

4 BootROM设计思路

通过研究主流微控制器的BootROM,综合分析BOOT_BLOCK和BOOT_FLASH代码逻辑,得到最优化的BootROM设计方案为:

保持BOOT_BLOCK基本不变,即上电后进入ISP/IAP;或是运行User Flash Application,由JLink连接Debug Module启动调试,ISP/IAP命令交互等都保持原有的处理逻辑。

保持BOOT_FLASH_ROM基本不变,即芯片特征值保持不变,同时沿用原有杜绝访问FLASH High Sector的思路。

保持BOOT_FLASH_CODE对IAP Command的分发处理流程不变,同时沿用原有拷贝配置FSHC代码至Embedded FLASH Memory之外的做法,拷贝发生的3个节点也保持一致[5-6]。

重新设计BOOT_FLASH_CODE中与FSHC相关的读写访问逻辑,某些行为被精简,如:Prepare for Write。FSHC配置方法与主流微控制器不同,考虑到配置代码量,初始设计时预留了一块Reserved RAM Memory(Base Address:0x7FD04000,Size:0x400,大小可随RTL配置而变动),称为EFSH_OPFUNC_RAM,专为保存拷贝的配置FSHC代码,而不再占用SRAM空间。

更换FSHC后的BootROM,需要芯片在量产封装时便要将BOOT_FLASH数据烧写入FLASH High Sector。传统芯片在出厂时只有BootROM(对应BOOT_BLOCK部分),二级以上BootLoader采用上位机软件编程写入的方式。若要支持出厂后才写入或升级BOOT_FLASH,则首先要保证BOOT_BLOCK可以正常响应ISP/IAP Write-to-RAM命令。而支持Auto-Baudrate和ISP/IAP Read-Chip-ID命令成为前提条件。另外还要支持进入ISP/IAP模式前的系统初始化动作,BOOT_FLASH_ROM中的部分芯片特征值需要拷贝入BOOT_BLOCK中。

在VCS/ASIC仿真环境充分验证FSHC基本功能的基础之上,需要验证IAP Command响应机制以保证JTAG调试可正常运行。在实测FPGA bitfile只有改造后的BOOT_BLOCK而缺失BOOT_FLASH的情况下,JTAG可连接进行SRAM代码调试[7]。鉴于BootROM中已有Real Monitor/ISP/IAP这三大响应机制,此处没有对该机制做出任何修改,而是决定将BootROM整个代码移到SRAM或UserFlash上,增加直接调用IAP Command响应函数的测试代码,形成IAP测试工程,用JTAG进行调试。

在IAP Command响应机制稳定的前提条件下,需要验证ISP Command响应机制以保证FlashMagic编程读写FLASH功能正常。同样,把BootROM整个代码移到SRAM或UserFlash上,采用FlashMagic下装到SRAM,或复位后用JTAG下装到UserFlash,然后通过FlashMagic发出ISP命令完成测试。

在SRAM和UserFlash上测试BootROM代码稳定之后,还需要一个下装或升级BOOT_FLASH的方案。此处仍将BootROM整个代码移到SRAM,打包入BOOT_FLASH_ROM和BOOT_FLASH_CODE两个binary文件并自动生成头文件,描述这两个文件的下装地址、大小和CRC32校验值。增加运行代码对两个bin数组进行CRC32校验,比对正确后,再调用IAP Command响应函数,以1024Byte为单位(若小于512则以512Byte为单位),先拷贝到SRAM对齐位置0x40000200,再拷入Embedded Flash Memory。该工程需要添加FLASH High Sector有效性判断逻辑,支持FlashMagic下装到SRAM并跳转完成升级。

5 BootROM工程验证

5.1 验证IAP Command响应机制

此工程默认BOOT_BLOCK中RealMonitor+IAP response功能完整,直接调用BOOT_FLASH中的IAPCommand分发函数bf01f8_handle_iap_command()进行测试。测试目标有两个:

目标1:IAP_Test SRAM。将代码平移到SRAM测试;

目标2:IAP_Test FLASH。为测试配置FSHC时跳转出FLASH之外执行的情况,将代码平移到User Flash底端0x00000000测试[8]。

5.2 验证ISP Command响应机制

工程有三个测试目标,除BootROM以外,另外两个用于测试ISP Command:

目标1:ISP_Test SRAM。将代码平移到SRAM,使用FlashMagic测试ISP功能;

目标2:ISP_Test FLASH,将代码平移到FLASH,目的在于测试Auto-Baudrate,以及响应ISP Command时,拷贝配置FSHC代码至EFSH_OPFUNC_RAM跳转执行的情况;

目标3:BOOT_BLOCK,逐一测试FlashMagic中的ISP功能,JTAG连接下装axf文件到SRAM,并可设置断点、单步调试、查看FLASH/SRAM Memory等。

5.3 写入/升级BOOT_FLASH功能验证

本工程只运行在SRAM,附加的BOOT_FLASH_ROM和BOOT_FLASH_CODE两个二进制数组放在BootROM整体代码的后面。测试目标BootFlash_ISPUpdate为支持JTAG下装调试和FlashMagic下装跳转执行。通过JLink连接读取SRAM下装内容可正常读出,通过ISP Go命令跳转也能正常运行。

BootFlash_ISPUpdate运行成功后,便可进行完整的ISP以及IAP功能测试来加以验证。

6 结束语

通过该款微控制器BootROM的设计及验证,提供了国产化芯片BootROM设计及验证的一种思路和方法。后续研究中,可在此基础上扩展更多的启动模式,使芯片功能更加丰富,以适应于更加灵活的应用场景。

猜你喜欢

微控制器特征值命令
利用LMedS算法与特征值法的点云平面拟合方法
只听主人的命令
单圈图关联矩阵的特征值
TASKING针对英飞凌第三代AURIX微控制器推出多核开发环境
凯莱图的单特征值
安装和启动Docker
移防命令下达后
用于高品质电动汽车的分布式并行计算
求矩阵特征值的一个简单方法
解析Windows10的内部命令