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.

[参考译文] TMS320F28388D:如何通过 EMIF 在 SDRAM 上加载和运行用户程序

Guru**** 2589265 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1177064/tms320f28388d-how-to-load-and-run-user-program-on-sdram-over-emif

器件型号:TMS320F28388D

各位专家、您好!

我想通过 EMIF 在 SDRAM 上加载和运行特定的用户函数。

因此、我已经参考 C2000中的示例 EMIF_ex2_16bit_asram_codemm.c 来测试代码。

 作为存储器访问16位 SDRAM、例如在 SDRAM 上读取和写入特定阵列、效果良好。

但是、当尝试将 SDRAM 作为代码存储器进行访问时、它必须发生故障、从而产生以下错误。

error

  用于连接异步/同步存储器的一些配置和用户代码如下所示。

  • 用户定义的函数

#pragma CODE_SECTION(add,".sdramfunc");
#pragma CODE_SECTION(multiply,".sdramfunc");

//
// Add - This function is for reference only. It will be copied to ASRAM
// and is executed from ASRAM.
//
uint16_t add(uint16_t a, uint16_t b)
{
    return(a+b);
}

//
// Multiply - This function is for reference only. It will be copied to ASRAM
// and is executed from ASRAM.
//
uint16_t multiply(uint16_t a, uint16_t b)
{
    return(a*b);
}

  • 异步/同步配置

void setupSdramParameter(void)
{
    EMIF_SyncTimingParams tParam;
    EMIF_SyncConfig conf;
    //
    // Configure SDRAM control registers
    //
    // Need to be programmed based on SDRAM Data-Sheet.
    //T_RFC = 60ns = 0x6
    //T_RP  = 18ns = 0x1
    //T_RCD = 18ns = 0x1
    //T_WR  = 1CLK + 6 ns = 0x1
    //T_RAS = 42ns = 0x4
    //T_RC  = 60ns = 0x6
    //T_RRD = 12ns = 0x1
    //
    //Emif1Regs.SDRAM_TR.all = 0x31114610;

    tParam.tRfc = 6;
    tParam.tRp = 1;
    tParam.tRcd = 1;
    tParam.tWr = 1;
    tParam.tRas = 4;
    tParam.tRc = 6;
    tParam.tRrd = 1;
    EMIF_setSyncTimingParams(EMIF1_BASE, &tParam);

    //
    //Txsr = 70ns = 0x7
    //
    //Emif1Regs.SDR_EXT_TMNG.all = 0x7;
    EMIF_setSyncSelfRefreshExitTmng(EMIF1_BASE, 7);

    //
    //Tref = 64ms for 8192 ROW, RR = 64000*100(Tfrq)/8192 = 781.25 (0x30E)
    //
    //Emif1Regs.SDRAM_RCR.all = 0x30E;
    EMIF_setSyncRefreshRate(EMIF1_BASE, 0x30E);

    //
    //PAGESIZE=1 (512 elements per ROW), IBANK = 2 (4 BANK), CL = 2,
    //NM = 1 (16bit)
    //
    //Emif1Regs.SDRAM_CR.all = 0x00015521;
    conf.pageSize = EMIF_SYNC_COLUMN_WIDTH_9;
    conf.iBank = EMIF_SYNC_BANK_4;
    conf.casLatency = EMIF_SYNC_CAS_LAT_2;
    conf.narrowMode = EMIF_SYNC_NARROW_MODE_TRUE;

    EMIF_setSyncMemoryConfig(EMIF1_BASE, &conf);
}


