基于JTAG的DSP外部FLASH在线编程与引导技术
时间:01-22
来源:作者:刘德生 李杰
点击:
3.2 FLASH文件在线编程的实现
考虑到AT29LV020的最小编程单位为一个扇区,首先应该将待编程的文件分割为若干个256字节的编程单元,对于最后的一个单元,无论是否够256字节,都无需理会,仍旧按照一个扇区处理。
假设待编程的文件名为filename.ldr,采用编程语言编写软件时,使用变量定义:
.var f_data[]="filename.ldr";
缓冲区f_data[]的首址指向filename.ldr的首行,f_data的每个元素都对应文件的一行。由于创建的引导程序文件每行数据都是16位的,包含两个8位字节,所以必须将其分解为两部分后分别写入FLASH。
软件的流程如图3所示。
下面是将文件写入FLASH的完整程序,在实际中已经调试成功。通过该程序将一段闪灯代码blink.ldr写入FLASH中,复位后,被写入的代码自动加载到DSP中执行。在编程过程中,ADSP-21065L的FLAG10引脚输出周期为40ms的方波;编程结束后,FLAG8输出周期为40ms的方波。
//宏定义与变量初始化
#define f_size 1572 //文件的行数
#define mem_offset 0x020000 //FLASH的地址偏移
#define u_mem1_a 0x025555 //命令字写入地址1
#define u_mem2_a 0x022AAA //命令字写入地址2
#include<def21065L.h>
.section/dm seg_fout;
.var f_data[]="blink,ldr" //待写入的代码文件
.section/dm seg_dmda;
.var d_byte;
.var addr;
.var line_num=0; //当前扇区已写入行数
.var byte_size; //待写入代码字节数-1
.var counter="0"; //延时的计数值
//复位中断
.section/pm pm_rsti;
nop;
jump start;
nop;
//以下是主程序
.section/pm seg_pmco;
start:
nop;
bit clr mode1 0x00001000; //屏蔽所有中断
IRPTL=0x0; //清除未响应中断
r0=0x0050; //设置FLAG10和
dm(IOCTL)=r0; //FLAG8为输出引脚
program:
i0=f_data;
r2=0x0; //已经写入的字节数-1
r3=f_size;
r4=r3+r3;
r4=r4-1;
dm(byte_size)=r4;
r6=dm(line_num);
r7=0;
comp(r6,r7); //判断是否为新的扇区
if ne jump sect_load; //不是,则直接向FLASH缓冲区写入字节
sect_ulock: //是,首先写命令字序列
r12=0xAA;
dm(u_mem1_a)=r12;
r12=0x55;
dm(u_mem2_a)=r12;
r12=0xA0;
dm(u_mem1_a)=r12;
sect_load:
r0=dm(i0,1); //读取一行数据
r1=fext r0 by 0:8; //获得低字节
dm(d_byte)=r1;
dm(addr)=r2;
call load_byte; //向FLASH写入低字节
r2=r2+1;
r1=fext r0 by 8:8; //获得高字节
dm(d_byte)=r1;
dm(addr)=r2;
call loade_byte; //向FLASH写入高字节
r8=dm(byte_size);
comp(r2,r8); //判断文件是否全部写完
if eq jump done; //是,则结束
r6=dm(line_num); //否,判断扇区是否结束
r6=r6+1;
dm(line_num)=r6;
r7=128;
comp(r6,r7);
if lt jump prog_loop; 否,继续向该扇区写数据
sect_done: //是,等待20ms
nop;
call wait_DQ7;
ustat2=dm(IOSTAT);
bit tg1 ustat2 FLG10O;
dm(IOSTAT)=ustat2; //翻转FLAG10
r6=0;
dm(line_num)=r6;
r2=r2+1;
jump sect_ulock; //开始向新扇区写数据
prog_loop:
r2=r2+1;
jump sect_load;
done: //编程结束
nop;
call wait_DQ7;
ustat2=dm(IOSTAT);
bit tg1 ustat2 FLG8O; //翻转FLAG8
dm(IOSTAT)=ustat2;
jump done;
load_byte: //写字节子程序
i4=dm(addr);
m4=mem_offset;
r12=dm(d_byte);
dm(m4,i4)=r12;
rts;
nop
wait_DQ7: //20ms延时子程序
r0=dm(counter);
r0=r0+1;
dm(counter)=r0;
r1=0x59000;
comp(r0,r1);
if lt jump wait_DQ7;
r0=0;
dm(counter)=r0;
rts;
nop;
上面的程序是针对由ADSP-21065L和AT29LV020构成的磁悬浮数字控制系统编写的,可行性与可靠性已经在实际应用中得到验证。该程序具有良好的可移植性,秒作修改即可用于类似的在线编程系统,具有较强的实用价值。
考虑到AT29LV020的最小编程单位为一个扇区,首先应该将待编程的文件分割为若干个256字节的编程单元,对于最后的一个单元,无论是否够256字节,都无需理会,仍旧按照一个扇区处理。
假设待编程的文件名为filename.ldr,采用编程语言编写软件时,使用变量定义:
.var f_data[]="filename.ldr";
缓冲区f_data[]的首址指向filename.ldr的首行,f_data的每个元素都对应文件的一行。由于创建的引导程序文件每行数据都是16位的,包含两个8位字节,所以必须将其分解为两部分后分别写入FLASH。
软件的流程如图3所示。
下面是将文件写入FLASH的完整程序,在实际中已经调试成功。通过该程序将一段闪灯代码blink.ldr写入FLASH中,复位后,被写入的代码自动加载到DSP中执行。在编程过程中,ADSP-21065L的FLAG10引脚输出周期为40ms的方波;编程结束后,FLAG8输出周期为40ms的方波。
//宏定义与变量初始化
#define f_size 1572 //文件的行数
#define mem_offset 0x020000 //FLASH的地址偏移
#define u_mem1_a 0x025555 //命令字写入地址1
#define u_mem2_a 0x022AAA //命令字写入地址2
#include<def21065L.h>
.section/dm seg_fout;
.var f_data[]="blink,ldr" //待写入的代码文件
.section/dm seg_dmda;
.var d_byte;
.var addr;
.var line_num=0; //当前扇区已写入行数
.var byte_size; //待写入代码字节数-1
.var counter="0"; //延时的计数值
//复位中断
.section/pm pm_rsti;
nop;
jump start;
nop;
//以下是主程序
.section/pm seg_pmco;
start:
nop;
bit clr mode1 0x00001000; //屏蔽所有中断
IRPTL=0x0; //清除未响应中断
r0=0x0050; //设置FLAG10和
dm(IOCTL)=r0; //FLAG8为输出引脚
program:
i0=f_data;
r2=0x0; //已经写入的字节数-1
r3=f_size;
r4=r3+r3;
r4=r4-1;
dm(byte_size)=r4;
r6=dm(line_num);
r7=0;
comp(r6,r7); //判断是否为新的扇区
if ne jump sect_load; //不是,则直接向FLASH缓冲区写入字节
sect_ulock: //是,首先写命令字序列
r12=0xAA;
dm(u_mem1_a)=r12;
r12=0x55;
dm(u_mem2_a)=r12;
r12=0xA0;
dm(u_mem1_a)=r12;
sect_load:
r0=dm(i0,1); //读取一行数据
r1=fext r0 by 0:8; //获得低字节
dm(d_byte)=r1;
dm(addr)=r2;
call load_byte; //向FLASH写入低字节
r2=r2+1;
r1=fext r0 by 8:8; //获得高字节
dm(d_byte)=r1;
dm(addr)=r2;
call loade_byte; //向FLASH写入高字节
r8=dm(byte_size);
comp(r2,r8); //判断文件是否全部写完
if eq jump done; //是,则结束
r6=dm(line_num); //否,判断扇区是否结束
r6=r6+1;
dm(line_num)=r6;
r7=128;
comp(r6,r7);
if lt jump prog_loop; 否,继续向该扇区写数据
sect_done: //是,等待20ms
nop;
call wait_DQ7;
ustat2=dm(IOSTAT);
bit tg1 ustat2 FLG10O;
dm(IOSTAT)=ustat2; //翻转FLAG10
r6=0;
dm(line_num)=r6;
r2=r2+1;
jump sect_ulock; //开始向新扇区写数据
prog_loop:
r2=r2+1;
jump sect_load;
done: //编程结束
nop;
call wait_DQ7;
ustat2=dm(IOSTAT);
bit tg1 ustat2 FLG8O; //翻转FLAG8
dm(IOSTAT)=ustat2;
jump done;
load_byte: //写字节子程序
i4=dm(addr);
m4=mem_offset;
r12=dm(d_byte);
dm(m4,i4)=r12;
rts;
nop
wait_DQ7: //20ms延时子程序
r0=dm(counter);
r0=r0+1;
dm(counter)=r0;
r1=0x59000;
comp(r0,r1);
if lt jump wait_DQ7;
r0=0;
dm(counter)=r0;
rts;
nop;
上面的程序是针对由ADSP-21065L和AT29LV020构成的磁悬浮数字控制系统编写的,可行性与可靠性已经在实际应用中得到验证。该程序具有良好的可移植性,秒作修改即可用于类似的在线编程系统,具有较强的实用价值。
JTAG DSP Flash 在线编程 引导技术 相关文章:
- 采用DSP的声音采集系统硬件原理及设计(04-28)
- AVR单片机介绍(07-09)
- 总线实现片内硬件调试支持单元设计(08-15)
- 多核处理器架构及调试方案(03-28)
- 基于JTAG口对DSP外部Flash存储器的在线编程设计(04-29)
- 一种嵌入式系统实现的JTAG调试器(10-16)