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.

[参考译文] TM4C1290NCPDT:在应用程序代码之前进行 EPI 初始化

Guru**** 2524550 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/917612/tm4c1290ncpdt-epi-initialization-before-application-code

器件型号:TM4C1290NCPDT

我们目前正在开发一个项目、该项目将使用 EPI 来与 SDRAM 部件配合使用。 我们的项目将有一个闪存引导加载程序、该加载程序最终将调用跳转到我们的应用程序二进制文件。 在 应用程序代码完成存储器初始化之前、我可以使用引导加载程序中的_system_pre_init 函数来设置 EPI。 不过、我想知道在 JTAG 调试应用程序代码之前需要做些什么、因为不会调用引导加载程序来设置 EPI。

如果在 SDRAM 中使用内存、INIT 将在设置 EPI 之前尝试初始化 SDRAM 中的内存、这将导致处理器出现硬故障。 是否有人建议如何调试我们的应用程序代码、但在内存初始化之前也有 EPI 设置? 如果可能、我们希望避免禁用存储器初始化。

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

    我们的引导加载程序全部是 C 语言、我们的应用程序代码是 C++。 我在我们的应用程序 main.cpp 中具有以下内容:

    extern "C" int _system_pre_init (void)
    {
    返回(1);
    } 

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

    您好、Bryan、

     也许我对您的问题和设置不完全清楚。 我假设您的应用程序存储在 SDRAM 上、而存储在 MCU 上的仅是基于闪存的引导加载程序。 这是正确的理解吗? 您是否将片上闪存用于引导加载程序以外的任何其他内容? 另一个问题是如何将应用程序代码加载到 SDRAM 中? 您是否在到 SDRAM 的总线上具有某种类型的多路复用。 换言之、MCU 仅从 SDRAM 读取和执行代码、而另一台主机向 SDRAM 写入数据以上传应用二进制文件。  

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

    您好、Charles、

    我们没有从外部 SDRAM 执行。 我们的应用代码通常保存在闪存中、并在 Tiva 的内部 SDRAM 中执行。 我们有一个外部 SDRAM、用于存储大型数据集。 我们的目标是设置我们的应用链接器、使其具有映射到外部 SDRAM 的存储器区域。 我们担心的是、当应用程序代码被拉入时、映射的存储器将在 main 之前初始化、这将生成处理器的硬故障。

    我们使用 EPI 模块与外部 SDRAM 接口相连。 我认为我可以在 我们的闪存引导加载程序中设置_system_pre_init (void)、这将在我们的应用代码执行之前成功启用 EPI。 不过、我相信在进行 JTAG 调试时、引导加载程序不会被执行、这意味着在完成存储器初始化之前不会启用 EPI、这将导致硬故障。

    FWiw、闪存引导加载程序在闪存中设置为0x0000。 应用程序代码在闪存中设置为0x4000。

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

    [引用 user="Bryan Radke"]我们担心的是,当应用程序代码被拉入时,映射的内存将在 main 之前初始化,这将导致处理器出现硬故障。

    您好、Bryan、

      也许这是我不清楚的。 复位后、首先启动闪存引导加载程序(位于0x0)。 然后、它将跳转到从0x4000开始的应用程序。 在运行从0x4000开始的应用程序之前、无需开始读取外部 SDRAM (通过 EPI)。 是这样吗? 在跳转到应用程序之前、我不清楚当您仍在引导加载程序中时、您尝试使用外部 SDRAM 或 EPI 模块执行什么操作。 在初始化 EPI 和访问外部 SDRAM 之前、您是否可以等到应用程序中? 很抱歉、如果我没有关注这个问题。 硬故障来自哪里? 是否仍在引导加载程序中?

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

    您好、Charles、

    您对我们的闪存引导加载程序和应用程序的运行方式正确无误。 我们跳转至0x4000处的应用程序代码、这是使用外部 SDRAM 的地方。 引导加载程序不会使用外部 SDRAM、但可以设置 EPI 模块、以便为应用程序代码启用。

    我们的目的是将我们的应用程序链接器命令文件更新为下面列出的文件:

    内存
    {
    闪存(RX):origin = 0x00000000,length = 0x00100000
    SRAM (rwx):origin = 0x20000000,length = 0x00040000
    EXSDRAM (rwx):origin = 0x60000000,length = 0x00800000
    } 

    我的理解是、应用程序代码的初始化将尝试将所有映射的存储器初始化为用户定义的初始化值或默认值。 我相信有一个标志可以跳过这一步。 无论如何、我相信我们已经映射到 EXSDRAM 部分的任何内存都将在执行我们的应用程序代码之前被初始化。 如果在此启动步骤之前未启用/配置 EPI 模块、则处理器将因无法访问而出现故障。 此链接中的帖子是整个计划启动 https://e2e.ti.com/support/microcontrollers/other/f/908/t/442360的地方

    当我们通过 JTAG 运行调试器时、无需提前启用 EPI、这意味着我们将遇到硬故障、因为无法初始化存储器。 我的问题是如何启用 EPI、以便由链接器映射存储器、并通过 JTAG 调试代码。

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

    下面的代码是启用 EPI 到外部 SDRAM 时所需的代码:

    #define SDRAM_APP_START_ADDRESS 0x60000000
    
    //为 EPI0的 GPIO 引脚定义
    #define EPI_PORta_Pins 0xC0 //引脚6、7
    #define EPI_PORTB_PINS 0x0C //引脚2、3
    #define EPI_PORTC_Pins 0xF0 //引脚4、5、6、7
    #define EPI_PORTG_Pins 0x03 //引脚0、1
    #define EPI_Porth_Pins 0x0F //引脚0、1、2、3
    #define EPI_PORTK_Pins 0xF0 //引脚4、5、6、7
    #define EPI_PORTL_Pins 0x3F //引脚0、1、2、3、4、 5
    #define EPI_PORTM_Pins 0x0F //引脚0、1、2、3
    #define EPI_PORTN_Pins 0x30 //引脚4、5
    #define EPI_PORTP_PINS 0x0C //引脚2、3
    #define EPI_PORTQ_Pins 0x0F //引脚0、1、2、3
    
    #define EPI_PORTA_PCTL 0xFF000000
    #define EPI_PORTB_PCTL 0x0000FF00
    #define EPI_PORTC_PCTL 0xFFFFFF0000
    #define EPI_PORTG_PCTL
    0x0000FF #define EPI_PT_PORTL_POLT_PRTL_0x0000FFT 0x0000FFT #define
    
    
    
    
    EPI_POLT_PCTL #define 0x0000_POLT_POLT_PCTL #define 0x0000FFTL_POLT_POLT_POLT_PFFTL_POLT_PFFTTR_PCTL #define 0x0000FFT 0x0000FFT 0x0000FFT 0x0000FFT #define 0xEP_PCTL #define 0xEP_POR
    
    
    
    {
    //
    
    
    
    在.bss 和.data 段*已初始化之前调用此函数*,因此这里的内核只应访问*外设寄存器或栈上分配的局部变量*//启用 EPI
    HWREG 的 GPIO 端口运行模式时钟(SYSCTL_RCGCGPIO)|=
    (
    SYSCTL_RCGCGPIO_R0 |// GPIO 端口 A
    SYSCTL_RCGCGPIO_R1 |// GPIO 端口 B
    SYSCTL_RCGCGPIO_R2 |// GPIO 端口 C
    SYSCTL_RCGCGPIO_R6 |// GPIO 端口 G
    SYSCTL_RCGCGPIO_R7 |// GPIO 端口 H RCGCTRL_9
    | GPIO_SYSCTR1_GPIO_R10 | GPIO_SYSCTR0 | GPIO_R10
    
    | GPIO_SYSCTR0 | GPIO_R9 | GPIO_SYSCTR0
    |// GPIO 端口 N
    SYSCTL_RCGCGPIO_R13 |// GPIO 端口 P
    SYSCTL_RCGCGPIO_R14 // GPIO 端口 Q
    );
    
    //等待时钟被启用
    ,同时(HWREG (SYSCTL_PRGPIO)&
    (
    SYSCTL_RCGCGPIO_R0 |// GPIO 端口 A
    SYSCTL_RCGCGPIO_R1 |// GPIO 端口 B
    SYSCTL_RCGCGPIO_R2 |// GPIO 端口 C
    SYSCTL_RCGCGPIO_R6 |// GPIO 端口 G
    SYSCTL_RCGCGPIO_R7 |// GPIO 端口 H RCGCTRL_9
    | GPIO_SYSCTR1_GPIO_R10 | GPIO_SYSCTR0 | GPIO_R10
    
    | GPIO_SYSCTR0 | GPIO_R9 | GPIO_SYSCTR0
    |// GPIO 端口 N
    SYSCTL_RCGCGPIO_R13 |// GPIO 端口 P
    SYSCTL_RCGCGPIO_R14 // GPIO 端口 Q
    ) !=
    (
    SYSCTL_RCGCGPIO_R0 |// GPIO 端口 A
    SYSCTL_RCGCGPIO_R1 |// GPIO 端口 B
    SYSCTL_RCGCGPIO_R2 |// GPIO 端口 C
    SYSCTL_RCGCGPIO_R6 |// GPIO 端口 G
    SYSCTL_RCGCGPIO_R7 |// GPIO 端口 H RCGCTRL_9
    | GPIO_SYSCTR1_GPIO_R10 | GPIO_SYSCTR0 | GPIO_R10
    
    | GPIO_SYSCTR0 | GPIO_R9 | GPIO_SYSCTR0
    |// GPIO 端口 N
    SYSCTL_RCGCGPIO_R13 |// GPIO 端口 P
    SYSCTL_RCGCGPIO_R14 // GPIO 端口 Q
    )
    )
    {
    |//
    
    配置 EPI IO 引脚
    HWREG (GPIO_PORta_AHB_BASE + GPIO_PCTL)|= EPI_PORta_PCTL
    
    ;HWREG (GPIO_PORta_AHB_BASE + GPIO_O_DEN)|= EPI_PORta_pins;HWREG (GPIO_PORta_PHB_BASE + GPIO_EP_ORT_BASE
    
    
    )|= EP_GPIO_PORt_GPIO_PORT_BASE;
    = EP_GPIO_PO_GPIO_PORT_BASE | GPIO_PORT_BASE | GPIO_PORT_BORT_BORT_GPIO_GPIO_GPIO_GPIO_PORT_BASE (+= EP_GPIO_PORT_BASE)| GPIO_PORT_BORT_BASE)
    HWREG (GPIO_PORTB_AHB_BASE + GPIO_DR8R)|= EP_PORTB_PINS;
    HWREG (GPIO_PORTB_AHB_BASE + GPIO_O_AFSEL)|= EP_PORTB_PINS;
    
    HWREG (GPIO_PORTB_PHB_BASE + GPIO_ORT_PO_ORT+=
    EP_ORTC_ORTC_OPORT2_PH_PO_RESP+= GPIO_PH_ORT+= GPIO_ORT_ORT_ORT_ORT+= GPIO_RES_ORT_PO_ORT_PO_PO_PO_PO_PO_PO_PO_PO_PO_PO_PO_PO_PORTC_PORTC_PINS
    
    
    
    )
    HWREG (GPIO_PORTG_AHB_BASE + GPIO_DEN)|= EP_PORTG_Pins;
    HWREG (GPIO_PORTG_AHB_BASE + GPIO_DR8R)|= EP_PORTG_GPIO_PHB
    
    
    
    
    
    )|= EP_PORT_BASE (GPIO_POST_POST_POST_GPIO_PORT_BASE)|= EP_POST_GPIO_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_GPIO_P=GPIO_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_POINS|= GPIO_POST_POST_POST_POST_POST_POST_POST_POST_POST_POST_GPIO_P=GPIO_P=GPIO_P_POST_POST_POST_POST_POST_POST_POST_
    
    HWREG
    
    
    
    
    
    
    (GPIO_PORTK_base + GPIO_PCTL)|= EP_PORTK_PCTL;HWREG (GPIO_PORTK_base + GPIO_DEN)|= EP_PORTK_BASS;HWREG (GPIO_PORTK_base + GPIO_DR8R)|= EP_PORTK_BASE_INS+= EPORTK_ORTK_+ GPIO_RESPORTK_PO_PORTK_ORTK_++= GPIO_REST_PORTK_ORTK_ORTK_ORTK_ORTK_+ GPIO_RESPORTK_ORTK_ORTK_+ GPIO_RESPORTK_PA_PORTK_ORTK_PA_PORTK_ORTK_ORTK_+ GPIO_RESPORTK_+ GPIO_RESPORTK_ORTK_PA_PORTK_PA_PORTK_ORTK_ORTK_ORTK_+ GPIORTK_+ GPIORTK_ORTK_PA_PORTK_OR
    HWREG
    
    
    
    
    
    
    
    (GPIO_PORTL_BASE + GPIO_AFSEL)|= EP_PORTL_Pins;HWREG (GPIO_PORTM_BASE + GPIO_PCTL)|= EP_PORTM_PCTL;HWREG (GPIO_PORT_BASE + GPIO_ORTN)|= EP_PORTN (+PORTM_PORTN)| GPIO_PORTN)+ PORTn_PORTn_PORTn_PORTN (+= GPIO_PORTM_PORTn_PORTn_PORTn_PORTn_PORTN)|= GPIO_PORTN)
    HWREG
    
    
    
    
    
    
    
    (GPIO_PORTN_BASE + GPIO_DR8R)|= EP_PORTN_PINS;HWREG (GPIO_PORTN_BASE + GPIO_AFSEL)|= EP_PORTN_PINS;HWREG (GPIO_PORTP_BASE + GPIO_PORTP_ORTP_ORTPL)|= EP_ORTP_ORTP_ORTP_ORTP_ORTP_++= GPIO_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_++= GPIO_RES_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_ORTP_++= EP_ORTP_ORTP_ORTP_
    HWREG (GPIO_PORTQ_BASE + GPIO_DEN)|= EP_PORTQ_Pins;
    HWREG (GPIO_PORTQ_BASE + GPIO_DR8R)|= EP_PORTQ_Pins;
    HWREG (GPIO_PORTQ_BASE + GPIO_AFSEL)|= EP_ORTQ/
    
    RRC0)模块(GPIO_REST0)
    ;HWRETP_REST0)
    
    //等待 EPI 模块就绪
    ,同时(((HWREG (SYSCTL_PREPI)& SYSCTL_PREPI_R0)!= SYSCTL_PREPI_R0)
    {
    //
    
    将 EPI 分频器设置为使用系统时钟的一半
    HWREG (EPI0_BASE + EPI_O_BAUD)= 0x1;
    
    //选择 SDRAM 模式
    HWREG (EPI0_BASE + EPI_O_CFG)= 0x00000011;
    
    //配置 SDRAM 模式
    // FREQ:
    // 0x00000000 - 0-15MHz
    // 0x40000000 - 15-30 MHz
    // 0x8000000 - 30-50 MHz
    // 0xC0000000 - 50-100 MHz
    // RFSH:
    // 0x04000000 - 1024个系统节拍<< 16
    //大小:
    // 0x00000000 - 8MB
    // 0x00000001 - 16MB
    // 0x00000002 - 32MB
    // 0x00000003 - 64MB
    #define EPI_FREQ 0xC0000000
    #define EPI_RFSH 0x04000000
    #define EPI_SIZE 0x00000000
    HWREG (EPI0_BASE + EPI_O_SDRAMCFG)=(EPI_FREQ | EPI_RFSH | EPI_SIZE);
    
    //设置 SDRAM 地址映射
    HWREG (EPI0_BASE + EPI_O_ADDRMAP)=(EPI_ADDR_RAM_SIZE | EPI_ADDR_RAM_BASE_6);
    
    //等待 SDRAM 唤醒完成
    ,同时(HWREG (EPI0_BASE + EPI_O_STAT)& EPI_STAT_INITSEQ)
    {
    //
    
    返回1以指示应发生 C/C++自动初始化*/
    return (1);
    } 

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

    您好、Bryan、

     我想我现在理解您的问题。 目前我不确定这是否值得关注。 我只是尝试通过 添加 EXSDRAM (rwx)来修改一个简单的 TivaWare 闪烁示例的链接器命令文件:origin = 0x60000000,length = 0x00800000。 代码编译和运行正常。 在引导加载程序代码中、如果您不声明和使用映射到 EXSDRAM 的任何变量、我认为这不会产生硬故障。 您今天是否看到任何硬件故障、仅仅是因为在链接器命令文件中声明了 EXSDRAM 存储器?

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

    [引用 USER="Bryan Radke">当我们通过 JTAG 运行调试器时、没有任何事情可以提前启用 EPI、这意味着我们将遇到硬故障、因为无法初始化存储器。 我的问题是如何启用 EPI、以便链接 器可以映射存储器、并通过 JTAG 调试代码。[/quot]可以创建一个 GEL 脚本、在调试会话启动时初始化 EPI。 其中 GEL 是一种类似于"C"的脚本编写语言、它在 PC 上运行、可以访问目标上的存储器/寄存器。

    TI 处理器通常使用 GEL 在加载 JTAG 程序之前初始化外部存储器接口。 例如、请参阅 CCS 安装中的 CCS/CCS_base/emulation/boards/BeagleBone/GEL/beaglebonebleblue.gel。

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

    切斯特、您好!

    这似乎是我们需要的。 明天我将查看 GEL、如果它纠正了我的问题、请标记您的响应。

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

    嘿、切斯特、

    我的 CCS 安装没有 BeagleBone GEL。 我在脚本中设置下面的挂钩函数、可以从控制台中看到它已执行。 但是、当应用程序代码运行时、EPI 模块将再次禁用。 在检查模块状态之前、我在应用代码中放入了相同的代码行、它将成功启用模块。 那么、这种设置似乎位于错误的区域? 有什么建议吗?

    OnPreFileLoaded()
    {
    //启用 EPI0模块的时钟
    *(int *) 0x400FE610 |=(1);
    
    GEL_TextOut ("\n 外部 EPI 初始化完成\n");
    } 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [quote user="Bryan Radke">SO、我在 CCS 10.1中的设置似乎不对?我修改了 GEL 脚本、以报告何时发生以下回调以及 SYSCTL_RCGCEPI 寄存器(以及 OnFileLoaded 的程序计数器)的值:

    OnPreFileLoaded()
    {
    GEL_TextOut ("OnPreFileLoaded SYSCTL_SYSCTL_RCGCEPI=%u\n"、、、、 SYSCTL_SYSCTL_RCGCEPI);
    }
    
    OnFileLoaded()
    {
    GEL_TextOut ("OnFileLoaded SYSCTL_SYSCTL_RCGCEPI=%u PC=0x%x\n"、、、、 SYSCTL_SYSCTL_RCGCEPI、PC);
    }
    
    OnTargetConnect ()
    {
    GEL_TextOut ("OnTargetConnect SYSCTL_SYSCTL_RCGCEPI=%u\n"、、、、 SYSCTL_SYSCTL_RCGCEPI);
    }
    
    OnReset ()
    {
    GEL_TextOut ("OnReset SYSCTL_SYSCTL_RCGCEPI=%u\n"、、、、 SYSCTL_SYSCTL_RCGCEPI);
    }
    
    OnResetDetected ()
    {
    GEL_TextOut ("OnResetDetected SYSCTL_SYSCTL_RCGCEPI=%u\n"、、、、 SYSCTL_SYSCTL_RCGCEPI);
    } 

    我发现 GEL 知道在 CCS"Registers"视图下为器件定义的寄存器的名称、因此不必在 GEL 脚本中对地址进行编码。 GEL 已知的寄存器是名称 _ 其中模块名称和寄存器名称显示在 CCS 调试器的"Registers"视图中。

    在运行启用 EPI 接口以进行 SDRAM 访问的程序的目标上启动调试会话时、CCS 控制台输出为:

    Cortex_M4_0:GEL 输出:
    存储器映射初始化完成
    Cortex_M4_0:GEL 输出:OnTargetConnect SYSCTL_SYSCTL_RCGCEPI=1
    Cortex_M4_0:GEL 输出:OnPreFileLoSYSCAFD SYSCGEL_RCGCEPI 0
    
    :OnSYSCTL_RCTL_0
    :OnSYSCTL_RCTL_0:OnSYSCT1_SYSCT1_SYSCTL_RCTL 输出:
    0:OnSYSCT1_SYSCT1_SYSCTL_RCTL_RTE_RTE_RUST_RUST_REST_RCTL_REST_R0_REST_REST_R0_RCTL_REST_REST_RCTL_REST_REST_REST_R0_REST_REST_R0_REST_R0_REST_REST_R0_REST_RCT 

    发生 OnFileLoaded 回调时的程序计数器是 _c_int00_noargs(),它是程序入口点。

    这表明在发生 OnPreFileLoaded 回调后会发生器件复位、这说明了您在应用启动时禁用 EPI 模块的观察结果。

    观察 Debug 工程属性可以发现、唯一启用的 Reset 是 Flash Settings -> Reset target during program load to flash memory。 我尝试取消选择"Reset target during program load"选项、但程序未正确刷写。

    [quote user="Bryan Radke">任何建议如果 OnFileLoaded() 回调发生在编程闪存之后器件已复位以及程序入口点被调用之前,建议将 EPI 初始化移至 OnFileLoaded()回调。

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

    我正在等待硬件可用性检查此解决方案。