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.

片上ROM中的bootloader问题,求解决一下,急!!!



我用的TMS320C5517的评估板,配置文件如下

-boot
-v5505
-serial8


-reg_config 0x1c02,0x0000
-reg_config 0x1c03,0x0000
-reg_config 0x1c1f,0x0000
-reg_config 0x1c20,0x1000
-reg_config 0x1c21,0x0005
-reg_config 0x1c23,0x0000
-reg_config 0x1c22,0x0010
-reg_config 0x1c20,0x6300
-delay 0xfffe
-reg_config 0x1c1f,0x0001


-reg_config 0x1c00,0x1400
-reg_config 0x1c1e,0x0001
-delay 0xffff
-reg_config 0x1c04,0x0020
-reg_config 0x1c05,0x0002
-delay 0x200
-reg_config 0x1c1e,0x0001
-reg_config 0x1c33,0x0000
-reg_config 0x1020,0x4510
-reg_config 0x1021,0x3911
-reg_config 0x103c,0x000b
-reg_config 0x100c,0x030d
-reg_config 0x1008,0x4720
-reg_config 0x1009,0x0001
-delay 0x200
-reg_config 0x100c,0x030d
-delay 0x200

-b
-o .\CSL_I2S_AudioCodec_DMA.bin
.\CSL_I2S_AudioCodec_DMA.out

我将生成的bin文件烧到了到了板子上的mcspi_flah上,bootloader无法正常加载程序,但是将配置文件里的-reg_config 0x1c05,0x0002去掉,也就是不复位EMIF接口,就可以正常工作,这是为什么啊?

补充一下,因为以后想在外部的SDRAM运行程序,所以需要在bootloader中将,EMIF接口配置好。但是发现只要在配置文件中一复位EMIF接口,bootloader就无法加载映像文件,使用给的bootdemo的例子也试过只要在配置文件中复位EMIF接口就无法正常加载,使用仿真看过bootload一直在下面的程序中循环:

