General method for burning and writing Flash in TMS320C6713

Source: Internet
Author: User

1. You must know the Startup Process of TMS320C6000.

This part of content is in my other blog

DSP TMS320C6000 basic learning (7) -- Bootloader and VectorTable

As mentioned above, I Will reextract it here.

For example

  • In the Device Reset phase: the Device is initialized to the default state, and most of the three-state output is configured to the high-impedance state.
  • In the CPU Reset phase: Start from the rising edge of RS (at this time, HD [4: 3] configures the startup mode, HD8 configures the size-end mode, and CLKMODE configures the input clock source, configure the peripheral function according to HPI_EN), check the Boot Mode HD [4: 3], and start the bootloader program.

    It can be seen that the CE1 address space must be connected to the Flash chip to use the External Flash Boot Mode. Pay attention to the circuit design.

    If HD [4: 3] = 10 (the operating environment in this article is based on this), EDMA automatically copies the 1KB code at the starting position of CE1 to the 0 address of the internal program memory, this part of the function is completed by hardware, called a level-1 Boot Bootloader.

    Therefore, the simplest idea for External Flash startup is to put the program to be run in the 1KB address space starting from CE1. In this way, you only need to set HD [4: 3] = 10 to enable automatic startup. Is it so simple that it is necessary to discuss this article?

    Er, if your thinking is still at home for a child, alas... 1KB? How much code can be stored in 1 kb? What if the code size exceeds 1 kb? This is the original intention of this article: The program code> 1 kb, how to enable the C6713 program to start from the External Flash?

    This involves another Bootloader, which we call a second-level boot Bootloader (to put it bluntly, it is a small program ). Level 2 Bootloader has the following functions: (1) copy your application from Flash to RAM after power-on reset; (2) Jump to the entry function of the application.

    The execution of level-2 Bootloader should be copied from level-1 Bootloader to RAM for execution. It is clear that level-2 Bootloader must be placed at the 1KB position starting from the external Flash.

    We briefly use a diagram to describe the self-starting process and main ideas of the so-called second-level Bootloader.

    To complete this process,

    • First, write a boot code called 2-Level Bootloader and write it to the initial 1KB address of Flash (the CE1 starting address of DSP6713 is 0x90000000 ), 1 Level Bootloader copies the code to the starting 0 address of RAM and starts execution.
    • Burn the user program to the Flash Address starting with 0x90000400
    • 2 Level Bootloader: copy the user code starting with 0x90000400 to the 0x400 address of RAM.
    • 2 Level Bootloader calls the _ c_int00 user portal program, and then calls the main function to start executing the user code

      For 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 Bootloader

      First, 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 defined

      The 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 Flash

        The 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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.