2 Level Bootloader calls the _ c_int00 user portal program, and then calls the main function to start executing the user codeFor more information about _ c_int00, see [DSP TMS320C6000 basic learning (7) -- Bootloader and VectorTable] the premise of all operations in this article is that you have configured the interrupt vector table (so that the user program can be correctly entered only when _ c_int00 is called ).
2. Write a second-level BootloaderFirst, the macro defines EMIF-related registers. Because we want to read Flash, we need to configure the EMIF register before the second-level pilot program runs,
;; ======== 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 controlEMIF_CE1 .equ 0x01800004 ;address of EMIF CE1 control reg.EMIF_CE0 .equ 0x01800008 ;EMIF CE0controlEMIF_CE2 .equ 0x01800010 ;EMIF CE2controlEMIF_CE3 .equ 0x01800014 ;EMIF CE3controlEMIF_SDRAMCTL .equ 0x01800018 ;EMIF SDRAM controlEMIF_SDRAMTIM .equ 0x0180001c ;EMIF SDRAM timerEMIF_SDRAMEXT .equ 0x01800020 ;EMIF SDRAM extension; EMIF Register Values specifically for 6713 DSKEMIF_GCTL_V .equ 0x00000078 ;EMIF_CE0_V .equ 0xffffff23 ;EMIF CE0 SDRAMEMIF_CE1_V .equ 0xffffff13 ;EMIF CE1 Flash 8-bitEMIF_CE2_V .equ 0xffffbf93 ;EMIF CE2 Daughtercard 32-bit asyncEMIF_CE3_V .equ 0xffffff13 ;EMIF CE3 Daughtercard 32-bit asyncEMIF_SDRAMCTL_V .equ 0x53115000 ;EMIF SDRAM controlEMIF_SDRAMTIM_V .equ 0x00000578 ;SDRAM timing (refresh)EMIF_SDRAMEXT_V .equ 0x000a8529 ;SDRAM extended control
The EMIF register defined by the macro is declared as a global symbol. The effect of. global is the same as that of the extern in the C language and is declared as an external symbol.
;; ======== boot_c671x.h62 ========; .if ($isdefed("BOOT_C671X_") = 0) ; prevent multiple includes of this fileBOOT_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_V ;EMIF CE2 Daughtercard 32-bit async .global EMIF_CE3_V ;EMIF CE3 Daughtercard 32-bit async .global EMIF_SDRAMCTL_V ;EMIF SDRAM control .global EMIF_SDRAMTIM_V ;SDRAM timing (refresh) .global EMIF_SDRAMEXT_V ;SDRAM extended control .endif ; if BOOT_C671X_ is not definedThe following code snippet is named. boot_load. You will see it in the cmd file later.
The code first initializes EMIF and then reads the segment information of the user program in copy_section_top (the segment's Flash loading address, the segment's RAM running address, and the segment length ), execute the cyclic copy operation in copy_loop.
;A;; ======== File: boot_c671x.s62 ========; .title "Flash bootup utility"; global EMIF symbols defined for the c671x family .include boot_c671x.h62; Address of the generated boot-tableuser_size .equ 0x00001798user_ld_start .equ 0x90000400user_rn_start .equ 0x00000400 .sect ".boot_load" .global _boot .ref _c_int00_boot: ;************************************************************************;* DEBUG LOOP - COMMENT OUT B FOR NORMAL OPERATION;************************************************************************ zero B1_myloop: ; [!B1] B _myloop nop 5_myloopend: nop;************************************************************************;* CONFIGURE EMIF;************************************************************************ ;**************************************************************** ; *EMIF_GCTL = EMIF_GCTL_V; ;**************************************************************** mvkl EMIF_GCTL,A4 || mvkl EMIF_GCTL_V,B4 mvkh EMIF_GCTL,A4 || mvkh EMIF_GCTL_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_CE0 = EMIF_CE0_V ;**************************************************************** mvkl EMIF_CE0,A4 || mvkl EMIF_CE0_V,B4 mvkh EMIF_CE0,A4 || mvkh EMIF_CE0_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_CE1 = EMIF_CE1_V (setup for 8-bit async) ;**************************************************************** mvkl EMIF_CE1,A4 || mvkl EMIF_CE1_V,B4 mvkh EMIF_CE1,A4 || mvkh EMIF_CE1_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_CE2 = EMIF_CE2_V (setup for 32-bit async) ;**************************************************************** mvkl EMIF_CE2,A4 || mvkl EMIF_CE2_V,B4 mvkh EMIF_CE2,A4 || mvkh EMIF_CE2_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_CE3 = EMIF_CE3_V (setup for 32-bit async) ;**************************************************************** || mvkl EMIF_CE3,A4 || mvkl EMIF_CE3_V,B4 ; mvkh EMIF_CE3,A4 || mvkh EMIF_CE3_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_SDRAMCTL = EMIF_SDRAMCTL_V ;**************************************************************** || mvkl EMIF_SDRAMCTL,A4 || mvkl EMIF_SDRAMCTL_V,B4 ; mvkh EMIF_SDRAMCTL,A4 || mvkh EMIF_SDRAMCTL_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_SDRAMTIM = EMIF_SDRAMTIM_V ;**************************************************************** || mvkl EMIF_SDRAMTIM,A4 || mvkl EMIF_SDRAMTIM_V,B4 ; mvkh EMIF_SDRAMTIM,A4 || mvkh EMIF_SDRAMTIM_V,B4 stw B4,*A4 ;**************************************************************** ; *EMIF_SDRAMEXT = EMIF_SDRAMEXT_V ;**************************************************************** || mvkl EMIF_SDRAMEXT,A4 || mvkl EMIF_SDRAMEXT_V,B4 ; mvkh EMIF_SDRAMEXT,A4 || mvkh EMIF_SDRAMEXT_V,B4 stw B4,*A4;****************************************************************************; copy sections;**************************************************************************** mvkl copyTable, a3 ; load table pointer mvkh copyTable, a3 ; ldw *a3++, b1 ; Load entry pointcopy_section_top: ldw *a3++, b0 ; byte count ldw *a3++, b4 ; load flash start (load) address ldw *a3++, a4 ; ram start address nop 2 [!b0] b copy_done ; have we copied all sections? nop 5copy_loop: ldb *b4++,b5 ; fetch from flash sub b0,1,b0 ; decrement counter [ b0] b copy_loop ; setup branch if not done [!b0] b copy_section_top zero a1 [!b0] and 3,a3,a1 stb b5,*a4++ ; store to ram [!b0] and -4,a3,a5 [a1] and 4, a5,a3;****************************************************************************; jump to entry point;****************************************************************************copy_done: mvkl .S2 _c_int00,b0 mvkh .S2 _c_int00,b0 b .S2 b0 nop 5copyTable: ; count ; flash start (load) address ; ram start (run) address ;; .text .word user_size .word user_ld_start .word user_rn_start ;; end of table .word 0 .word 0 .word 0
In use, we need
user_size .equ 0x00001798user_ld_start .equ 0x90000400user_rn_start .equ 0x00000400
Modify. user_size indicates the size of the bytes in the user program segment, and user_ld_start indicates the start address of the Flash of the user code (I use 0x90000400 by default, which is not changed ), user_rn_start indicates that the user code is to be stored in the starting address of RAM (as shown in the previous figure, I usually do not change this ). I usually only modify the size of the byte of the user program segment. Large programs may need to adjust copyTable.
To meet the above address distribution, modify the cmd file of the user application as follows:
-c-x-l rts6700.lib-heap 100h-stack 200hMEMORY{ BOOT_RAM : o=00000000h,l=00000400h IRAM : o=00000400h,l=00040000h FLASH_BOOT : o=90000000h,l=00000400h FLASH_REST : o=90000400h,l=000FFB00h}SECTIONS{ .boot_load:> BOOT_RAM /* Initialized User code section */ .text :> IRAM .cinit :> IRAM .vectors :> IRAM .bss :> IRAM .far :> IRAM .stack :> IRAM .const :> IRAM .switch :> IRAM .sysmem :> IRAM .cio :> IRAM }Note that the. boot_load section corresponds to. sect ". boot_load" of the second-level Bootstrap program. If your application defines other segments, you can modify the cmd file, but. boot_load:> BOOT_RAM cannot be modified, and do not place other segments in the BOOT_RAM storage area.
Add the above three assembly file boxes to the project of the user program and re-compile the project.
3. Extract the binary data to be written.This part is purely manual. If you use VIM, it is much easier to process data.
First, connect the Jtag to the TMS320C6713 Development Board, download the user application, and use the File-> Data-> Save... function to save the binary code data in the memory. dat file.
Address is set in the above cmd file. <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + kernel/kernel + G/kernel/PC9wPgo8cD4Kx + kernel/CvM/CtPK/qi5tYXDOxLz + o6jI58/CzbyjqaOsz + kernel = "http://www.2cto.com/uploadfile/Collfiles/20140331/2014033109073742.png alt = "\">
Okay. Let's take a look at the saved boot. dat file,
Except for the first row, each row is a 4-byte length value. Put the numbers in boot. dat and those in text. dat in the array of boot [] and text [], and save the array in the header file.
Well, you don't need to talk about it. You can use your own explicit skills to format the data. I will use my VIM editor to easily handle it:
- First, delete the first line.
- Run the vim command to add a comma: % s/$/,/g
- Add array name
The result is as follows:
Now, it's almost the same, indicating that the binary of the machine code is now saved in our c header file. The following is to burn the machine code in the header file array to the corresponding address space of Flash.
4. Burn and write FlashThe Flash model used in this tutorial is AM29LV800BT.
First, you need to create a new project for Flash burning.
There are also a lot of explanations on the Internet about Flash programs. If I have activated Flash programs today, I will give you benefits and my Flash Driver,
/* * FileName : FLASH.h * Author : xiahouzuoxin * Date : 2013.09.28 * Version : v1.0 * Brief : */#ifndef _FLASH_H#define _FLASH_H#include "Config.h"#define FLASH_UL1 0xAA#define FLASH_UL2 0x55#define FLASH_UL3 0x80#define FLASH_UL4 0xAA#define FLASH_UL5 0x55#define FLASH_SECTOR_UL6 0x30#define FLASH_CHIP_UL6 0x10#define FLASH_PROGRAM 0xA0#define SECTOR_SIZE 0x0800#define BLOCK_SIZE 0x8000#define CHIP_SIZE 0x40000#define FLASH_FIRST_ADDR 0x90000000#define FLASH_OFFSET(addr) (FLASH_FIRST_ADDR+(addr)<<1) // 16 bit boot mode/* External functions propotype */extern uint32_t Flash_Erase(uint32_t addr,uint16_t type);extern void Flash_Readm(uint32_t addr,uint16_t *ptr,uint32_t length);extern uint32_t Flash_Reads(uint32_t addr);extern void Flash_Writem(uint32_t addr,uint16_t *ptr,uint32_t length);extern void Flash_Writes(uint32_t addr,uint16_t data);#endif
/** FileName: FLASH. c * Author: xiahouzuoxin * Date: 2013.09.28 * Version: v1.0 * Brief: */# include "FLASH. h "# include" stdio. h "/* Global vaiables */volatile uint16_t * FLASH_5555 = (volatile uint16_t *) (0x90000000 + (0x5555 <1 )); volatile uint16_t * FLASH_2AAA = (volatile uint16_t *) (0x90000000 + (0x2AAA <1);/** @ brief Flash erase function. * @ param addr: * type: * @ retval */uint32_t Flash_Eras E (uint32_t addr, uint16_t type) {uint32_t I, j; * FLASH_5555 = FLASH_UL1; // first * FLASH_2AAA = FLASH_UL2; // second * FLASH_5555 = FLASH_UL3; // third * FLASH_5555 = FLASH_UL4; * FLASH_2AAA = FLASH_UL5; switch (type) {case 0x50: // block erase * (uint16_t *) addr = type; while (* (uint16_t *) addr & 0x80 )! = 0x80); for (I = 0; I <BLOCK_SIZE; I ++) {if (* (uint16_t *) (addr + I )! = 0 xffff) {j = 0; break;} j = 1; break; case 0x30: // sector erase * (uint16_t *) addr = type; while (* (uint16_t *) addr & 0x80 )! = 0x80); break; case 0x10: // chip erase * FLASH_5555 = type; while (* FLASH_5555 & 0x80 )! = 0x80); break; default: break;} return (j);}/** @ brief Write a single data. * @ param addr: * data: * @ retval */void Flash_Writes (uint32_t addr, uint16_t data) {uint32_t j = 0; * FLASH_5555 = FLASH_UL1; * FLASH_2AAA = FLASH_UL2; * FLASH_5555 = FLASH_PROGRAM; * (uint16_t *) addr = data; j = 0; while (j <255) j ++; // with delay while (* (uint16_t *) addr! = Data); // check}/** @ brief Write the certain length data. * @ param addr: * ptr: * length: * @ retval */void Flash_Writem (uint32_t addr, uint16_t * ptr, uint32_t length) {uint32_t I; for (I = 0; I <length; I ++) {Flash_Writes (addr + (I <1), * (ptr + I); if (I % 0xFF = 0) {printf ("\ nWrite % d bytes... ", I <1) ;}}/ ** @ brief Read a single data. * @ param addr: * @ retval */uint32_t Flash_Reads (uint32_t addr) {return (* (uint16_t *) addr);}/** @ brief Read the certain length data. * @ param addr: * ptr: * length: * @ retval */void Flash_Readm (uint32_t addr, uint16_t * ptr, uint32_t length) {uint32_t I; for (I = 0; I <length; I ++) {* (ptr + I) = Flash_Reads (addr + 2 * I );}}The Flash_Writem function I use is burned every time by 16 bits (2 bytes). The burning code in the main program is
#include <c6x.h>#include <csl.h>#include <stdio.h>#include <stdlib.h>#include "Flash.h"#include "BSP.h"#include "boot.h"#include "text.h"main(){ /* Init PLL EMIF ... */ BSP_init(); /* Fetch data from file */ /* Erase flash memory. */ Flash_Erase(0x90000000,0x10); printf("\nErase Flash ok."); /* Write flash memory. */ Flash_Writem(0x90000000, (uint16_t *)boot, sizeof(boot)<<1); printf("\nWrite .boot ok."); Flash_Writem(0x90000000+(0x200<<1), (uint16_t *)text, sizeof(text)<<1); printf("\nWrite .text ok."); printf("\nBurn to flash ok.");}Note that in the Flash _writem calling format above, the second-level boot_loader is burned to the address space where the Flash start address is 0x90000000. The user application program is burned to the address space where the Flash start address is 0x90000400.
The data is successfully written. See the following section,
For more information, refer to [2]. It contains the CCS project used for program burning. To write different applications, you only need to replace the text. h and boot. h.
Note: You should pay attention to any of the above details when burning Flash. An error in a specific detail may cause the writing failure!
5 References[1] Creating a Second-Level Bootloader for FLASH Bootloading on TMS320C6000 Platform With Code Composer Studio
[2] My Flash burn CCS project