1.     前言

TMS320F2812 DSP 里,代码从内部flash里运行,比从内部RAM里运行要慢30%左右,所以对运行时间苛刻的程序直接在flash里运行,往往不能满足要求。故而,需要将代码拷贝到RAM以提高运行速度。TI文档只提供了部分代码从flash拷贝到RAM中的方法。然而,在一些应用中,需要将整个代码段都拷贝到RAM中执行,以提高整体运行速度。本文通过对TMS320F2812 的启动代码研究,来探讨如何在从FLASH启动后将整个代码段拷贝到RAM中,然后在RAM中运行的方法。

2.     TMS320F2812 启动过程

TMS320F2812的内部存储器中,0x3FF000  ----0x3FFFC0是4K*16的Boot ROM。

  1  2812内部BootRom地址图

CPU向量表位于北部ROM的底端(0x3FFFC0 ---- 0x3FFFF)。当VMAP=1,ENPIE=0 ,MPNMC=0时,该向量表被激活。复位向量出厂时被编程指向函数InitBoot。这个函数开始启动过程。当然,启动过程完成之后,我们需要初始化PIE中断向量表,同时使能PIE block。初始化PIE中断向量表之后,除了复位,所有中断向量均从PIE获得。

TMS320F2812启动代码固化在该内部ROM中。当TMS320F2812上电或者热复位后,首先由芯片本身将一些寄存器初始化:

PIE disabled(ENPIE=0,VMAP=1,OBJMDE=0,AMODE=0,MOM1MAP=1),

然后dsp芯片会对XMPNMC管脚采样,根据采样值的高低,来决定启动模式是“微处理器模式”还是“微计算机模式”。当XMPNMC=0时,为“微计算机模式”,此时,启动ROM存储器被使能而XINTF Zone 7被禁止。复位向量从内部启动ROM获取,启动ROM在复位期间一直被使能。

启动ROM里的复位向量(位于0x3FFFC0)指向InitBoot函数(位于0x3FFC00)。在完成器件初始化(InitBoot)之后,Boot loader将检查GPIO管脚的状态,然后再决定选用的启动模式。启动模式有4种:跳转到flash,跳转到H0 SARAM,跳转到OTP或者调用片上启动程序。

InitBoot Function 所做工作有:1.初始化状态寄存器;2.将堆栈指针设为0x400(0x400 - 0x44F作为启动过程中的堆栈);3.读CSM密码保护部分;4.调用SelectBootMode;5.调用ExitBoot

在完成选择启动模式过程之后,根据选择的启动模式,dsp会跳到相应的启动入口。也可以自己选择启动入口。这些入口地址都在这之前已经被dsp定义好的。

如果从flash启动,那么我们的管脚状态应该是

GPIOF4

GPIOF12

GPIOF3

GPIOF2

(SCITXDA)

(MDXA)

(SPISTEA)

(SPICLK)

内部上拉

无内部上拉

无内部上拉

无内部上拉

Mode Selected

1

x

x

x

Jump to Flash address 0x3F7FF6

下图为BootROM 函数的流程图

图2  BootROM 函数的流程图

对于内部flash启动,如图

图3跳转到Flash启动的流程图

在0x3F7FF6必须放置一个跳转指令,该指令跳转到你自己的启动代码或者应用程序。

3.     搬移思路

根据上节2的启动过程,flash启动过后,跳到0x3F7FF6,然后根据其内容再跳转到应用程序。我们在这里稍微修改一下,就可以将PC指针跳到RAM首地址,程序就能在RAM里运行了。

将“搬移程序”烧在flash上,从flash启动之后,“搬移程序”会被执行。“搬移程序”做的工作就是将“应用主程序”代码拷贝到内部RAM,然后经过初始化环境(InitBoot,ExitBoot),将PC指针指向RAM里代码首地址。这样,你的程序就在RAM中运行起来了。也就是说,我们需要一个“搬移程序”,启动时运行,用来拷贝flash上的代码到RAM中;当然,还需要一个你的“应用主程序”,该主程序被“搬移程序”从flash里“挪”到RAM后在RAM中运行。我们还要做的工作就是,把“应用主程序”烧写到flash里的某一块,这个块又不会影响flash启动时运行“搬移程序”。完成这个烧写过程的程序,我们称之为flash烧写程序。

