1 你必须知道的TMS320C6000启动过程
这部分内容在我的另一篇博客
DSP TMS320C6000基础学习(7)—— Bootloader与VectorTable
有提到过,这里重新摘录一遍。
如上图
- 在Device Reset阶段:设备初始化为默认状态,大部分三态输出都配置为高阻态。
- 在CPU Reset阶段:从RS上升沿处开始(这个时候,HD[4:3]配置启动模式,HD8配置大小端模式,CLKMODE配置输入时钟源,根据HPI_EN配置外设功能),处理器检查启动模式HD[4:3],启动bootloader程序。
从上图可以看出,CE1地址空间必需连接Flash芯片才能使用外部Flash引导模式,在电路设计时要注意。
若HD[4:3]=10(本文的操作环境基于此),EDMA自动将CE1起始位置的1KB代码拷贝到内部程序存储器的0地址,这部分功能是由硬件完成的,称一级引导Bootloader。
因此,外部Flash启动的最简单的想法就是:把要运行的程序放到CE1的起始1KB地址空间。这样只要设置HD[4:3]=10就能自启动了。那这么简单,还有讨论本文的必要吗?
呃,如果你的思维还停留在小孩子过家家的程度,唉。。。1KB?1KB才能存多少代码?要是代码量超过1KB呢?这正是本文要探讨的问题的初衷:程序代码>1KB,如何让C6713的程序从外部Flash自启动?
这就涉及另一个Bootloader了,我们称之为二级引导Bootloader(说白了就是一段小程序)。二级Bootloader作用有:(1)在上电复位后将用户的应用程序从Flash拷贝到RAM中执行;(2)跳转到应用程序的入口函数处。
二级Bootloader的执行要由一级Bootloader拷贝到RAM中执行,这就明白了,二级Bootloader必须放在外部Flash的起始的1KB位置处。
我们简要的用个图描述下所谓的二级Bootloader的自启动过程及主要思路。
要完成这个过程,
- 首先要编写一段称为2 Level Bootloader的启动代码并烧写到Flash的初始1KB地址处(DSP6713的CE1起始地址为0x90000000),1 Level Bootloader将该代码拷贝到RAM的起始0地址,开始执行。
- 烧写用户程序到0x90000400开始的Flash地址处
- 2 Level Bootloader将0x90000400开始的用户代码拷贝到RAM的0x400地址处
- 2 Level Bootloader调用_c_int00用户入口程序,然后调用main函数开始执行用户代码
关于_c_int00的介绍也请参考[DSP TMS320C6000基础学习(7)—— Bootloader与VectorTable]本文所有操作的前提是您已经配置好了中断向量表(这样在调用_c_int00时才能正确的进入到用户程序)。
2 编写二级Bootloader
先宏定义一下EMIF相关的寄存器,因为我们要读Flash,所以在二级引导程序运行前要配置EMIF寄存器,
;
; ======== c6713_emif.s62 ========
;
.title "Flash bootup utility"
; global EMIF symbols defined for the c671x family
.include boot_c671x.h62
;EMIF Register Addresses for c671x family
EMIF_GCTL .equ 0x01800000 ;EMIF global control
EMIF_CE1 .equ 0x01800004 ;address of EMIF CE1 control reg.
EMIF_CE0 .equ 0x01800008 ;EMIF CE0control
EMIF_CE2 .equ 0x01800010 ;EMIF CE2control
EMIF_CE3 .equ 0x01800014 ;EMIF CE3control
EMIF_SDRAMCTL .equ 0x01800018 ;EMIF SDRAM control
EMIF_SDRAMTIM .equ 0x0180001c ;EMIF SDRAM timer
EMIF_SDRAMEXT .equ 0x01800020 ;EMIF SDRAM extension
; EMIF Register Values specifically for 6713 DSK
EMIF_GCTL_V .equ 0x00000078 ;
EMIF_CE0_V .equ 0xffffff23 ;EMIF CE0 SDRAM
EMIF_CE1_V .equ 0xffffff13 ;EMIF CE1 Flash 8-bit
EMIF_CE2_V .equ 0xffffbf93 ;EMIF CE2 Daughtercard 32-bit async
EMIF_CE3_V .equ 0xffffff13 ;EMIF CE3 Daughtercard 32-bit async
EMIF_SDRAMCTL_V .equ 0x53115000 ;EMIF SDRAM control
EMIF_SDRAMTIM_V .equ 0x00000578 ;SDRAM timing (refresh)
EMIF_SDRAMEXT_V .equ 0x000a8529 ;SDRAM extended control
宏定义的EMIF寄存器声明为全局符号,.global与C语言中的extern效果一致,声明为外部符号。
;
; ======== boot_c671x.h62 ========
;
.if ($isdefed("BOOT_C671X_") = 0) ; prevent multiple includes of this file
BOOT_C671X_ .set 1
; EMIF Register Addresses for c671x family
.global EMIF_GCTL ;EMIF global control
.global EMIF_CE1 ;address of EMIF CE1 control reg.
.global EMIF_CE0 ;EMIF CE0control
.global EMIF_CE2 ;EMIF CE2control
.global EMIF_CE3 ;EMIF CE3control
.global EMIF_SDRAMCTL ;EMIF SDRAM control
.global EMIF_SDRAMTIM ;EMIF SDRAM timer
.global EMIF_SDRAMEXT ;EMIF SDRAM extension
; EMIF Register Values for c671x family
.global EMIF_GCTL_V ;
.global EMIF_CE0_V ;EMIF CE0 SDRAM
.global EMIF_CE1_V ;EMIF CE1 Flash 8-bit
.global EMIF_CE2_