dsp28335启动流程:
Reset→0x3fffc0启动,经过固化在ram里面一次bootloader,根据选择的启动方式跳转。
用的是flash启动:
从.cmd文件的begin 0x33FFF6的跳转指令 到codeStartBranch.asm里面的 c_int00再跳动bootloader的main函数,main函数再跳转到0x300000 (APP),app里面,app也要走一边begin→c_int00→main
我的测试流程:
1.做写个简单的跳转测试,不用上位机,只通过ccs烧录功能。
先在ccs上烧录一个小灯的程序到flashB区域,(右键工程选择properties,步骤如下图,在烧录时只擦除flashB区域,烧录到哪配置在cmd中)

2.然后再烧录boot程序,主程序只写一个跳转到app的指针地址。
在烧录时配置只擦flash除扇区A。
3.重新上电,程序会运行到bootloader跳转到app,小灯闪烁。
说明一些问题:
对于boot和app,在RAM上的分配,
我看网上有一些是直接在cmd里面把ram分配两块不重叠的区域,这样比较浪费空间,比较RAM的特点就是运行快但内存小。其实boot和app在cmd上可以完全重叠,在跳转到app的时候会进行覆盖,但需要注意Boot 跳转前清空中断、重置栈指针等:
· RAM 里的代码段:通过 MemCopy 手动覆盖初始化。
· RAM 里的变量段:通过 _c_int00 自动(编译器生成)覆盖初始化。
· 中断向量表:通过 InitPieVectTable() 手动覆盖初始化。
最后粘贴一下代码:
#include "DSP2833x_Device.h"
// 声明外部函数
void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr);
void InitSysCtrl(void);
// 引用全局的ramfuncs搬运变量
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
// APP起始地址(跳转到APP的codestart入口)
#define APP_CODESTART_ADDR 0x300000
#define VECT_ADDR_REG 0x000D08
void main(void) {
Uint16 idx;
// 1. 系统初始化:关闭看门狗、配置时钟
InitSysCtrl();
EALLOW;
SysCtrlRegs.WDCR = 0x0068; // 彻底关闭看门狗
EDIS;
// 2. RAMfuncs搬运(Boot自己的ramfuncs)
MemCopy((Uint16*)&RamfuncsLoadStart,
(Uint16*)&RamfuncsLoadEnd,
(Uint16*)&RamfuncsRunStart);
// 3. 重置系统状态
DINT; // 关全局中断
IER = 0x0000; // 清CPU中断使能
IFR = 0x0000; // 清CPU中断标志
PieCtrlRegs.PIECTRL.bit.ENPIE = 0; // 禁用PIE
PieCtrlRegs.PIEACK.all = 0xFFFF; // 清所有PIE中断响应
// 清空PIE向量表
EALLOW;
// 直接操作PIE向量表的物理地址0x00D00
Uint32 *pie_vect_ptr = (Uint32 *)0x00D00;
for(idx = 0; idx < 128; idx++) {
*pie_vect_ptr++ = 0;
}
// 重置向量表到Boot ROM默认位置
*((Uint32 *)VECT_ADDR_REG) = 0x3FFFC2;
EDIS;
// 4. 重置栈指针到RAMM1末尾
asm(" MOV SP, #0x0007FF");
// 5. 跳转到APP的codestart入口(0x300000)
if(*(Uint32*)APP_CODESTART_ADDR != 0xFFFFFFFF) {
((void (*)(void))APP_CODESTART_ADDR)();
}
// 6. 跳转失败保底
while(1);
}
//=================bootloader main.c=================================
/* F28335 Bootloader.cmd(仅放扇区A,适配跳转功能) */
MEMORY
{
PAGE 0: /* Program Memory */
RAML0 : origin = 0x008000, length = 0x002000 /* RAML0(用于ramfuncs搬运) */
BOOT_ENTRY : origin = 0x338000, length = 0x007F80 /* 扇区A主区域(0x338000-0x33FF7F) */
CSM_RSVD : origin = 0x33FF80, length = 0x000076 /* 扇区A保留区 */
BEGIN : origin = 0x33FFF6, length = 0x000002 /* 启动向量 */
CSM_PWL : origin = 0x33FFF8, length = 0x000008 /* CSM密码区 */
ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC校准 */
ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */
RESET : origin = 0x3FFFC0, length = 0x000002 /* 复位向量 */
PAGE 1 : /* Data Memory */
RAMM1 : origin = 0x000500, length = 0x000300 /* 栈空间:0x000500-0x0007FF,共768字节 */
RAML4 : origin = 0x00C000, length = 0x001000 /* 数据段:4KB */
}
SECTIONS
{
codestart : > BEGIN PAGE = 0 /* 启动向量,必须放在扇区A末尾 */
.cinit : > BOOT_ENTRY PAGE = 0 /* 初始化段,放扇区A */
.text : > BOOT_ENTRY PAGE = 0 /* 代码段,放扇区A */
ramfuncs : LOAD = BOOT_ENTRY, /* 加载到Flash扇区A */
RUN = RAML0, /* 运行在RAML0 */
LOAD_START(_RamfuncsLoadStart), /* 生成搬运起始符号 */
LOAD_END(_RamfuncsLoadEnd), /* 生成搬运结束符号 */
RUN_START(_RamfuncsRunStart), /* 生成运行起始符号 */
PAGE = 0
.stack : > RAMM1 PAGE = 1 /* 栈空间,必须独立 */
.ebss : > RAML4 PAGE = 1 /* 全局变量段 */
.econst : > BOOT_ENTRY PAGE = 0 /* 常量段 */
.reset : > RESET, PAGE = 0, TYPE = DSECT /* 禁用Boot的复位段,避免覆盖 */
.adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD /* ADC校准段,只读不加载 */
}
//=================bootloader cmd.c=================================
#include "DSP2833x_Device.h"
#include "DSP2833x_Examples.h"
// 声明ramfuncs搬运相关变量(由.cmd文件定义,必须声明才能正常搬运)
extern Uint16 RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart;
// 150MHz系统时钟下,延时约1秒
void delay_1s(void) {
volatile Uint32 i;
for(i = 0; i < 1500000; i++) {
// 空循环,增加编译器优化屏障,避免被优化掉
asm(" NOP");
}
}
void main(void) {
// 1. 系统初始化(关闭看门狗、配置PLL时钟=150MHz)
InitSysCtrl();
// 2. 搬运ramfuncs段(从Flash的APPLICATION区域搬运到RAML0区域运行)
// 必须在初始化其他外设/中断前执行,避免Flash运行函数出错
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
// 3. 中断系统初始化(小灯APP无中断需求,仅做基础初始化,禁止所有中断)
DINT; // 禁止全局中断(防止初始化过程中触发中断)
InitPieCtrl(); // 初始化PIE中断控制器:复位PIE寄存器到默认状态
IER = 0x0000; // 清空CPU中断使能寄存器(禁用所有CPU级中断)
IFR = 0x0000; // 清空CPU中断标志寄存器(清除所有未处理中断)
InitPieVectTable(); // 初始化PIE向量表:将ROM默认向量表拷贝到RAM
// 4. GPIO初始化(配置GPIO60、GPIO61为推挽输出,控制小灯)
EALLOW; // 解锁受保护的寄存器(GPIO控制寄存器属于受保护寄存器)
// 配置GPIO60
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0; // 0=通用GPIO模式(禁用外设功能)
GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1; // 1=输出模式(0=输入模式)
GpioCtrlRegs.GPBPUD.bit.GPIO60 = 0; // 0=使能上拉电阻(避免IO口悬空)
// 配置GPIO61
GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0; // 0=通用GPIO模式
GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1; // 1=输出模式
GpioCtrlRegs.GPBPUD.bit.GPIO61 = 0; // 0=使能上拉电阻
EDIS; // 锁定受保护的寄存器(配置完成后锁定,防止误修改)
// 5. 主循环:翻转GPIO60、GPIO61,实现小灯闪烁
while(1) {
GpioDataRegs.GPBTOGGLE.bit.GPIO60 = 1; // 翻转GPIO60电平
GpioDataRegs.GPBTOGGLE.bit.GPIO61 = 1; // 翻转GPIO61电平
delay_1s(); // 延时1秒
}
}
//============================app main.c=========================
/* F28335 APP.cmd(小灯程序专用) */
MEMORY
{
PAGE 0: /* Program Memory */
ZONE0 : origin = 0x004000, length = 0x001000 /* XINTF zone 0 */
RAML0 : origin = 0x008000, length = 0x002000 /* on-chip RAM block L0 */
RAML2 : origin = 0x00A000, length = 0x001000 /* on-chip RAM block L2 */
RAML3 : origin = 0x00B000, length = 0x001000 /* on-chip RAM block L3 */
ZONE6A : origin = 0x100000, length = 0x00FC00 /* XINTF zone 6 - program space*/
ZONE7 : origin = 0x200000, length = 0x100000 /* XINTF zone 7 */
BEGIN : origin = 0x300000, length = 0x000002
APP_ENTRY : origin = 0x300002, length = 0x007FFE
OTP : origin = 0x380400, length = 0x000400 /* on-chip OTP */
ADC_CAL : origin = 0x380080, length = 0x000009 /* ADC_cal function */
IQTABLES : origin = 0x3FE000, length = 0x000b50 /* IQ Math Tables in Boot ROM */
IQTABLES2 : origin = 0x3FEB50, length = 0x00008c /* IQ Math Tables in Boot ROM - 放回PAGE 0 */
FPUTABLES : origin = 0x3FEBDC, length = 0x0006A0 /* FPU Tables in Boot ROM */
ROM : origin = 0x3FF27C, length = 0x000D44 /* Boot ROM */
RESET : origin = 0x3FFFC0, length = 0x000002 /* part of boot ROM */
VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of boot ROM */
PAGE 1 : /* Data Memory */
BOOT_RSVD : origin = 0x000000, length = 0x000050 /* Part of M0 */
RAMM0 : origin = 0x000050, length = 0x0004B0 /* on-chip RAM block M0 */
RAMM1 : origin = 0x000500, length = 0x000300 /* on-chip RAM block M1 */
RAML4 : origin = 0x00C000, length = 0x001000 /* on-chip RAM block L4 */
RAML5 : origin = 0x00D000, length = 0x001000 /* on-chip RAM block L5 */
RAML6 : origin = 0x00E000, length = 0x001000 /* on-chip RAM block L6 */
RAML7 : origin = 0x00F000, length = 0x001000 /* on-chip RAM block L7 */
ZONE6B : origin = 0x10FC00, length = 0x000400 /* XINTF zone 6 - data space */
}
SECTIONS
{
codestart : > BEGIN PAGE = 0
/* 程序段映射到APP Flash分区 */
.cinit : > APP_ENTRY PAGE = 0
.pinit : > APP_ENTRY, PAGE = 0
.text : >> APP_ENTRY PAGE = 0
/* ramfuncs段:从Flash搬运到RAML0运行 */
ramfuncs : LOAD = APP_ENTRY,
RUN = RAML0,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
/* 未初始化数据段 */
.stack : > RAMM1 PAGE = 1
.ebss : > RAML4 PAGE = 1
.esysmem : > RAMM1 PAGE = 1
/* 初始化数据段 */
.econst : > APP_ENTRY PAGE = 0
.switch : > APP_ENTRY PAGE = 0
/* IQ数学库相关 */
IQmath : > APP_ENTRY PAGE = 0
IQmathTables : > IQTABLES, PAGE = 0, TYPE = NOLOAD
IQmathTables2 : > IQTABLES2, PAGE = 0, TYPE = NOLOAD
FPUmathTables : > FPUTABLES, PAGE = 0, TYPE = NOLOAD
/* DMA相关RAM */
DMARAML4 : > RAML4, PAGE = 1
DMARAML5 : > RAML5, PAGE = 1
DMARAML6 : > RAML6, PAGE = 1
DMARAML7 : > RAML7, PAGE = 1
/* XINTF Zone6数据区 */
ZONE6DATA : > ZONE6B, PAGE = 1
/* 复位和向量表(禁用) */
.reset : > RESET, PAGE = 0, TYPE = DSECT
vectors : > VECTORS PAGE = 0, TYPE = DSECT
/* ADC校准函数 */
.adc_cal : load = ADC_CAL, PAGE = 0, TYPE = NOLOAD
}
//============================app cmd.c=========================
#10063-D entry-point symbol other than "_c_int00" specified: "code_start" test_upgrade C/C++ Problem
这个app编译时会有一个警告,这个是正常的,意思是手动指定了一个非标准的程序入口点,先烧录app也是在测试app代码是否正确,ccs在调试时会智能帮助找到代码运行。

3887

被折叠的 条评论
为什么被折叠?