ff4709: a9511815 MOV port(#01815h),AR1
ff470d: 5290 MOV AR1,HI(AC0)
ff470f: da51001814 OR port(#01814h),AC0,AC0
ff4714: 0410f2 BCC #0xff4709,AC0 != #0

  • ROM bootloader初始化时会enable timer, 在reset EMIF口的同时,也reset了timer, 所以会一直在上面那段读timer寄存器的代码里运行。这个要写二次bootloader来避免。请参考下面的E2E上的帖子。
    https://e2e.ti.com/support/dsp/c5000/f/109/p/148852/539641#539641
    https://e2e.ti.com/support/dsp/c5000/f/109/p/132583/480099#480099

  • 我写过一个二次bootloader,是用C语言写的,仿真的时候后可以正常的引导我烧到mcspi flash中的bin文件,但是我把这个二次bootloader的bin文件烧到nor flash中,然后用ROM的中的bootloader加载二次bootloader再加载mcspi flash中的bin程序就出错了,后来发现是ROM中的bootloader加载二次bootloader后,二次bootloader运行出错,程序一运行到二次bootloader的mcspi初始化程序就会出错,不进行mcspi 初始化程序,二次bootloader可以正常运行,但是由于没有初始化mcspi所以也不会正确加载mcspi中的bin文件,但是二次bootloader确实正确运行起来了。这个很奇怪,我仿真的时候二次bootloader是可以正常工作的,我的mcspi初始化如下:

    #define SYS_PRCNTR *(volatile ioport Uint16*)(0x1c04)
    #define SYS_PRCNTRLR *(volatile ioport Uint16*)(0x1c05)

    #define MCSPI_BASE                  0x3400

    #define MCSPI_MODULCTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x128 )
    #define MCSPI_CH0CONFL *(volatile ioport Uint16*)( MCSPI_BASE + 0x12C )
    #define MCSPI_CH0CONFU *(volatile ioport Uint16*)( MCSPI_BASE + 0x12D )

    void spirom_init( )
    {

    volatile unsigned int i;
    /* Reset SPI */

    SYS_PRCNTR = 0x20;
    SYS_PRCNTRLR |= 0x0020;
    for(i = 0; i < 0x200; i++)
    asm(" nop");

    /* Configure MCSPI Module */
    MCSPI_MODULCTRLL = 0
    | ( 0 << 8 ) // Data managed by MCSPI_TX(i) and MCSPI_RX(i) registers
    | ( 0 << 7 ) // Multiple word access disabled
    | ( 0 << 4 ) // No delay for first spi transfer
    | ( 0 << 3 ) // Functional mode
    | ( 0 << 2 ) // Master
    | ( 0 << 1 ) // SPIEN is used as a chip select
    | ( 1 << 0 );// Only one channel will be used in master mode


    MCSPI_CH0CONFL = 0
    | ( 0 << 15 ) // DMA Read Request disabled
    | ( 0 << 14 ) // DMA Write Request disabled
    | ( 0 << 12 ) // Transmit and Receive mode
    | ( 7 << 7 ) // SPI word length = 8
    | ( 1 << 6 ) // SPIEN is held high during the active state
    | ( 8 << 2 ) // CLKD = 8 Clock devider
    | ( 0 << 1 ) // SPICLK is held high during the active state
    | ( 0 << 0 );// Data are latched on even numbered edges of SPICLK

    MCSPI_CH0CONFU = 0
    | ( 0 << 13 ) // Clock divider granularity of power of two
    | ( 1 << 12 ) // The buffer is used to receive data
    | ( 1 << 11 ) // The buffer is used to transmit data
    | ( 1 << 9 ) // 1.5 cycles between CS toggling and first or last edge of SPI clock
    | ( 0 << 8 ) // Start bit polarity
    | ( 0 << 7 ) // Disable start bit
    | ( 0 << 4 ) // SPIEN active between SPI words
    | ( 0 << 3 ) // Turbo is deactivated
    | ( 1 << 2 ) // Data Line0 selected for reception
    | ( 1 << 1 ) // Data Line1 selected for transmission
    | ( 0 << 0 );// No transmission on Data Line0


    /* Enable MCSPI channel */
    MCSPI_MODULCTRLL = 0x01; // Enable Channel

  • 建议用汇编写二次bootloader,应用程序中的_c_int00中才会建立C语言环境。

  • 好的,我试一试,多谢帮助

  • 不好意思,现在是我的二次bootloader没有运行起来,我测试时是在spirom_init( );后面跟了一个死循环循闪烁led灯,我注释掉spirom_init( )led可以闪烁,加上spirom_init( )就不行了,这是为什么?我现在是不太明白这个是为什么,二次bootloader我会用汇编试一试。

    /* Initialize the SPI interface */
    spirom_init( );
    for(i = 0; i < 0xff; i++)
    asm(" nop");

    #if 1
    while(1)
    {
    asm(" bset XF");
    asm(" nop");
    for(j = 0; j < 100; j++)
    for(i = 0; i < 100000; i++ );

    asm(" bclr XF");
    asm(" nop");
    for(j = 0; j < 100; j++)
    for(i = 0; i < 50000; i++ );
    }
    #endif

  • 是进不了spirom_init( );这个函数?

  • 能进这个函数,只要一访问mcspi的寄存器程序就死了不能往下走了

  • ROM bootloader里已经对McSPI初始化过了,二次bootloader是要做怎么样的McSPI初始化?

  • 我的二次bootloader烧到nor flash里了,ROM bootl 也会初始化mcspi吗?

  • 我的mcspi初始化如下

    void spirom_init( )
    {

    volatile unsigned int i;
    /* Reset SPI */

    SYS_PRCNTR = 0x20;
    SYS_PRCNTRLR |= 0x0020;
    for(i = 0; i < 0x200; i++)
    asm(" nop");

    /* Configure MCSPI Module */
    MCSPI_MODULCTRLL = 0
    | ( 0 << 8 ) // Data managed by MCSPI_TX(i) and MCSPI_RX(i) registers
    | ( 0 << 7 ) // Multiple word access disabled
    | ( 0 << 4 ) // No delay for first spi transfer
    | ( 0 << 3 ) // Functional mode
    | ( 0 << 2 ) // Master
    | ( 0 << 1 ) // SPIEN is used as a chip select
    | ( 1 << 0 );// Only one channel will be used in master mode


    MCSPI_CH0CONFL = 0
    | ( 0 << 15 ) // DMA Read Request disabled
    | ( 0 << 14 ) // DMA Write Request disabled
    | ( 0 << 12 ) // Transmit and Receive mode
    | ( 7 << 7 ) // SPI word length = 8
    | ( 1 << 6 ) // SPIEN is held high during the active state
    | ( 8 << 2 ) // CLKD = 8 Clock devider
    | ( 0 << 1 ) // SPICLK is held high during the active state
    | ( 0 << 0 );// Data are latched on even numbered edges of SPICLK

    MCSPI_CH0CONFU = 0
    | ( 0 << 13 ) // Clock divider granularity of power of two
    | ( 1 << 12 ) // The buffer is used to receive data
    | ( 1 << 11 ) // The buffer is used to transmit data
    | ( 1 << 9 ) // 1.5 cycles between CS toggling and first or last edge of SPI clock
    | ( 0 << 8 ) // Start bit polarity
    | ( 0 << 7 ) // Disable start bit
    | ( 0 << 4 ) // SPIEN active between SPI words
    | ( 0 << 3 ) // Turbo is deactivated
    | ( 1 << 2 ) // Data Line0 selected for reception
    | ( 1 << 1 ) // Data Line1 selected for transmission
    | ( 0 << 0 );// No transmission on Data Line0


    /* Enable MCSPI channel */
    MCSPI_MODULCTRLL = 0x01; // Enable Channel

  • 附上我二次bootloader的所有代码

    /*
    * boo.h
    *
    * Created on: 2015-8-28
    * Author: lsxxjx
    */

    #ifndef __BOOT_H__
    #define __BOOT_H__

    //#include ""

    #define SPIROM_SIZE 0x00008000
    #define SPIROM_BASE 0x00000000
    #define SPIROM_PAGESIZE 256
    #define SPIROM_SECTORSIZE 4096
    #define SPIROM_PAGEMASK 0xffffff00
    #define SPIROM_SECTORMASK 0xfffff000

    #define Uint32 unsigned long
    #define Uint16 unsigned short
    #define Uint8 unsigned char
    #define Int32 int
    #define Int16 short
    #define Int8 char


    /* ------------------------------------------------------------------------ *
    * System Module *
    * ------------------------------------------------------------------------ */
    #define SYS_EXBUSSEL *(volatile ioport Uint16*)(0x1c00)
    #define SYS_PCGCR1 *(volatile ioport Uint16*)(0x1c02)
    #define SYS_PCGCR2 *(volatile ioport Uint16*)(0x1c03)
    #define SYS_PRCNTR *(volatile ioport Uint16*)(0x1c04)
    #define SYS_PRCNTRLR *(volatile ioport Uint16*)(0x1c05)
    #define SYS_GPIO_DIR0 *(volatile ioport Uint16*)(0x1c06)
    #define SYS_GPIO_DIR1 *(volatile ioport Uint16*)(0x1c07)
    #define SYS_GPIO_DATAIN0 *(volatile ioport Uint16*)(0x1c08)
    #define SYS_GPIO_DATAIN1 *(volatile ioport Uint16*)(0x1c09)
    #define SYS_GPIO_DATAOUT0 *(volatile ioport Uint16*)(0x1c0a)
    #define SYS_GPIO_DATAOUT1 *(volatile ioport Uint16*)(0x1c0b)
    #define SYS_OUTDRSTR *(volatile ioport Uint16*)(0x1c16)
    #define SYS_SPPDIR *(volatile ioport Uint16*)(0x1c17)
    #define CCR1 *(volatile ioport Uint16*)(0x1c1e)
    #define CCR2 *(volatile ioport Uint16*)(0x1c1f)
    #define PMR *(volatile ioport Uint16*)(0x1c20)
    #define PICR *(volatile ioport Uint16*)(0x1c21)
    #define PCR *(volatile ioport Uint16*)(0x1c22)
    #define PODCR *(volatile ioport Uint16*)(0x1c23)
    #define ESCR *(volatile ioport Uint16*)(0x1c33)
    #define ICR *(volatile ioport Uint16*)(0x0001)

    #define IER0 *(volatile Uint16*)(0x0000)
    #define IFR0 *(volatile Uint16*)(0x0001)
    #define ST1_55 *(volatile Uint16*)(0x0003)
    #define IER1 *(volatile Uint16*)(0x0006)
    #define IFR1 *(volatile Uint16*)(0x0007)

    /* ------------------------------------------------------------------------ *
    * EMIF Module *
    * ------------------------------------------------------------------------ */
    #define SDTIMR1 *((volatile ioport Uint16*)(0x1020))
    #define SDTIMR2 *((volatile ioport Uint16*)(0x1021))
    #define SDCR1 *((volatile ioport Uint16*)(0x1008))
    #define SDCR2 *((volatile ioport Uint16*)(0x1009))
    #define SDSRETR *((volatile ioport Uint16*)(0x103C))
    #define SDRCR *((volatile ioport Uint16*)(0x100C))

    /* ------------------------------------------------------------------------ *
    * SPI ROM Commands *
    * ------------------------------------------------------------------------ */
    #define SPIROM_CMD_WRSR 0x01
    #define SPIROM_CMD_WRITE 0x02
    #define SPIROM_CMD_READ 0x03
    #define SPIROM_CMD_WRDI 0x04
    #define SPIROM_CMD_RDSR 0x05
    #define SPIROM_CMD_WREN 0x06
    #define SPIROM_CMD_ERASESEC 0x20
    #define SPIROM_CMD_UNPROTECTSEC 0x39

    /* ------------------------------------------------------------------------ *
    * SPIOCP Module *
    * ------------------------------------------------------------------------ */
    #define MCSPI_BASE 0x3400
    #define MCSPI_REVISION *(volatile ioport Uint16*)( MCSPI_BASE + 0x100 )
    #define MCSPI_SYSCONFIGL *(volatile ioport Uint16*)( MCSPI_BASE + 0x110 )
    #define MCSPI_SYSSTATUSL *(volatile ioport Uint16*)( MCSPI_BASE + 0x114 )
    #define MCSPI_IRQSTATUSL *(volatile ioport Uint16*)( MCSPI_BASE + 0x118 )
    #define MCSPI_IRQSTATUSU *(volatile ioport Uint16*)( MCSPI_BASE + 0x119 )
    #define MCSPI_IRQENABLEL *(volatile ioport Uint16*)( MCSPI_BASE + 0x11C )
    #define MCSPI_IRQENABLEU *(volatile ioport Uint16*)( MCSPI_BASE + 0x11D )
    #define MCSPI_WAKEUPENABLEL *(volatile ioport Uint16*)( MCSPI_BASE + 0x120 )
    //#define MCSPI_SYST *(volatile ioport Uint16*)( MCSPI_BASE + 0x20 )
    #define MCSPI_MODULCTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x128 )
    #define MCSPI_CH0CONFL *(volatile ioport Uint16*)( MCSPI_BASE + 0x12C )
    #define MCSPI_CH0CONFU *(volatile ioport Uint16*)( MCSPI_BASE + 0x12D )
    #define MCSPI_CH0STATL *(volatile ioport Uint16*)( MCSPI_BASE + 0x130 )
    #define MCSPI_CH0CTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x134 )
    #define MCSPI_CH0TXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x138 )
    #define MCSPI_CH0TXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x139 )
    #define MCSPI_CH0RXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x13C )
    #define MCSPI_CH0RXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x13D )
    #define MCSPI_CH1CONFL *(volatile ioport Uint16*)( MCSPI_BASE + 0x140 )
    #define MCSPI_CH1CONFU *(volatile ioport Uint16*)( MCSPI_BASE + 0x141 )
    #define MCSPI_CH1STATL *(volatile ioport Uint16*)( MCSPI_BASE + 0x144 )
    #define MCSPI_CH1CTRLL *(volatile ioport Uint16*)( MCSPI_BASE + 0x148 )
    #define MCSPI_CH1TXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x14C )
    #define MCSPI_CH1TXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x14D )
    #define MCSPI_CH1RXL *(volatile ioport Uint16*)( MCSPI_BASE + 0x150 )
    #define MCSPI_CH1RXU *(volatile ioport Uint16*)( MCSPI_BASE + 0x151 )


    /* ------------------------------------------------------------------------ *
    * type define *
    * ------------------------------------------------------------------------ */

    typedef struct
    {
    unsigned char boot_signature[2];
    unsigned char entry_point[4];

    /* register configuration count */
    unsigned char reg_conf_cnt[2];
    } boot_image_head;

    typedef struct
    {
    unsigned char word_count[2];
    unsigned char load_address[4];
    } section_head;

    /* current section information*/
    typedef struct
    {
    unsigned long load_address;
    unsigned int word_count;
    unsigned int pad_size;
    } cur_section_info;

    /* flash information */
    typedef struct
    {
    /* current reading address*/
    unsigned long cur_rd_addr;
    } flash_info;


    /* ------------------------------------------------------------------------ *
    * Prototype *
    * ------------------------------------------------------------------------ */
    void spirom_init( );
    void spirom_read1( Uint32 src, Uint32 length );
    void spirom_erase( unsigned long base, unsigned long length );
    void spirom_read( unsigned long src, unsigned long dst, unsigned long length );
    void spirom_write( unsigned long src, unsigned long dst, unsigned long length );
    void set_PLL_100Hz(void);
    void EMIF_SDRAM_Init(void);
    unsigned int get_pad_size(unsigned int cword_of_section);

    #endif /* __BOOT_H__ */

    /*
    * main.c
    *
    * Created on: 2015-8-28
    * Author: lsxxjx
    */

    #include "boot.h"
    #include "stdio.h"
    //#include "evm5517.h"

    //Int16 EVM5517_I2CGPIO_configLine( Uint16 line, Uint16 dir );
    //Int16 EVM5517_I2CGPIO_writeLine( Uint16 line, Uint16 val );

    static unsigned char spirombuf[SPIROM_PAGESIZE + 5];
    static unsigned char statusbuf[8];


    void (*enter_new_point)(void);

    boot_image_head *boot_image_head_p;
    section_head *section_head_p;

    flash_info flash_info_r;

    cur_section_info cur_section_info_r;

    /*
    *
    * main
    *
    */
    void main( )
    {
    volatile unsigned long i;
    volatile unsigned long j;


    ICR = 0x000E;
    asm(" idle");

    /* Disable global interrupts */
    asm("\tNOP ;====> CODE AUTO-GENERATED by CSL");
    asm("\tBSET INTM ;====> CODE AUTO-GENERATED by CSL");

    /* Disable all the interrupts */
    //IER0 = 0x0000;
    //IER1 = 0x0000;

    /* Clear any pending interrupts */
    //IFR0 = 0xFFFF;
    //IFR1 = 0xFFFF;


    SYS_PCGCR1 = 0x0000;
    SYS_PCGCR2 = 0x0000;

    set_PLL_100Hz();
    EMIF_SDRAM_Init();

    /* Configure EBSR for McSPI */
    SYS_EXBUSSEL &= ~0x0C00; // Clear SP1MODE
    SYS_EXBUSSEL |= 0x0400; // Set SP1MODE to McSPI


    /* Initialize the SPI interface */
    spirom_init( );
    for(i = 0; i < 0xff; i++)
    asm(" nop");

    #if 1
    while(1)
    {
    asm(" bset XF");
    asm(" nop");
    for(j = 0; j < 100; j++)
    for(i = 0; i < 100000; i++ );

    asm(" bclr XF");
    asm(" nop");
    for(j = 0; j < 100; j++)
    for(i = 0; i < 50000; i++ );
    }
    #endif

    //flash_info_r.cur_rd_addr = 1726;
    flash_info_r.cur_rd_addr = 0;

    /* read the boot image file's head */
    spirom_read1( flash_info_r.cur_rd_addr, sizeof(boot_image_head));

    boot_image_head_p = (boot_image_head *)(spirombuf + 4);

    if(boot_image_head_p->boot_signature[0] == 0x09
    && boot_image_head_p->boot_signature[1] == 0xaa)
    {

    flash_info_r.cur_rd_addr += sizeof(boot_image_head);

    /* get boot image file's entry point */
    enter_new_point = (void(*)(void))((unsigned long)boot_image_head_p->entry_point[0] << 24
    | (unsigned long)boot_image_head_p->entry_point[1] << 16
    | (unsigned long)boot_image_head_p->entry_point[2] << 8
    | (unsigned long)boot_image_head_p->entry_point[3]);

    /* ignore the register configuration informaton */
    flash_info_r.cur_rd_addr += ((unsigned long)boot_image_head_p->reg_conf_cnt[0] << 8 |
    boot_image_head_p->reg_conf_cnt[1]) << 2;

    /* load section data */
    for(;;)
    {
    /* read a secion's head */
    spirom_read1( flash_info_r.cur_rd_addr, sizeof(section_head));

    flash_info_r.cur_rd_addr += sizeof(section_head);

    section_head_p = (section_head *)(spirombuf + 4);

    cur_section_info_r.word_count = ((unsigned int)section_head_p->word_count[0] << 8
    | (unsigned int)section_head_p->word_count[1]);
    cur_section_info_r.load_address = ((unsigned long)section_head_p->load_address[0] << 24
    | (unsigned long)section_head_p->load_address[1] << 16
    | (unsigned long)section_head_p->load_address[2] << 8
    | (unsigned long)section_head_p->load_address[3]);

    if(cur_section_info_r.word_count == 0)
    break;

    cur_section_info_r.pad_size = get_pad_size(cur_section_info_r.word_count);

    while(cur_section_info_r.word_count > 0)
    {
    if(cur_section_info_r.word_count > 128)
    {
    spirom_read1( flash_info_r.cur_rd_addr, 256);

    for(i = 0; i < 128; i++)
    {
    *(unsigned int *)(cur_section_info_r.load_address + i)
    = (unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2)) << 8
    |(unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2 + 1));
    }

    flash_info_r.cur_rd_addr += 256;
    cur_section_info_r.word_count -= 128;
    cur_section_info_r.load_address += 128;
    }
    else
    {
    spirom_read1( flash_info_r.cur_rd_addr, cur_section_info_r.word_count << 1);

    for(i = 0; i < cur_section_info_r.word_count; i++)
    {
    *(unsigned int *)(cur_section_info_r.load_address + i)
    = (unsigned int)(*(unsigned char *)(spirombuf + 4 + i * 2)) << 8
    |(*(unsigned char *)(spirombuf + 4 + i * 2 + 1));
    }

    flash_info_r.cur_rd_addr += (unsigned long)cur_section_info_r.word_count << 1;
    cur_section_info_r.word_count = 0;
    }
    }
    flash_info_r.cur_rd_addr += cur_section_info_r.pad_size;

    }

    enter_new_point();
    }

    }

    /*
    * get the byte sizes of pad data
    */
    unsigned int get_pad_size(unsigned int cword_of_section)
    {
    unsigned long cbyte_of_section;
    unsigned long cbyte_alignment;

    cbyte_of_section = ((unsigned long)cword_of_section + 2) << 1;

    //return ((cbyte_of_section & 0x7 > 0 ? cbyte_of_section & 0xFFFFFFF8 + 0x8 : cbyte_of_section) - cbyte_of_section);
    cbyte_alignment = (cbyte_of_section + 0x7) & ~0x7;
    return cbyte_alignment - cbyte_of_section;

    }


    void set_PLL_100Hz(void)
    {
    volatile unsigned int i;

    /* Enable clocks to all peripherals */
    SYS_PCGCR1 = 0x0000;
    SYS_PCGCR2 = 0x0000;

    /* Bypass PLL */
    CCR2 = 0x0000;

    /* Turn off PLL */
    PMR = 0x1000;

    /* For CLKIN = 12MHz */
    PICR = 0x0005; // Enable reference divider = 2+1
    PODCR = 0x0000; // Output divider = 0
    PCR = 0x0010;
    PMR = 0x6300;// Multiplier = 99*256+1

    /* Wait for PLL lock (atleast 4ms)*/
    for(i=0;i<0x7fff;i++)
    asm(" nop");

    /* Switch to PLL clk */
    CCR2 = 0x1;
    }

    void EMIF_SDRAM_Init(void)
    {
    volatile unsigned int i;


    /* configure EBSR for EMIF */
    SYS_EXBUSSEL |= 0x1000;
    /* enable the EM_SDCLK */
    CCR1 |= 0x0001;
    for(i = 0; i < 0x200; i++)
    asm(" nop");

    /* reset the EMIF */
    SYS_PRCNTR = 0x20;
    SYS_PRCNTRLR |= 0x0002;
    for(i = 0; i < 0x200; i++)
    asm(" nop");
    /* enable word writes to EMIF*/
    ESCR = 0x0000;
    //-reg_config 0x1c1e,0x0001

    /* step 1 */
    SDTIMR1 = 0x4510;
    SDTIMR2 = 0x3911;
    SDSRETR = 0x000b;

    /* step 2 */
    SDRCR = 0x030d;

    /* step 3 */
    SDCR1 = 0x4720;
    SDCR2 = 0x0001;

    /* step 4 */
    for(i = 0; i < 0x200; i++)
    asm(" nop");

    /* step 5 */
    SDRCR = 0x030d;
    }

    /* ------------------------------------------------------------------------ *
    * spirom_init( ) *
    * ------------------------------------------------------------------------ */
    void spirom_init( )
    {

    volatile unsigned int i;
    /* Reset SPI */
    //MCSPI_SYSCONFIGL |= 0x02; // Bit is automatically reset by hardware
    /* Wait for reset to complete */
    //while(MCSPI_SYSSTATUSL & 0x01 == 0x00);
    SYS_PRCNTR = 0x20;
    SYS_PRCNTRLR |= 0x0020;
    for(i = 0; i < 0x200; i++)
    asm(" nop");

    /* Configure MCSPI Module */
    MCSPI_MODULCTRLL = 0
    | ( 0 << 8 ) // Data managed by MCSPI_TX(i) and MCSPI_RX(i) registers
    | ( 0 << 7 ) // Multiple word access disabled
    | ( 0 << 4 ) // No delay for first spi transfer
    | ( 0 << 3 ) // Functional mode
    | ( 0 << 2 ) // Master
    | ( 0 << 1 ) // SPIEN is used as a chip select
    | ( 1 << 0 );// Only one channel will be used in master mode


    MCSPI_CH0CONFL = 0
    | ( 0 << 15 ) // DMA Read Request disabled
    | ( 0 << 14 ) // DMA Write Request disabled
    | ( 0 << 12 ) // Transmit and Receive mode
    | ( 7 << 7 ) // SPI word length = 8
    | ( 1 << 6 ) // SPIEN is held high during the active state
    | ( 8 << 2 ) // CLKD = 8 Clock devider
    | ( 0 << 1 ) // SPICLK is held high during the active state
    | ( 0 << 0 );// Data are latched on even numbered edges of SPICLK

    MCSPI_CH0CONFU = 0
    | ( 0 << 13 ) // Clock divider granularity of power of two
    | ( 1 << 12 ) // The buffer is used to receive data
    | ( 1 << 11 ) // The buffer is used to transmit data
    | ( 1 << 9 ) // 1.5 cycles between CS toggling and first or last edge of SPI clock
    | ( 0 << 8 ) // Start bit polarity
    | ( 0 << 7 ) // Disable start bit
    | ( 0 << 4 ) // SPIEN active between SPI words
    | ( 0 << 3 ) // Turbo is deactivated
    | ( 1 << 2 ) // Data Line0 selected for reception
    | ( 1 << 1 ) // Data Line1 selected for transmission
    | ( 0 << 0 );// No transmission on Data Line0


    /* Enable MCSPI channel */
    MCSPI_MODULCTRLL = 0x01; // Enable Channel
    }

    /*
    * spirom_cycle( buf, len )
    *
    * Execute a SPI spirom data transfer cycle. Each byte in buf is shifted
    * out and replaced with data coming back from the spirom.
    */
    void spirom_cycle( Uint8 *buf, Uint16 len )
    {
    Uint16 i;

    /* Enable Channel */
    MCSPI_CH0CTRLL = 0x01;
    /* SPIROM access cycle */
    MCSPI_CH0CONFU |= 0x0010;
    for ( i = 0 ; i <= len ; i++ )
    {

    /* Wait for transmit empty */
    while ( (MCSPI_CH0STATL & 0x02) == 0 );
    MCSPI_CH0TXL = buf[i]; // Write to RX buffer 0 ??? Use upper register
    /* Wait for receive data full */
    while ( (MCSPI_CH0STATL & 0x01) == 0 );
    buf[i] = MCSPI_CH0RXL; // Read from RX buffer 0 ??? Use upper register

    }
    MCSPI_CH0CONFU &= ~0x0010;
    /* Disable Channel */
    MCSPI_CH0CTRLL = 0x00;
    }

    /*
    * spirom_status( )
    */
    Uint8 spirom_status( )
    {
    /* Issue read status command */
    statusbuf[0] = SPIROM_CMD_RDSR;
    statusbuf[1] = 0;

    spirom_cycle( statusbuf, 2 );

    return statusbuf[1];
    }


    void spirom_read1( Uint32 src, Uint32 length )
    {
    // Setup command
    spirombuf[0] = SPIROM_CMD_READ;
    spirombuf[1] = ( src >> 16 );
    spirombuf[2] = ( src >> 8 );
    spirombuf[3] = ( src >> 0 );

    // Execute spirom read cycle
    spirom_cycle( spirombuf, length + 4 );
    }f

  • 请试试把二次bootloader也烧写到McSPI flash,看是否能避免此问题。

  • 1、试过,二次bootloader可以加载应用程序,但是应用程序运行一部分后,应用程序会出问题。起码这说明我的二次bootloader可以在mcspiflash中正常运行起来,但是奇怪的就是为什么在nor flash中却不行。

    2、我还有一个不明白的地方就是,您说用汇编写二次bootloader,应用的_c_int0()才可以正确初始C环境。我用C语言写的二次bootloader为什么仿真的时候可以正确的加载应用程序,应用程序可以正常运行,这时_c_int0()为什么可以正确初始C运行环境。_c_int0()执行时是根据什么判断要不要初始C环境,我的理解是我的二次bootloader将应用加载好后,这时的控制权就完全交给应用了,应用是通过什么判断要不要初始C环境,难道有专门的寄存器?

  • _c_int00的源代码可以参考C:\ti\ccsv5\tools\compiler\c5500_4.4.1\lib\rtssrc里的boot.asm,主要是初始化stack, heap, SP建立C语言环境,最后去call main函数。

    如果你的二次bootloader也用c写,会调用_c_int00,  你的应用程序里又会调用_c_int00, 相当于调用了两次_c_int00,你试试二次bootloader改用汇编,看应用程序能否跑起来。

  • 可是我的二次bootloader和应用是独立的啊,它们分别链接自己的_c_int00啊?您有二次bootloader汇编的例子吗,我参考一下?还有就是第一个问题是怎么回事啊,很奇怪

  • 这里有篇老的c54x的二次bootloader文档,可以参考一下。
    http://www.ti.com/lit/an/spra773/spra773.pdf

  • 谢谢,我再研究一下吧