摘要:引导程序的开发是系统芯片设计的重要组成部分。针对基于8051核的某控制系统芯片的具体要求,提出了一种系统芯片引导程序的设计策略。该策略思路是:当系统上电复位后,开始执行固化在系统芯片中的引导程序,并加载存储于片外串行接口Flash的用户程序到片内SRAM中;加载完成后,程序无条件跳到SRAM中执行用户程序。在分析该系统芯片组成的基础上,重点阐述了引导程序开发面临的问题、解决的思路、引导程序的具体实现及开发编译环境的配置。该方案对其它系统芯片引导程序的设计具有一定的参考价值。
1 引言
随着IC设计与制造技术的发展,芯片的设计规模越来越大,SoC已经成为主流的设计。软硬件协同工作是SoC的一个重要特征[2]。在SoC设计软件中,引导程序又是重要组成部分。引导程序是系统加电后运行的段软件代码。由于SoC的系统资源有限,为了节省成本,引导程序往往固化在片内ROM中。SoC引导程序的设计是SoC设计过程的难点之一,SoC的用户程序能否正确加载和其运行环境能否正确构建要取决于引导程序能否正确的工作。
本文结合基于8051核的某控制SoC的硬件构架,提出了一种系统芯片引导程序的设计策略,阐述了设计时应考虑的因素和解决的思路,给出了具体的设计实现和仿真结果。
2 系统组成
某控制SoC 采用8 位8051 核为。该8051 核指令和MCS-51 兼容、且提供了指令地址空间可擦写功能。8051 核具有三种地址空间:XDATA 地址空间、IDATA 地址空间、SFR 地址空间,并对应三条总线。SoC 硬件结构如图1 所示,包括用户专用的IP 模块、存储器模块、通用接口模块、AD 及运放等;其中片内ROM 为1K 字节,程序和数据SRAM 为8 KB(XDATA地址空间),ROM 和SRAM 共同占用8051 CPU 的连续地址空间,片内数据SRAM 为256 B(IDATA地址空间)。
SPI 模块与片外串行Flash 基于SPI 协议进行通信。SPI 模块主要有三个寄存器:控制寄存器(SPCON),状态寄存器(SPSTA),数据寄存器(SPDAT)。图2 是SPI 模块与片外Flash的接口示意图,其中FLASH_SI 为串行数据输入、FLASH_SDOUT 为串行数据输出、FLASH_SCLK为串行时钟,FLASH_CS 为片选(低有效)。
3 存在的问题
SoC 的加载过程如下:1)上电后,时钟管理模块产生片内需要的时钟和复位信号;2)复位后,CPU 执行ROM 中的bootloader 引导程序,通过SPI 口将外部Flash 中的用户程序加载到片内8KB SRAM 中;3)加载完成后,程序指针无条件跳转到片内8 KBSRAM 起始地址处。
对于整个SoC 来说,里面的代码包括两个部分:引导程序(采用ROM 设计)、用户程序(采用SRAM 设计)。SoC 的引导程序基本设计原则是在满足系统要求的前提下,用户在后续开发过程之中尽量不受引导程序的影响。引导程序主要的功能是进行用户程序加载、部分硬件初始化。引导程序一旦设计好就无法修改,用户程序是结合SoC 应用环境而随时改变的。
引导程序和用户程序都是针对8051 核而言的。在一般情况下,所有的代码是同一个main程序下的不同模块,二者之间有着不可分割的联系。引导程序是确定的,用户程序是不确定的,因此每次编译,编译器都会对代码重新定位、变量重新分配、堆栈重新设置、中断程序重新定位。另外,系统芯片的复位既可以采用外部进行冷复位,也可以采用内部看门狗(WATCHDOG)进行热复位,二者为“或”的关系。SoC 应用系统要求Watchdog 复位时避免重新加载,因此在引导程序必须能够记忆系统的冷热复位情况。
4 引导程序设计
为了解决ROM 代码的确定性和将来用户程序不确定性的矛盾,的方法是割断引导程序和用户程序之间的联系。在该控制SoC 设计中,引导程序的设计思路是:
1)将引导程序设计为一个独立的主程序,但这个独立的主程序的一条语句不是平常的程序返回语句“RET”,而是一条跳转语句,从而在完成加载后将程序跳转到用户程序的首地址。用户程序的首地址定义为SRAM 的首地址。
2)在引导程序中建立中断映射表,用户开发程序时需要将中断入口地址重新映射,而不是采用通常8051 核的中断入口地址。SoC 用户程序的中断地址由8051 核中断地址加上ROM的地址偏移(0x400h)。
3)为了避免系统芯片热复位时用户程序重新加载,在片内256 B SRAM 中设置了两个加载完毕的标志位。引导程序开始加载用户程序前,首先对加载标志位进行判断,芯片是冷复位时则进行加载,为热复位时则直接跳到用户空间执行用户程序。当需要加载时,则进一步读取Flash 中程序大小的数据,然后加载相应大小的用户程序。
4)对用户程序进行编译、连接后,生成二进制代码或HEX 文件,进一步统计出用户程序的大小。片外Flash 中存储的是用户程序和其它数据,我们定义Flash 第零页的第零及个数据存放用户程序大小的数值,其中高位放在第零地址。在随后的地址内按顺序存放用户程序数据。
因此,引导程序须完成的主要功能如下:
1)建立中断向量表:SoC 在加电复位后,程序0 地址开始执行。当中断发生时,必须无条件跳转到用户中断程序空间。
2)初始化部分硬件环境并加载用户程序:SoC 启动后要从片外Flash 加载程序,因此必须对SPI 模块进行初始化;初始化结束后按照约定的协议格式进行程序加载。
3)记忆冷热复位:判断冷热复位;当热复位时不进行程序加载。
Bootloader 的主要代码实现如下(采用SDCC 编译器进行编译):
/*中断向量表,用于处理异常情况。在异常向量处放置无条件跳转指令,使程序进入相
应的异常处理过程*/
void isr0 (void) interrupt 0 using 0 _naked
{_asm
LJMP 0x0403
_endasm;}
void isr1 (void) interrupt 1 using 0 _naked
{ _asm
LJMP 0x040B
_endasm;}
……
void main(void)
{xdata uchar *data xcode;
……
/*定义冷热复位标志位,并固定其地址空间*/
idata at 0xff unsigned char reset_flag;
idata at 0xfe unsigned char reset_flag2;
/*初始化SPI 模块*/
SPCON=0x72;
/*冷热复位判断*/
if((reset_flag!=0x83)&&(reset_flag2!=0xeb))
{ /*读取用户程序大小的数据*/
……
/*程序加载*/
for(i = 0x400;i<= size.psize;i=i+1 )
{ SPDAT = 0;
while((SPSTA&0x80)==0);
xcode = (xdata uchar *data)(i);
*xcode = SPDAT; }
…… }
/*置加载成功标志*/
reset_flag = 0x83 ;
reset_flag2 = 0xeb
/*跳转到用户程序空间*/
_asm
LJMP 0x0400
_endasm; }
图3 是引导程序的软硬件协同仿真波形(采用Modelsim 软件)。其中用户程序功能是:先通过UART 发送程序执行标志(“wdt start”),接着使能看门狗(启动热复位),然后等待系统重新启动。仿真波形显示,用户程序被系统上电复位后,引导程序首先将执行对片外用户程序的加载(片选信号FLASH_CS 将被拉低,FLASH_SI 引脚出现串行数据,FLASH_SCLK出现时钟);接着开始执行用户程序,并通过UART 口输出了程序执行标志(“wdt start”),并使能了WATCHDOG(WDT_ACTIVE 有效);然后芯片被WATCHDOG 进行了热复位(WDT_RST 出现有效复位脉冲),但热复位过程并没有启动用户程序加载过程。仿真结果表明,引导程序能够从片外串口Flash 中进行程序加载,并能够记忆冷热复位。
5 开发环境设置
为了使得用户程序能否正确的运行,用户程序编译时必须在开发环境上做一些设置。主要是三个方面:
1)设置程序和数据存储空间:用户代码的条指令地址为0x400。程序和数据存储空间公用一个物理空间(地址范围:0x400-0x23FF),用户程序需要将其分成两个连续的空间,低地址空间为程序存储器,高地址空间为数据存储器;但两者空间范围不能够交叉。
2)中断映射:控制SoC 芯片的中断空间需要重新进行映射。在KEIL C51 可设置如图4所示。
3)内部数据SRAM 大小空间设定:内部数据SRAM(IDATA 地址空间)为256 个,引导程序已经使用了0xFE、0xFF 两个地址空间,所以留给用户程序使用空间的大小为254 个。
6 结束语
SoC的引导程序是与具体的硬件环境紧密联系在一起,针对某个SoC芯片编写引导程序,必须了解该SoC结构、片上资源及用户的具体要求。本文给出的引导代码已经在基于8051核的某控制SoC得到具体实现,系统运行稳定,完全实现了设计目的。
本文创新点:提出一种基于8051 核SoC 的引导程序的设计方法,该方法能够从片外串行Flash 加载程序,并解决了中断向量重新映射、系统冷热复位等问题。该方法对其它基于8051 核设计的SoC 中具有一定的参考价值。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。