微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 基于JTAG的DSP外部FLASH在线编程与引导技术

基于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所示。


  4 测试实现

  下面是将文件写入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构成的磁悬浮数字控制系统编写的,可行性与可靠性已经在实际应用中得到验证。该程序具有良好的可移植性,秒作修改即可用于类似的在线编程系统,具有较强的实用价值。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top