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.

some issues about boot project in tci66x



2146.newhw66.zip

Hi Expert

The attach is the project which I boot the 6614 EVM from EMAC,  I found some problems.

Two months ago ,I successfully boot the 6614 EVM from EMAC, but now I meet some troubles.

the only differences are belows.

about the main functions,two months ago, the complier will console errors if there is not main function .

but recently, the complier will noy console errors if there is not main function.

and if  I put the main function in a individual C file , I will not find the main fuction in map file,but if I add  the main function in the other C file ,I will find the main in the map file.

Could you help me solve these problems?

Brs

  Winston

  • could TI expert help me solve this problem?

    Thanks very much!

  • Hi,

    It seems to me that your _c_int00() don't call main or other compiler initialization rotuines, so the linker doesn't link it in. If you add it to another C file, it link main() simple as part of it but nobody call it.

    Normally your override of the default library  _c_int00() should call _auto_init_elf() (or _auto_init() for COFF) that will initiliazed bss, data. C++ ctor, and then call main().

    To be sure to be compliant with the compiler library, I use a custom boot routine, not named _c_int00(), that call the library _c_int00 and I say to the linker that the entry point is my custom routine and not the default _c_int00().

  • Hi

    I still do not know,why the  linker can not link  the main function   after it finished the _c_int00().

    should I add a library or change the compiler setting? please give me some details?

    or if I still use _c_int00() as the entry ,is there any soultion which the link can link the main fuction in the map file ?

    and ,you mean ,I can change the _c_int00() function to my custom function ,such as" _my_c_int00 ", and change  the "rmd" file , from "-e _c_int00" to " -e _ my_c_int00"

    Brs

    Winston

  • Hi 

    if I change the" _c_int00() "to " _c_e_int00", I can not find _c_e_int00 in the map file .

    Brs

    Winston

  • Hi

    I change the" _c_int00() "to " _c_e_int00", I can not find _c_e_int00 in the map file .  and change the rmd file, but I still can not boot the EVMboard.

    two months ago ,I successfully boot the EVM6614 board from EMAC just using the same boot project.

    Maybe I need to change some build options. could you give me some more details?

    lists are about my complier options:

    -mv6600 -g -O3 -ms3 --include_path="C:/ti/ccsv5/tools/compiler/c6000/include" --include_path="C:/workspacev1/newhw66/newhw66/csl_6614" --include_path="C:/ti/pdk_tci6614_1_00_00_04/packages" --include_path="C:/ti/pdk_tci6614_1_00_00_04/packages/ti/csl" --display_error_number --diag_warning=225 --abi=eabi

    about link options:

    -mv6600 -g -O3 -ms3 --display_error_number --diag_warning=225 --abi=eabi -z -m"newhw66.map" --warn_sections -i"C:/ti/ccsv5/tools/compiler/c6000/lib" -i"C:/ti/ccsv5/tools/compiler/c6000/include" --reread_libs --rom_model

    Brs

    Winston

  • winston xue said:

    I still do not know,why the  linker can not link  the main function   after it finished the _c_int00().

    The linker remove the unused functions, that iis the functions not called by any other function. The main function is not magic: the compiler don't generate any special code to call it.

    Everithing begins from the entry function specified tothe linker, default _c_int00.. The default version (from compiler library) does various initialization that terminates in a call to main(), that force the linker to include the main and so on (in case of C++ there are some global object constructor that can be automatically linked and called before main, as part of the initialization done by _c_int00).

    If you include in your project a function named _c_int00(), the linker resolve the entry point to your function and don't include the library one, so all the initialization, including a final invokation of main(), should be done by your function.

    In your code I didn't see any call to main() and to the other library function required to perform the initializaiton required to correcly run a C program. See the compiler manual for details and compiler library source code for c_int00().

    I suggest to get the compiler supplied version of c_int00() and add there your initialization, even if IMHO the best practice is too write a separate routine:

    extern far void _c_int00();  //get it from the compiler library

    void my_c_int00()

    {

       .... your initialization here....

      _c_int00();  //call the library version to finish initialization and call main

    }

    And in the linker command file:  --entry_point=my_c_int00

  • Hi Alberto Chessa

    Thanks for your reply, after follow your steps ,I successfully compiler the project ,and I can successfully initial the DDR3 control by loading the code from JTAG .

    But still can not boot the EVM board from EMAC.

    I just follow these steps

    the rmd file in core0

    "newhw66.out"
    -a
    -boot
    -e _c_int00
    -order L

    ROMS
    {
    ROM1: org= 0x0400, length = 0x100000, memwidth = 32, romwidth = 32
    files = { hw_init66.btbl }
    }

    rmd file in core1,just for test

    "ddr3test.out"
    -a
    -boot
    -e _c_int00
    -order L

    ROMS
    {
    ROM1: org= 0x0400, length = 0x100000, memwidth = 32, romwidth = 32
    files = { ddr3_hw_init66.btbl }
    }

    and the use the tools supported by TI   

    C:\ti\ccsv5\tools\compiler\c6000\bin\hex6x hw_init66.rmd
    C:\ti\ccsv5\tools\compiler\c6000\bin\hex6x ddr3testcore0.rmd
    C:\ti\ccsv5\tools\compiler\c6000\bin\hex6x ddr3testcore1.rmd
    C:\ti\ccsv5\tools\compiler\c6000\bin\hex6x ddr3testcore2.rmd
    C:\ti\ccsv5\tools\compiler\c6000\bin\hex6x ddr3testcore3.rmd
    C:\ti\ccsv5\tools\compiler\c6000\bin\mergebtbl hw_init66.btbl ddr3testcore0.btbl ddr3testcore1.btbl ddr3testcore2.btbl wholetest.btbl
    C:\ti\ccsv5\tools\compiler\c6000\bin\bconvert64x -le wholetest.btbl wholetest.btbl.be
    C:\ti\ccsv5\tools\compiler\c6000\bin\bootpacket wholetest.btbl.be wholetest.eth 00-18-31-7e-48-e9 d4-85-64-95-93-07

    after generate the wholetest.eth file ,I send the packet using pcsend,exe  to EVMboard.

    two months ago ,after I did these steps ,I just connect the board , and look for the memory brower and seach the address I write in DDR3. it always right with the code I wote in boot project.

    what I confused is why I can not success do these now?

    Brs 

    Winson

  • and I also change the "  -e my_c_int00"  in rmd file.

  • Hi,

    Do you build with "rom autonitialization" or "ram autoinitialization" model? From your map file it seem to me that you use the rom autoinitialization.

    In this case, when executing your initialization routine (and any oher routine called from them, including library routine printf) the data sections (both initialized and zero filled) are not yet ready (they are initialized as part of _c_int00()).

    For instance, the pointer to the boot_cfg_regs is not yet initialized when you use it.

    So you can try the ram autoinitialization or remove all reference to routine not needed by the initialization (mainly printf) and explicitally initialize the required variable priot to call the PLL init routines (essentially move the "boot_cfg_regs=..." and company at the beginning of my-c_int00()).

    Pay attenation that you can not assume that non initialized variable are set to 0. Also the stack is not initialized but in this case you can use the stack coming from the boot loader is it don't overlap the memory aread used by your code on L2 (see bootloader manual about this).

  • I'm not sure what is going on, but I'll take a guess.  All the advice from Mr. Chessa is correct.  Please note Mr. Chessa is suggesting changes in how the linker is invoked.  It appears Mr. Xue is applying those changes not to the linker, but to the hex utility.  The hex utility runs after the linker to convert the executable .out file from a binary object file format (COFF or ELF) to a hex format the next tool used (not from TI) can handle.  

    Thanks and regards,

    -George

  • Hi Mr.Chessa &Mr.MOCK

    I know, the program have not enter the  absolutely C environment  before the entry of _c_int00(), it is better to write the DDR3 initialize code in assembly language ,but maybe  it is hard for me . there are some differences about bootloader between 64x and 66x DSP.

    Frankly speaking, I have not found a way to initialize the DDR3 control registers.

    you mean,the variable pointer can not be used befor _c_int00()?

    How can I get these knowledge about  what is on before _c_int00?

    Can I do like this?

    #define CSL_BOOT_CFG_REGS        (0x02620000)

     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[2] = 0x20;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[3] = 0x24;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[4] = 0x3A;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[5] = 0x38;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[6] = 0x51;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[7] = 0x5E;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[8] = 0x5E;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[9] = 0x5E;
     ((CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)->DDR3_CONFIG_REG[10]= 0x44;

    ...............

    and the same way I changed   "DDR_Regs".  also I delete the printf() function.

    What important is  could you please share me  a bootloader project about 66x  , I want to refer the best way to initilize the DDR3 and boot from EMAC.

    Brs

    Winston

  • Hi,

    Assembly is not required. To debug this kind of problem I suggest to:

    • Write a very simple start up routine (see below) that invoke main (I choose main() simple since CCS automatically stop there when you lunch a debug session)
    • Inside main place you DDR initialization code and at the end the write to a DDR address
    • Command the linker to use your simple startup routine as entry point
    • Build and verify that the memory area used by your code doesn't overlap the RBL memory in L2 (see boot loader documentation)
    • With CCS on the EVM in EMAC boot or EMIF16 no boot, start a debug session (and start without an initialization GEL file)
    • When CCS breaks at the beginning of main, open a memory browser window at 0x80000000 and verify that if you try  writes (from the memory windows)  to DDR fails (that is the value display don't match your write  and if you refresh the memory windows the values change randomly. This is to verify that the DDR is not initialized)
    • Continue the execution and break at the end of main (where you try to write to DDR). With the CCS memory window you can verify if it works or not.

    The simple startup routine is:


    #include <c6x.h>

    __asm("\t.global __TI_STACK_END");
    __asm("\t.global __TI_STATIC_BASE");

    #pragma DATA_ALIGN   (_stack, 8);
    #pragma DATA_SECTION (_stack, ".stack");
    char _stack[8];

    extern void main(void);

    extern void bare_c_int00()
    {
      __asm("\t   MVKL\t\t   __TI_STACK_END - 4, SP");
      __asm("\t   MVKH\t\t   __TI_STACK_END - 4, SP");
      __asm("\t   AND\t\t   ~15,SP,SP");
      __asm("\t   MVKL\t\t   __TI_STATIC_BASE,DP");
      __asm("\t   MVKH\t\t   __TI_STATIC_BASE,DP");

      main();
    }


    To access the DDR config without touch to much your code, do somethins like:

    #define boot_cfg_regs  ((volatile CSL_BootcfgRegs *)CSL_BOOT_CFG_REGS)

    The same for the other control register (DDR_Regs, pllc_regs, DSP_Core_Clock_KHz, ...).  You can verify if you are indipendent on the data and bss initiliazation (that is not executed by my example) by looking at the linker memory map: all data section but the stack should have size = 0 (.bss, .fardata, .data, .cinit, ...). Also in the code linked you should see only your 2 routine and nothing else from the C compiler library.

    When this work you can change the name of the main in something else and modifiy the startup routine:

    ...

    ddr_init();   //was main()

    _c_int00(); //ok, continue with initialization fron C compiler libry that will invoke main()

    }

    And return to your original project.

    Anyway consider that if in the future you allocate something on the DDR, the EMAC boot will fails since when you try to load it the DDR is not initialized (your code has not yet run). About this problem there are some old discussion in the forum.

  • Hi Mr.Chessa

    Thanks for you reply,follow your steps ,I debug the boot project . but  still failed from boot from EMAC.

    you have said:

    Anyway consider that if in the future you allocate something on the DDR, the EMAC boot will fails since when you try to load it the DDR is not initialized (your code has not yet run). About this problem there are some old discussion in the forum.

    where can I find my code is running or not?

    Brs

    Winston

  • winston xue said:

    where can I find my code is running or not?

    I'm not sure this works but I think you can try by power-on the evm and prior to send via EMCA your application connect with CCS (without a gel file and without loading an application), place an hardware  breakpoint at the address of your application entry point (at the row heaxadecimal address you find in the linker map) then continue the execution and send the file. When the CPU stop at your breakpoint load only the symbols from your application and then debug step-by-step.

    If you don't already do it, go to the C66 forum and search for "EMAC boot", you'll find some message about.

  • Hi

    I just write a simple  aassembly

       .data
       .def     someData
    someData   .word   01234ABCDh

        .def  byte1
     .sect ".byte1"
    byte1: .byte 0x12

     .def byte2
     .sect ".byte2"
    byte2: .byte 0x12, 0x34

       .text
       .def _c_int00
      
    myConst    .equ    011223344h
      
    _c_int00:

       MVKL.S1     myConst, A1
       MVKH.S1     myConst, A1

       MVKL.S1     byte1, A2
       MVKH.S1     byte1, A2
       LDB.D1    *A2, B2

       MVKL.S1     byte2, A3
       MVKH.S1     byte2, A3
       LDB.D1    *A3++, B3
       LDB.D1      *A3,   B4
      
      
    etrap:

       BNOP.S1 etrap, 5


     and boot the code to EVM from EMAC ,and  connected the EVM using JTAG, and find the A1 register is 0x011223344h.

    it seems that, 8551.hwinit66.rar.