1.     前言

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

2.     F28XXX 启动过程

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

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;

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 0x3F 7FF6

3.     搬移思路

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

这样,完成整个搬移过程,一共需要三个程序。两个程序被固化到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。

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();

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

  1. F28335 学习系列一——FLASH 搬移到 RAM 运行实现方法

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! F283 ...

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

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

  3. 在x86服务器上 搭建基于docker的arm64程序编译和运行环境

    docker 镜像: multiarch/qemu-user-static:register arm64v8/ubuntu:18.04 必要的组件: qemu https://github.com/m ...

  4. c#上传文件程序在本地测试没问题发布到服务器上就,高分求助!!!C#为什么程序在本地运行没有问题,但布署到服务器上后就不行了呢...

    具体如何实施修补程序管理将取决于组织的大小和复杂性. 但是,您了解修补程序管理的重要性以及它是如何符合组织的整体风险管理策略是非常重要的. 例如,如果您决定不惜代价将风险最小化,可以遵循软件中每次出现 ...

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

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

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

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

  7. FlashVml2.0(WEB上的PhotoShop+Flash、VML最强开发工具)

    fvml2.0完整压缩包下载地址(6860KB,包括fvml2主程序.所有演示VMLFLASH.MP3.图片资源文件等所有文件): http://www.codefans.com/CodeView/C ...

  8. FlashVml2.0(WEB上的PhotoShop+Flash、VML最强开发工具)[推荐]

    fvml2.0完整压缩包下载地址(6860KB,包括fvml2主程序.所有演示VMLFLASH.MP3.图片资源文件等所有文件): http://www.codefans.com/CodeView/C ...

  9. ipad iphone开发_如何在iPhone或iPad上使用Adobe Flash

    ipad iphone开发 Khamosh Pathak Khamosh Pathak Growing up, you might have come across Flash while playi ...

  10. 360浏览器无法看html5,win7在360浏览器上不能看flash的彻底解决方法推荐

    win7系统在360浏览器上不能看flash的页面,如何才能彻底解决呢?很多用户在使用360浏览器的时候,会出现不能播放flash的问题,具体是哪个环节的原因用户们并不清楚,在用户们描述了相关的情况之 ...

最新文章

  1. 打造属于自己的underscore系列 ( 一 )
  2. 农牧行业销售经理生存手册(二)
  3. Intelij IDEA 2016.3安装mybatis插件并激活教程
  4. linux 下 storm环境搭建,Storm在Ubuntu环境下的单机部署
  5. python画正方体_python绘制立方体的方法
  6. ruby在类中访问@,类外访问调用方法
  7. 和华为杯_新闻|“华为杯”足球赛正式开展:我院女足小组赛拿下首胜
  8. i59400f能带动2070s吗?
  9. 剑指offer没有java版吗_剑指Offer(Java版) 持续更新中
  10. mac os x 安装mysql遇到 Access denied for user 'root'@'localhost' (using password: YES)的解决方法...
  11. Asp.net页面传值
  12. sqlserver之创建视图
  13. 【椭球大地测量学】Python及MATLAB实现大地坐标与空间直角坐标间的转换编程(含流程图)
  14. 会员消费积分管理系统c语言,三步教你玩转会员系统——会员等级、折扣、积分...
  15. 服务器正在运行由于另一个程序,关于 服务器正在运行中,由于另一个程序正在运行中,此操作没法完成 问题的解决...
  16. 搭建表白网站详细教程,小白也可以学懂!!!!
  17. OGG同步字符集从US7ASCII to ZHS16GBK故障解决
  18. css3渐变中的,css3 中的渐变
  19. 2022-03-26-Subline3的常用快捷键
  20. js和html:周岁年龄计算器

热门文章

  1. 聊聊泰国的工作和生活
  2. Android WebView下载使用教程
  3. 用Python实现6升水桶和7升水桶导出3升水
  4. 这5种数据挖掘技术,大数据玩的贼溜!
  5. python选择题题库百度文库_Python题库
  6. 国外问卷调查赚钱网站
  7. 会员数据化运营分析小技巧(留存分析+AARRR+)
  8. 全面理解 DNS 及 HTTPDNS
  9. 教你炒股票15:没有趋势,没有背驰
  10. 云服务器带宽如何选择?