引言
Altera公司为在系统编程(ISP)提供了软件级标准:Jam STAPL JEDEC标准JESD-71[2],它彻底改变了可编程逻辑器件(PLD)的编程和配置。该标准支持当前所有使用JTAG进行在系统编程的可编程逻辑器件。对于嵌入式系统,该标准满足所有的必要条件,例如:文件小、便于操作以及平台独立。
Jam STAPL(标准测试和编程语言)ByteCode Player是一种读取并执行.jbc文件的解释性程序。一个.jbc 文件可包含多种功能,例如,对CPLD 进行编程、配置、验证、擦除以及空白检查等[3]。Jam STAPL Byte-Code Player执行软件可以访问用来执行基于IEEE 1149.1标准的所有指令的IEEE 1149.1信号。执行软件也能够处理.jbc 文件中用户定义的操作和程序。.jbc文件是二进制文件,Jam STAPL Byte-Code Player 执行软件解析.jbc文件描述信息后,将其翻译成设置到目标CPLD中的数据和算法。这个执行软件不针对某一供应商或者器件体系结构进行编程,它只读取并解释Jam STAPL规范定义的语句[3]。
针对这种情况,设计了一种基于STM32的CPLD离线烧写模块。离线CPLD烧写器是针对生产和现场调试等应用场合而设计的一款烧写设备,它的出现可以抛开PC机烧写的固有模式,无需在线JTAG下载器甚至是电源,就可以轻松完成CPLD的烧写功能,从而大大提高生产效率,降低了现场系统升级及调试时对设备和环境的苛刻需求。该模块的成功实现,极大地方便了用户对CPLD的烧写和更新。对厂家而言,生产线上就可以告别笨重的电脑和繁琐的操作,修改和维护已销售产品中的CPLD逻辑,再不需要技术人员背着沉重的笔记本和各种线缆出差,所以其意义非常重大。
1 离线烧写系统设计
CPLD的离线烧写系统由两部分组成:一部分是以嵌入式处理器STM32为核心的硬件平台[4],另一部分是以Jam STAPL ByteCode Player为核心的软件系统。
1.1核心芯片的介绍
本系统所使用的嵌入式处理器是ST公司的产品STM32F103ZET6——基于ARM架构芯片来完成的嵌入式CPLD离线烧写[4]。使用STM32F103ZET6是因为该芯片技术相当成熟,在新的平台上移植非常方便,而且使用其自带的固件库,极大地方便了程序员项目的开发,减少了一些不必要的麻烦。同时,其处理器的速度为72 MHz,足够强大;MCU内部集成的功能单元非常多,简化了系统的设计,增强了系统的稳定性和可靠性[45]。
1.2软件工具
本系统使用的软件开发环境为Keil uVision4。Keil提供了包括C编译器、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。运行Keil软件需要Win98、NT、Win2000、WinXP、Win7等操作系统[6]。
如果使用C语言编程,那么Keil几乎就是不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。Keil uVision4引入灵活的窗口管理系统,使开发人员能够使用多台监视器。新的用户界面可以更好地利用屏幕空间,更有效地组织多个窗口,提供一个简洁、高效的环境来开发应用程序。新版本支持更多最新的ARM芯片,还添加了一些其他新功能。
1.3系统烧写框图
系统的烧写框图如图1所示。
图1 系统烧写框图
由Quartus软件产生.jbc文件,如果所产生的.jbc文件过大,则将文件放置于TF卡中,之后通过数据的读取,将文件数据读到片内FLASH。在STM32F103ZET6主控芯片中已经成功固化了Jam STAPL ByteCode Player执行软件,Jam STAPL ByteCode Player执行软件解析,并执行.jbc文件包含的信息,经过主控芯片模拟JTAG的时序,在系统时钟的驱动下烧写目标板CPLD。
2 硬件系统设计
主控芯片选择STM32F103ZET6,该芯片片上集成512 KB的FLASH存储器,完全能够容纳本系统所需求的.jbc文件,不必再外接FLASH芯片。如果用户所生成的用于烧写CPLD的.jbc文件大小比芯片片内FLASH存储容量大,就需要外扩FLASH芯片,以保证文件的完整性[7]。在生产上,为了适应绝大部分的数据烧写文件,可以把.jbc文件放到TF卡中。通过文件系统,将数据一块一块地搬移到片内FLASH中去,这样一来,不管多大的数据文件,都不用担心存储空间不足的问题。
图2为硬件系统结构框图。
图2 硬件系统结构框图
硬件系统主要包括外部晶振电路、电源模块、用于调试的20针JTAG调试接口、复位电路、串行接口USART、TF卡槽和用于烧写的5针JTAG烧写接口。硬件系统组成非常简洁,JTAG调试口是上位机用来调试烧写程序,并将烧写程序固化到STM32芯片中;外部晶振选择8 MHz;电源电压值选择3.3 V;SPI总线用来读取TF卡中的文件数据;JTAG烧写接口是用来烧写目标板的JTAG接口;USART串行口会打印出目标板的烧写信息,显示在PC机上。USART这一部分也可以省去,因为在程序中已经设定,目标板的CPLD烧写成功后,会有LED灯提示。
3 软件系统设计
本系统的软件设计主要采用Altera公司所提供的嵌入式处理器上使用 Jam 标准测试和编程语言(STAPL)进行在系统编程时的配置方案。
Altera公司为ISP 编程提供了软件级标准:Jam STAPL JEDEC 标准JESD71 ,它的出现彻底改变了可编程逻辑器件(PLD) 的编程和配置。该标准支持当前所有使用JTAG 进行在系统编程的可编程逻辑器件。对于嵌入式系统,该标准满足所有的必要条件,例如文件、便于操作以及平台独立。
3.1 烧写文件的生成
系统用于烧写CPLD的.jbc文件是由Altera公司提供的Quartus软件生成的[9]。其步骤如下:
① 在TOOLs菜单中,单击Programmer。
② 单击Add File,为所选逻辑器件选择编程文件。
③ 在File菜单上,指向Create/Update、单机Create Jam、SVF或者ISC File。
④ 在列出的File Format中,选择.jbc文件格式。
⑤ 单击OK按钮。
3.2 Jam STAPL ByteCode Player执行软件
系统所需要移植的源代码主要包括9个文件:JBICOMP.C文件、JBIJTAG.C文件、JBIMAIN.C文件、JBISTUB.C文件、JBC_FILE.C文件、JBICOMP.H文件、JBIJTAG.H文件、JBIPORT.H文件和JBIEXPRT.H文件。以上9个文件构成了Jam STAPL ByteCode Player执行软件。图3为该执行软件源代码结构图。
图3 执行软件源代码结构图
Quartus软件生成的.jbc文件,存放在JBC_FILE.C文件中。Jam STAPL ByteCode Player解析.jbc文件中的描述信息,将其翻译成设置到目标CPLD中的数据和算法。一个.jbc文件可包括多种功能,例如对CPLD进行编程、配置、验证、擦除以及空白检查等。Jam STAPL ByteCode Player是用C语言写的,应用于16位和32位处理器,其源代码的一部分也适用于8位处理器。把执行软件源代码分成3类:
① JBCSTUB.C文件:它是专门用于处理I/O功能的代码平台,应用到所使用的硬件上。
② JBC_FILE.C文件:用于存放.jbc文件中的数据。在该文件中定义了一个数组jbc_code,该数组存储的是十六进制的数,这些十六进制的数是由.jbc文件转换得来,本系统所用.jbc文件的大小为43 KB。
③ 所有其他的C文件:执行Player内部功能的通用代码。
3.3 软件的移植与实现
本系统是基于嵌入式处理器的CPLD的烧写,移植代码需要对其中的一些C文件进行修改。Jam STAPL ByteCode Player执行软件的默认配置包括支持DOS、32位Windows以及UNIX的代码,移植到本系统所选的平台上,需要使用预处理声明#define来去掉这些代码。移植主要修改的文件为JBISTUB.C文件,其中需要定制几个函数:
① jbi_jtag_io():为4个IEEE 1149.1 JTAG信号(TDI、TMS、TDO和TCK)提供接口。
② jbi_export():把信息(例如用户电子签名)传递回调用程序(选择默认)。
③ jbi_delay():执行期间实现所需的编程脉冲或者延迟。
④ jbi_vector_map():处理非IEEE 1149.1JTAG信号的信号到引脚映射(选择默认)。
⑤ jbi_vector_io():对VECTOR MAP 中定义的非IEEE 1149.1 JTAG 信号进行置位(选择默认)。
系统的代码移植包括以下4步:
① 将预处理声明设置为去掉无关代码。
修改默认的PORT参数为EMBEDDED来去除DOS、Windows和UNIX源代码以及包含库,在JBISTUB.C 文件开头定义#define JBC_PORT EMBEDDED,即选择的环境是嵌入式处理器平台。
② 将JTAG信号映射至硬件引脚。
JBISTUB.C中的jbi_jtag_io()函数含有发送和接收二进制编程数据的代码。其实现代码如下:
#define TCK GPIOB,GPIO_Pin_6
#define TDO GPIOB,GPIO_Pin_7
#define TMS GPIOB,GPIO_Pin_8
#define TDI GPIOB,GPIO_Pin_9
int jbi_jtag_io(int tms, int tdi, int read_tdo){
int tdo = 0;
if (!jtag_hardware_initialized){
initialize_jtag_hardware();
jtag_hardware_initialized = TRUE;
}
GPIO_WriteBit(TMS,tms);/* set TMS signal */
GPIO_WriteBit(TDI,tdi);/* set TDI signal */
if (read_tdo){
tdo = GPIO_ReadInputDataBit(TDO);
/*read TDO signal*/
}
GPIO_SetBits(TCK);/* strobe TCK signal */
GPIO_ResetBits(TCK);
return (tdo);
}
③ 定制延时校准。
calibrate_delay()函数确定处理器每ms运行多少次循环。因为编程和配置需要精确的延时,因此这一校准过程非常重要。默认情况下,one_ms_delay = 1000L,根据自己系统所使用的处理器芯片进行修改,本系统定义的函数修改如下:
void calibrate_delay(void){
one_ms_delay = 10000L;
}
④ 修改主入口函数jbi_execute()。
Jam STAPL ByteCode Player主入口点是jbi_execute()函数,该函数将某些信息传给Player,Player根据所传达的命令作出相应的编程动作,当Player完成后会返回一个退出代码,以及任何运行时错误的详细信息。JBISTUB.C中的程序原型定义了接口:
JBI_RETURN_TYPE jbi_execute
(PROGRAM_PTR program,long program_size,char *workspace,long workspace_size,char *action,char **init_list,int reset_jtag,long *error_address,int *exit_code,int *format_version)
在JBISTUB.C的main()函数中确定了传给 jbi_execute()的变量。初始化列表告诉Jam STAPL ByteCode Player要执行的函数类型(例如编程和验证),传送该列表到 jbi_execute()。必须以正确的方式来传送初始化列表,如果初始化列表没有被传送或者无效,那么Jam STAPL ByteCode Player就会检查.jbc文件的语法。如果没有错误,那么返回一个成功退出码,不会执行程序函数。
移植只需要修改列表中3个参数:定义program_size = 43 883,单位是字节,该参数是.jbc文件的大小;定义program = (unsigned char *)jbi_code,该参数是指向.jbc文件的指针,也就是指向由.jbc文件转换而来的数组jbi_code[]的指针;定义 action[]= "PROGRAM\\0",即Player要对CPLD进行烧写动作。余下的参数不用修改,保持默认即可。主程序流程图如图4所示。
图4 主程序流程图
3.4 系统功能的实现与验证
系统所要烧写的目标CPLD为Altera公司生产的MAX II型号的器件,该器件能够支持.jbc文件所包括的操作有5项:Program、Blankcheck、Verify、Erase和Read_usercode。本系统只选择Program操作进行了功能验证。表1为.jbc文件操作声明定义。
对器件进行烧写后会返回退出代码。无论烧写成功与否,都会有一个退出代码被返回。退出代码是一个整数值,用于指示.jbc文件执行后的结果。退出代码为零表示成功,而非零则表示失败,并指示出失败的一般类型。系统的测试平台和烧写目标板实物图略——编者注。
在程序中已经设定:目标板中的CPLD烧写成功后,目标板的LED连闪三次,之后变成常亮的状态。烧写不成功,LED灯一直处于灭的状态。通过串口在PC机上打印出烧写成功的信息略——编者注。
表1 .jbc文件操作声明
若返回代码Exit code=0,表示CPLD烧写成功;若返回其他任何非0数字,均为烧写失败。
结语
该模块的成功实现,极大地方便了用户对CPLD的烧写和更新。对厂家而言,生产线上就可以告别笨重的电脑,省去繁琐的操作,修改和维护已销售产品中的CPLD逻辑将变得非常方便。