void EMIF_init(void)
{
    EMIF_AsyncTimingParams tparam;
    //
    // Configure to run EMIF1 on full Rate. (EMIF1CLK = CPU1SYSCLK)
    //
    SysCtl_setEMIF1ClockDivider(SYSCTL_EMIF1CLK_DIV_2);

    //
    // Grab EMIF1 For CPU1.
    //
    EMIF_selectMaster(EMIF1CONFIG_BASE, EMIF_MASTER_CPU1_G);

    //
    // Disable Access Protection. (CPU_FETCH/CPU_WR/DMA_WR)
    //
    EMIF_setAccessProtection(EMIF1CONFIG_BASE, 0x0);

    //
    // Commit the configuration related to protection. Till this bit remains
    // set, contents of EMIF1ACCPROT0 register can't be changed.
    //
    EMIF_commitAccessConfig(EMIF1CONFIG_BASE);

    //
    // Lock the configuration so that EMIF1COMMIT register can't be changed
    // any more.
    //
    EMIF_lockAccessConfig(EMIF1CONFIG_BASE);

    //
    // Configure GPIO pins for EMIF1.
    //
    setupEMIF1PinmuxAsync16Bit(g_nMcuIndex);

    //
    // Configure for SDARM
    //
    setupSdramParameter();

    //
    // Configures Normal Asynchronous Mode of Operation.
    //
    EMIF_setAsyncMode(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET,
                      EMIF_ASYNC_NORMAL_MODE);

    //
    // Disables Extended Wait Mode.
    //
    EMIF_disableAsyncExtendedWait(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET);

    //
    // Configure EMIF1 Data Bus Width.
    //
    EMIF_setAsyncDataBusWidth(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET,
                              EMIF_ASYNC_DATA_WIDTH_16);

    //
    // Configure the access timing for CS2 space.
    //
    tparam.rSetup = 2;
    tparam.rStrobe = 5;
    tparam.rHold = 2;
    tparam.turnArnd = 0;
    tparam.wSetup = 2;
    tparam.wStrobe = 5;
    tparam.wHold = 2;
    EMIF_setAsyncTimingParams(EMIF1_BASE, EMIF_ASYNC_CS2_OFFSET, &tparam);

}

  • 链接命令

MEMORY
{
   HWBIST           : origin = 0x000000, length = 0x000020
   /* BEGIN is used for the "boot to Flash" bootloader mode   */
   RAMM0            : origin = 0x0001B1, length = 0x00024F
   RAMM1            : origin = 0x000400, length = 0x0003F8     /* on-chip RAM block M1 */
   RAMD0            : origin = 0x00C000, length = 0x000800
   RAMD1            : origin = 0x00C800, length = 0x000800
   RAMLS0           : origin = 0x008000, length = 0x000800
   RAMLS1           : origin = 0x008800, length = 0x000800
   RAMLS2           : origin = 0x009000, length = 0x000800
   RAMLS3           : origin = 0x009800, length = 0x000800
   RAMLS4           : origin = 0x00A000, length = 0x000800
   RAMLS5           : origin = 0x00A800, length = 0x000800
   RAMLS6TO7		: origin = 0x00B000, length = 0x001000

   RAMGS0           : origin = 0x00D000, length = 0x001000
   RAMGS1TO15		: origin = 0x00E000, length = 0x00F000

   BEGIN            : origin = 0x088000, length = 0x000002
   VERSION			: origin = 0x088008, length = 0x000008
   FLASH4TO6		: origin = 0x088010, length = 0x017FF0
   FLASH7TO10		: origin = 0x0A0000, length = 0x01A000
   FLASH11          : origin = 0x0BA000, length = 0x002000  /* on-chip Flash */
   FLASH12          : origin = 0x0BC000, length = 0x002000  /* on-chip Flash */
   FLASH13          : origin = 0x0BE000, length = 0x001FF0  /* on-chip Flash */

   EMIF1_CS0n      : origin = 0x80000000, length = 0x10000000
   EMIF1_CS2n      : origin = 0x00100000, length = 0x00100000
   EMIF1_CS0_CS2n  : origin = 0x00200000, length = 0x00100000
   EMIF1_CS3n      : origin = 0x00300000, length = 0x00080000
   EMIF1_CS4n      : origin = 0x00380000, length = 0x00060000
   EMIF2_CS0n      : origin = 0x90000000, length = 0x10000000
   EMIF2_CS2n      : origin = 0x00002000, length = 0x00001000
}