总结一下,完成整个搬移过程,一共需要三个程序。“搬移程序”和“应用主程序”被固化到flash里“烧写flash程序”将“应用主程序”烧入flash中指定的块中。TI的烧写flash插件用来烧写“搬移程序”。

4.     搬移方法

1)首先你要用的主程序必须编译通过,并且通过仿真器在RAM里运行无问题。将主程序的CMD文件进行改写,保证程序段(.text段)分配在连续的存储空间。程序从flash启动,所有初始化段链接在非易失存储器里,而非初始化段必须链接在易失存储器。我们可以把初始化段都放在一个连续的内部RAM空间,而非初始化段放在另一个内部RAM空间。如果你的代码不是很大,也可以都放在连续的RAM空间。但在实际项目中,通常你会遇到存储空间不够的问题。这时就要考虑将无关紧要的段放在另外的非程序空间了。

.cinit

Flash

.cio

RAM

.const

Flash

.econst

Flash

.pinit

Flash

.switch

Flash

.text

Flash

.bss

RAM

.ebss

RAM

.stack

Lower 64Kw RAM

.sysmem

RAM

.esysmem

RAM

.reset

RAM1

例如:

MEMORY
{
PAGE 0 :
RAMH0      : origin = 0x3F8000, length = 0x002000
PAGE 1 :
/* SARAM                     */
RAMM0M1    : origin = 0x000000, length = 0x000800
RAML0L1    : origin = 0x008000, length = 0x002000
}
SECTIONS
{
/* Allocate program areas: */
.reset              : > RAMH0     PAGE = 0
vectors             : > RAMH0     PAGE = 0
.cinit              : > RAMH0     PAGE = 0
.text               : > RAMH0     PAGE = 0
.const              : > RAMH0     PAGE = 0
.econst             : > RAMH0     PAGE = 0
.switch                               : > RAMH0     PAGE = 0
/* Allocate data areas: */
.stack              : > RAMM0M1     PAGE = 1
.bss                : > RAML0L1     PAGE = 1
.ebss               : > RAML0L1     PAGE = 1
.sysmem             : > RAML0L1     PAGE = 1
}

从上面的

2)其次,将该工程编译成功后,加载到内部ram,仿真器自动完成必要的初始化环境之后,pc指针应该指向_c_init00,记下现在PC指针的位置,在Boot.asm中会用到。

3)自制一个flash烧写程序,或者从网上下载其他网友的flash烧写程序,将目标地址放在除flashJ块以外的块中。烧写的长度不能小于被烧写的主程序长度。该烧写程序在RAM中运行。,其代码段不能和被烧写的主程序用的代码段存储区域相同,否则会破坏主程序在ram中的代码。

烧写之后,可以用CCS的Save data功能,来查看flash中的数值是否和ram里主程序空间数值一致。

4) 用TI的烧写插件烧写“搬移程序”。注意,该“搬移程序”要能在dsp启动后执行。并且,烧写的时候,不能将上一步烧到flash上的主程序代码擦除。“搬移程序”具体见下节。

5.     “搬移程序”具体实现方法

Boot.asm文件内容:

    .def _InitBoot
