This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
需求是这样的:
早期软件复位向量在0x33FFF6,FLASHA,由于使用仿真器升级软件不方便,因此做了一个bootloader,占用FLASHA,上电以后,bootloader先运行,接管DSP,根据外部条件判断是否运行用户代码,用户代码位于FLASH B C D E F G H,任意一块,用户程序在编写的时候避开FLASHA,同时把复位向量放到FLASHA之外的地方,比如FLASHC中,复位向量放到0x328000,用户程序和bootloader不公用任何资源和代码,都会分别初始化硬件。
现在的问题是:
我从bootloader跳转到用户代码,该如何操作?直接用LB指令跳转到用户程序的复位向量就可以吗? 上电时DSP处于复位状态,各个寄存器,内存内容都是确定的,但是我从bootloader跳转到用户代码,寄存器,内存都是跳转之前bootloader中的内容,直接跳转到用户代码会不会有问题?虽然用户软件会重新初始化硬件,但是实际中发现一些用户代码运行不正常。两种操作唯一的差别就是不使用bootloader的时候,用户软件时从DSP复位以后开始执行的,而使用bootloader以后,用户软件从bootloader开始运行,如果能实现软复位,将寄存器和内存复位到上电前的状态,就没有问题了。
请TI工程师不吝赐教,这种情况怎么操作比较好?谢谢
感谢纠正复位向量问题,实际的复位向量应该是0x3FFFC0,执行完Boot ROM中的原厂bootloader以后,才会把DSP控制权交给0x33FFF6处的用户代码。
DSP内置的bootloader通过GPIO来选择引导方法,这个实际使用很不灵活,因此我才要实现自己的bootloader。实际上我的bootloader具备一个用户界面和一些命令,类似uboot,可以执行一些简单的单板测试任务,用户代码加载任务。我希望可以从bootloader中直接跳转到用户代码,实际中发现跳转以后,有一些用户代码执行不正常,比如中断无法进入之类。而这些用户代码在不使用bootloader之前,直接跳转到0x33FFF6时是没有问题的。因此我分析,可能的原因是我的bootloader执行的时候改变了CPU寄存器和内存。因此我需要一个方法,在跳转到用户代码的时候将CPU内存和寄存器恢复到DSP内置bootloader执行完毕,转去执行0x33FFF6处代码时的状态。
重新上电或者复位,都会先执行bootloader,会把硬件初始化,所以还是存在这个问题。
在TI e2e上看到一个讨论帖,我在做的是类似的事情。
里面提到了一个跳转方法,先压栈,然后弹栈,把跳转地址放到RPC寄存器,最后使用LRETR指令返回,这样做的好处在哪里呢?
http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/113899.aspx
;; TI File $Revision: /main/7 $
;; Checkin $Date: May 2, 2006 20:49:39 $
;;###########################################################################
;;
;; FILE: Init_Boot.asm
;;
;; TITLE: 280x Boot Rom Initialization and Exit routines.
;;
;; Functions:
;;
;; _InitBoot
;; _ExitBoot
;;
;; Notes:
;;
;;###########################################################################
;; $TI Release:$
;; $Release Date:$
;;###########################################################################
.def _jumpToAppEntry
_jumpToAppEntry:
; Initialize the device for running in C28x mode.
C28OBJ ; Select C28x object mode
C28ADDR ; Select C27x/C28x addressing
SETC INTM;
ZAPA;
MOV @SP,#0;
PUSH ACC;
PUSH AL;
MOV AL, #0x0a08;
PUSH AL;
MOVL XAR7, #0x3E8000;
PUSH XAR7;
POP RPC;
POP ST1;
POP ST0;
POP IER;
POP DBGIER;
LRETR;
问题完美解决,附代码:extern void ExitXboot(Uint32 entry)
跟踪代码发现ExitXboot函数返回之前,CPU寄存器已经恢复到复位状态,之前跳转以后运行不正常的用户代码也工作正常了。那么现在的问题是:我现在的bootloader 位于FLASHA,只能更新FLASHA之外的用户代码,如何更新位于FLASHA的bootloader自身呢?也就是说,如何把所有的bootloader内容从FLASHA加载到RAM运行?RAM空间是足够的,代码可以通过不同的load地址和run地址,初始化的时候MemCopy到RAM来实现。代码常量如.econst段该如何处理呢?
;;###########################################################################
;;
;; FILE: ExitXboot.asm
;;
;; TITLE: 2833x Boot Rom Exit routines.
;;
;; Functions:
;;
;; _ExitXboot
;;
;; Notes:
;;
;;###########################################################################
.def _ExitXboot
.global __stack
;-----------------------------------------------
; _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
;-----------------------------------------------
_ExitXboot:
;-----------------------------------------------
; Insure that the stack is deallocated
;-----------------------------------------------
MOV SP,#__stack
;-----------------------------------------------
; Clear the bottom of the stack. This will endup
; in RPC when we are finished
;-----------------------------------------------
MOV *SP++,#0
MOV *SP++,#0
;-----------------------------------------------
; Load RPC with the entry point as determined
; by the boot mode. This address will be returned
; in the ACC register.
;-----------------------------------------------
PUSH ACC
POP RPC
;-----------------------------------------------
; 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
POP ST1
POP ST0
;------------------------------------------------
; Jump to the EntryAddr as defined by the
; boot mode selected and continue execution
;-----------------------------------------------
LRETR
;eof ----------
兄弟,我的情况和你一模一样,也是用LB从bootloader跳转到应用软件,同样遇到了所说的问题,应用软件起来之后运行不稳定,请问你这个exitxboot文件是从哪找到的?直接用exitxboot(应用软件跳转地址,也就是入口点)替代LB就行了么?万分感谢!
你好,我也在做和你一样的东西,串口升级28335的Flash;
我的思路是:一上电,串口输出一个界面,用户可以选择升级程序,或运行用户代码;
用户代码烧写到FlashA;升级程序的代码烧写到FlashB,运行时调至RAM中运行;
如果选择升级Flash程序,则通过串口传输HEX文件,并存储到外扩的RAM中运行,内部的RAM不够用;
我的问题是:
用CCS编译出来的.out文件直接通过工具转为.hex格式文件就可以传输了吗?
传输完成后是直接把接受进数组的内容 烧录进Flash 复位后就可以跳到新的Flash代码了吗?
大哥,我最后的问题你看到了么?求教啊;
还有我是上电从Flash启动的,人家说要用SCIA方式启动,我郁闷了,Flash启动后,RAM调用API,烧写完程序后复位不也是可以重新从Flash启动吗?这时候执行的是新的Flash代码。