SECTIONS
{
   codestart           : > BEGIN, ALIGN(8)
   .text               : > FLASH4TO6, ALIGN(8)
   .cinit              : > FLASH4TO6, ALIGN(8)
   .switch             : > FLASH4TO6, ALIGN(8)
   .reset              : > RESET, TYPE = DSECT /* not used, */
   .stack              : > RAMGS0

#if defined(__TI_EABI__)
   .init_array      : > FLASH4TO6, ALIGN(8)
   .bss             : >> RAMGS1TO15	
   .bss:output      : > RAMLS4
   .bss:cio         : > RAMLS5
   .data            : > RAMLS5
   .sysmem          : > RAMLS5
   /* Initalized sections go in Flash */
   .const           : >> FLASH4TO6, ALIGN(8)
#else
   .pinit           : > FLASH8, ALIGN(8)
   .ebss            : > RAMLS5 | RAMLS6TO7
   .esysmem         : > RAMLS5 | RAMLS6TO7
   .cio             : > RAMLS5 | RAMLS6TO7
   /* Initalized sections go in Flash */
   .econst          : >> FLASH4 | FLASH5, ALIGN(8)
#endif

   ramgs0 : > RAMGS0, type=NOINIT
   //ramgs1 : > RAMGS1, type=NOINIT
   ramm0  : > RAMM0,  type=NOINIT
   
   MSGRAM_CPU1_TO_CPU2 : > CPU1TOCPU2RAM, type=NOINIT
   MSGRAM_CPU2_TO_CPU1 : > CPU2TOCPU1RAM, type=NOINIT
   MSGRAM_CPU_TO_CM    : > CPUTOCMRAM, type=NOINIT
   MSGRAM_CM_TO_CPU    : > CMTOCPURAM, type=NOINIT

   MSGRAM_CLA_TO_CPU 	: > CLATOCPURAM, type=NOINIT
   MSGRAM_CPU_TO_CLA 	: > CPUTOCLARAM, type=NOINIT
   MSGRAM_CLA_TO_DMA    : > CLATODMARAM, type=NOINIT
   MSGRAM_DMA_TO_CLA    : > DMATOCLARAM, type=NOINIT

#if defined(__TI_EABI__)
   .sdramfunc       : LOAD = FLASH4TO6,
                   RUN = EMIF1_CS0_CS2n,
                   LOAD_START(XintffuncsLoadStart),
                   LOAD_END(XintffuncsLoadEnd),
                   RUN_START(XintffuncsRunStart)
#else
   .sdramfunc       : LOAD = FLASH4TO6,
                   RUN = EMIF1_CS0_CS2n,
                   LOAD_START(_XintffuncsLoadStart),
                   LOAD_END(_XintffuncsLoadEnd),
                   RUN_START(_XintffuncsRunStart)
#endif

   emif_cs0_nonfar  : > EMIF1_CS0_CS2n
   .farbss          : > EMIF1_CS0n
   .farconst        : > EMIF1_CS0n
   .em1_cs0         : > EMIF1_CS0n
   .em1_cs2         : > EMIF1_CS2n | EMIF1_CS0_CS2n
   .em1_cs3         : > EMIF1_CS3n
   .em1_cs4         : > EMIF1_CS4n
   .em2_cs0         : > EMIF2_CS0n
   .em2_cs2         : > EMIF2_CS2n
}

请查看是否存在任何错误。

如果您对此问题有任何经验、我希望您就使用 SRAM 作为程序存储器的正确方法提供一些建议。   

  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    假设 F28388D 的 EMIF 与 F2837x 的 EMIF 相似、恐怕无法从 SDRAM 执行代码。 具体请参阅 https://www.ti.com/lit/an/spraby4/spraby4.pdf?ts=1670227002859

    此致

    Johannes

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您正在使用哪个地址映射- EMIF1_CS0n 或 EMIF1_CS0_CS2n?

    您需要为此 使用 EMIF1_CS0_CS2n 并启用该映射、您需要将 MEMMAPTYPE 的 TYPE 字段设置为"01"。 (图3-226。 MMAPTYPE 寄存器)

    通常、建议为数据使用 SDRAM 空间。 是否有任何特定的原因需要从那里执行代码?

    此致、

    Vivek Singh  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我之所以将 SDRAM/EMIF 上的 SDRAM 用作程序存储器、是因为我想写入二进制映像、以便在运行时将固件更新到片上闪存中。

    我知道、禁止在程序运行的闪存中写入相同的程序。 因此、我曾计划在从外部 SDRAM 运行程序时将固件映像写入片上闪存。 但遗憾的是、如果是 C28x、它似乎不起作用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [引用 userid="5255590" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1177064/tms320f28388d-how-to-load-and-run-user-program-on-sdram-over-emif/4432382 #4432382"]但不幸的是、如果是 C28x、它似乎不起作用。

    您应该能够为此使用 EMIF ASRAM 接口。 这应该起作用。

    此致、

    Vivek Singh