.ref _EntryAddr_H
.ref _EntryAddr_L
.sect ".InitBoot"
;
; _InitBoot
;
; 1) Initalizes the stack pointer
; 2) Sets the device for C28x operating mode
; 3) Calls the main boot functions
; 4) Calls an exit routine
;
_InitBoot:
; Initalize the stack pointer.
MOV SP, #0 ; Initalize the stack pointer
; Initalize the device for running in C28x mode.
C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
C28MAP ; Set blocks M0/M1 for C28x mode
CLRC PAGE0 ; Always use stack addressing mode
MOVW DP,#0 ; Initialize DP to point to the low 64 K
CLRC OVM
; Set PM shift of 0
SPM 0
; Read the password locations – this will unlock the
; CSM only if the passwords are erased. Otherwise it
; will not have an effect.
MOVL XAR1,#0x3F7FF8;
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1++
MOVL XAR0,*XAR1
; Cleanup and exit. At this point the EntryAddr
; is located in the ACC register
BF _ExitBoot,UNC
;
; _ExitBoot
;
;
;This module cleans up after the boot loader
;
; 1) Make sure the stack is deallocated.
; SP = 0x400 after exiting the boot
; loader
; 2) Push 0 onto the stack so RPC will be
; 0 after using LRETR to jump to the
; entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR – this will also clear the RPC
; register since 0 was on the stack
;
_ExitBoot:
;
; Insure that the stack is deallocated
;
MOV SP,#0
;
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;
MOV *SP++,#0
MOV *SP++,#0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
;
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;向堆栈中压入0x3f8000,该地址即为主程序在ram中运行的首地址。
MOV *SP++, #0x8000
MOV *SP++, #0x3F
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
POP RPC
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
;
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
; (OBJMODE = 1, AMODE = 0)
;
ZAPA
MOVL XT,ACC
MOVZ AR0,AL
MOVZ AR1,AL
MOVZ AR2,AL
MOVZ AR3,AL
MOVZ AR4,AL
MOVZ AR5,AL
MOVZ AR6,AL
MOVZ AR7,AL
MOVW DP, #0
;
; Restore ST0 and ST1. Note OBJMODE is
; the only bit not restored to its reset state.
; OBJMODE is left set for C28x object operating
; mode.
;
; ST0 = 0x0000 ST1 = 0x0A0B
; 15:10 OVC = 0 15:13 ARP = 0
; 9: 7 PM = 0 12 XF = 0
; 6 V = 0 11 M0M1MAP = 1
; 5 N = 0 10 reserved
; 4 Z = 0 9 OBJMODE = 1
; 3 C = 0 8 AMODE = 0
; 2 TC = 0 7 IDLESTAT = 0
; 1 OVM = 0 6 EALLOW = 0
; 0 SXM = 0 5 LOOP = 0
; 4 SPA = 0
; 3 VMAP = 1
; 2 PAGE0 = 0
; 1 DBGM = 1
; 0 INTM = 1
;
MOV *SP++,#0
MOV *SP++,#0x0A0B
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
POP ST1
POP ST0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
;
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;
LRETR
;
.end

“搬移程序”部分代码:

unsigned long *srcAddr = (unsigned long *)0x3D8000;
unsigned long *desAddr = (unsigned long *)0x3F8000;
InitSysCtrl();
// Disable and clear all CPU interrupts:
DINT;
IER = 0x0000;
IFR = 0x0000;
// Initialize Pie Control Registers To Default State:
InitPieCtrl();
InitPieVectTable();
//以下即将flash上的代码拷贝到ram中,根据自己需要,更改源地址和目标地址
for(i = 0; i < 0x2000; i++)
{
*(desAddr + i) = *(srcAddr + i);
}
InitBoot();   //调用Boot.asm中程序

摘自:http://blog.csdn.net/flylonginsky/archive/2008/04/10/2278048.aspx

CMD可知,主程序代码均放在RAMH0中,长度为0x2000。

在TMS320F2812上实现从flash拷贝整个程序到RAM上运行的方法探讨相关推荐

  1. 编写并运行php程序,上传所编写的PHP程序代码,并上传运行后的效果截图

    上传所编写的PHP程序代码,并上传运行后的效果截图 更多相关问题 [多选] 对税务机关的下列行政行为,纳税人可以申请行政复议的有(). [多选] 纳税人收到税务机关的行政处罚决定书之后,在法定期限内可 ...

  2. php微信小程序多图上传,tp5实现微信小程序多图片上传到服务器功能

    最近在做一个教育类的小商城的微信小程序,用到了上传多个图片文件到服务器端,这里做一个讲解,希望对大家有所帮助. 1,小程序端: 在wxml文件中: 删除 点击上传作业 在js文件中: Page({ / ...

  3. 将flash中的代码复制到RAM中运行的方法

    在MCU的使用过程中,偶尔会遇到将flash中的代码复制到RAM中运行的情况,下面就来说一下具体的方法,以28335的flash初始化为例: 1,编写函数,该函数处于flash中,就是我们即将要复制的 ...

  4. [第一讲]DSP28335将Flash中的代码拷贝到RAM中运行

    背景: 近期需要使用28335完成一个简单的逆变器设计,由于开关频率为81kHz,每个开关周期只有12.34us,担心在每个开关期间无法完成相应的计算工作,因此想到了将代码烧写时放在Flash中,初始 ...

  5. TMS320F280049C 学习笔记9 CMD文件 程序从FLASH复制到RAM中运行

    文章目录 动机 CMD文件结构与语法 MEMORY和SECTIONS指令 MEMORY指令 SECTIONS指令 程序与数据段 已初始化段 未初始化段 其他指令 #pragma指令的使用 程序从FLA ...

  6. DSP28377S_程序从FLASH部分复制到RAM中运行详解

    程序从FLASH部分复制到RAM中运行详解 为什么要复制到RAM中运行 CMD文件中对存储空间的分配 CMD文件中对段的定义 CMD文件中FLASH部分复制到RAM中的定义 main中的操作 编译后如 ...

  7. 在纸上写好一个c语言程序后,上机运行的基本步骤为,c基本概念(选择题).docx

    PAGE / NUMPAGES 一.单选题 1.下面叙述中正确的是: (A) 在C语言程序中,main()函数必须放在程序的开始位置 (B) 在C语言程序中,要调用的函数必须在main()函数中定义 ...

  8. 微信开发上传视频到服务器,微信小程序中实现上传视频的开发代码

    微信小程序中实现上传视频的开发代码,视频,接口,上传,代码,服务器 微信小程序中实现上传视频的开发代码 易采站长站,站长之家为您整理了微信小程序中实现上传视频的开发代码的相关内容. 本篇文章给大家带来 ...

  9. 加快windows上对大文件,以及很多很多小文件进行不同磁盘拷贝的速度——windows上的最快拷贝软件FastCopy

    欢迎大家关注笔者,你的关注是我持续更博的最大动力 原创文章,转载告知,盗版必究 加快windows上对大文件,以及很多很多小文件进行不同磁盘拷贝的速度--windows上的最快拷贝软件FastCopy ...

  10. 批量上传插件(flash,html5,jquery)

    1.jQuery File Upload 官网:http://blueimp.github.com/jQuery-File-Upload/ 在线示例:http://blueimp.github.com ...

最新文章

  1. 174. Dungeon Game
  2. java 显示日历_JAVA显示日历(已知年和该年第一天为星期几)
  3. IIS+PHP+MYSQL安装配置
  4. 通过yum安装Nginx
  5. POJ1284:Primitive Roots——题解
  6. Qt工作笔记-对QImage的进一步认识(关于α通道)
  7. net 自定义表单的设计
  8. 医药电商为何发展不起来?
  9. Java基础(二)——面向对象
  10. vs可以编译python_Python如何进行编译和反编译
  11. ThinkPHP 3 的输出
  12. matlab给函数积分,MATLAB函数积分
  13. piwik阅读(整体结构)
  14. 织梦系统基本参数php,织梦后台系统基本参数新增的变量数据库修改
  15. Ajax的简历技能如何写,web前端开发工程师简历专业技能怎么写
  16. raw/rgb/yuv/nv21图像格式总结
  17. java数据结构和算法——图的广度优先(BFS)遍历
  18. Java身份证处理工具
  19. 国产x86服务器芯片,华为、飞腾扛旗,国产服务器芯片有望突破!ARM要替代x86?...
  20. c语言反三角函数值域,反三角函数定义域和值域

热门文章

  1. tl-wdr5620千兆版设置虚拟服务器,TP-LINK无线路由TL-WDR5620千兆版使用步骤图解
  2. 爱快软路由上装linux,爱快软路由系统利用自带虚拟机安装系统
  3. Matplotlib 25张图,数据分析可视化利器,不收藏女友要和我分手
  4. Android应用锁实现
  5. 大学生创新创业大赛案例_大学生创新创业典型案例4
  6. 哔哩哔哩手机客户端下载视频转到电脑上播放
  7. win10熄屏时间不对_win10的息屏时间怎么调
  8. 局域网内计算机无法ping通,局域网内目标主机无法ping通怎么处理 局域网内目标主机无法ping通如何解决...
  9. traceroute不通linux,能ping通traceroute不通
  10. android word编辑图片,Word转换成图片详细教程.doc