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.

[参考译文] TM4C123GH6PM:帮助将闪存引导加载程序集成到应用项目中

Guru**** 2527790 points
Other Parts Discussed in Thread: UNIFLASH

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1255682/tm4c123gh6pm-help-integrating-flash-bootloader-into-application-project

器件型号:TM4C123GH6PM
主题中讨论的其他器件:EK-TM4C1294XLEK-TM4C123GXLUNIFLASH

您好!

我正在尝试将闪存引导加载程序导入到我的应用项目中。  在 TI 论坛支持工程师(Charles)的帮助下、我找到了一个非常有用的示例项目。  我正在尝试弄清楚如何告诉该工具(CCS 编译器/连接器-我认为主要是连接器?) 在何处放置闪存引导加载程序与应用程序项目。  我一直在看 TM4C123GXL 板级工程的 boot_serial 示例的工程设置、发现 bl_link_ccs.cmd 在 load_start 中为"init_load"、在 run_start 中为"init_run"。

要将 boot_serial 源代码/ boot loader 引入我的应用程序、我需要具体做些配置、以便引导加载程序放置在0x00000000、而我的应用程序放置在0x00002800上?  对.cmd 文件的比较显示 boot_serial *。cmd 文件具有两个单独的组、而我的*。cmd 文件不具有这两个单独的组。   

下面是两个.cmd 文件-一个来自 boot_serial 示例、一个来自我的应用程序工程:

BOOT_SERIAL 示例

MEMORY
{
    FLASH (RX) : origin = 0x00000000, length = 0x00010000
    SRAM (RWX) : origin = 0x20000000, length = 0x00010000
}

/* Section allocation in memory */

SECTIONS
{
    GROUP
    {
        .intvecs
        .text
        .const
        .data
    } load = FLASH, run = 0x20000000, LOAD_START(init_load), RUN_START(init_run), SIZE(init_size)

    GROUP
    {
        .bss
        .stack
    } run = SRAM, RUN_START(bss_run), RUN_END(bss_end), SIZE(bss_size), RUN_END(__STACK_TOP)

}

当前应用项目

#define APP_BASE 0x00000000
#define RAM_BASE 0x20000000

/* System memory map */

MEMORY
{
    /* Application stored in and executes from internal flash */
    FLASH (RX) : origin = APP_BASE, length = 0x00040000
    /* Application uses internal RAM for data */
    SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}

/* Section allocation in memory */

SECTIONS
{
    .intvecs:   > APP_BASE
    .text   :   > FLASH
    .const  :   > FLASH
    .cinit  :   > FLASH
    .pinit  :   > FLASH
    .init_array : > FLASH

    .vtable :   > RAM_BASE
    .data   :   > SRAM
    .bss    :   > SRAM
    .sysmem :   > SRAM
    .stack  :   > SRAM
#ifdef  __TI_COMPILER_VERSION__
#if     __TI_COMPILER_VERSION__ >= 15009000
    .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
#endif
#endif
}

__STACK_TOP = __stack + 1024;

我还想知道我是否需要编辑.cmd 文件、或者我是否需要使用项目属性(在 CCS 中右键单击项目并选择属性)来设置此信息?

谢谢

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

    忘记在方框图中发布我想要实现的目标、请参阅下面的内容、以防万一这是有用的。

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

    尊敬的 Robert:

    Unknown 说:
    要将 boot_serial 源代码/引导加载程序引入我的应用程序、我需要具体配置什么、以便引导加载程序放置在0x00000000、我的应用程序放置在0x00002800?

    对于您的应用、APP_BASE 需要为0x2800。 但是、在读取应用程序链接器文件时、可以看到 APP_BASE 等于0x00000000、如下所示。 请将其更改为0x2800。  

    #define APP_BASE 0x00000000

    您可以参考 boot_demo1示例。 这是与 boot_serial 一同使用的应用程序示例。 下面是链接器命令文件、您可以在其中看到 APP_BASE 定义为0x2800。  

    --retain=g_pfnVectors
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M3_T_le_eabi.lib                                           */
    
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    #define APP_BASE 0x00002800
    #define RAM_BASE 0x20000000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application stored in and executes from internal flash */
        FLASH (RX) : origin = APP_BASE, length = 0x0003d800
        /* Application uses internal RAM for data */
        SRAM (RWX) : origin = 0x20000000, length = 0x00008000
    }
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > APP_BASE
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
    
        .vtable :   > RAM_BASE
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
    #endif
    #endif
    }
    
    __STACK_TOP = __stack + 1024;

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

    尊敬的 Charles:

    所以、以下示例对您有所帮助。  我想对于如何做到这一点我有一个基本的误解。  请告诉我您对以下问题的看法:

    1.采用将闪存引导加载程序作为完全独立的项目的方法是否正确?  您首先在地址0x00000000处对闪存引导加载程序项目进行编程。  完成编程后、您对"应用项目"进行编程、这是一个完全独立的项目、作为第二个编程操作?

    2.在 bl_config.h 中,RCGCGPIO_Rx 指的是什么?  如下所示、请在第1169行找到

    //*****************************************************************************
    //
    // Specifies the GPIO peripheral containing the pin which is used for DP.
    // The value is of the form SYSCTL_RCGCGPIO_Rx, where the Rx represents
    // the required GPIO port.  This applies to Blizzard class and later 
    // devices.
    //
    // Depends on: USB_ENABLE_UPDATE, USB_DP_CONFIG
    // Exclusive of: None
    // Requires: None
    //
    //*****************************************************************************
    //#define USB_DP_PERIPH          SYSCTL_RCGCGPIO_R10            // For EK-TM4C1294XL
    #define USB_DP_PERIPH          SYSCTL_RCGCGPIO_R3            // For EK-TM4C123GXL

    3.是期望  仅限 是否更改我的链接器#define APP_BASE 值、如下所示?  尝试此操作时、我的应用程序会崩溃。  CCS 的屏幕截图如下所示。  我担心还有更多设置需要修改来支持、但我遗漏了这些设置。   

    /******************************************************************************
     *
     * usb_dev_bulk_ccs.cmd - CCS linker configuration file for usb_dev_bulk.
     *
     * Copyright (c) 2012-2020 Texas Instruments Incorporated.  All rights reserved.
     * Software License Agreement
     * 
     * Texas Instruments (TI) is supplying this software for use solely and
     * exclusively on TI's microcontroller products. The software is owned by
     * TI and/or its suppliers, and is protected under applicable copyright
     * laws. You may not combine this software with "viral" open-source
     * software in order to form a larger program.
     * 
     * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
     * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
     * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
     * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
     * DAMAGES, FOR ANY REASON WHATSOEVER.
     * 
     * This is part of revision 2.2.0.295 of the EK-TM4C123GXL Firmware Package.
     *
     *****************************************************************************/
    
    --retain=g_pfnVectors
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M3_T_le_eabi.lib                                           */
    
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    //#define APP_BASE 0x00000000
    #define APP_BASE 0x00002800
    #define RAM_BASE 0x20000000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application stored in and executes from internal flash */
        FLASH (RX) : origin = APP_BASE, length = 0x00040000
        /* Application uses internal RAM for data */
        SRAM (RWX) : origin = 0x20000000, length = 0x00008000
    }
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > APP_BASE
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
    
        .vtable :   > RAM_BASE
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
    #endif
    #endif
    }
    
    __STACK_TOP = __stack + 1024;

    4.是否需要更新调试会话、以便它知道从0x2800运行应用程序工程?  我想知道我在#3的问题是否是由于这个原因。  我今天已经四处查看、但没有找到指定调试器应在何处开始运行代码的字段? 不知道您是否需要从地址0 NO 更改为0x2800。

    谢谢

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

    尊敬的 Charles:

    我想我最终找到了问题的根本原因。  当我将#define APP_BASE 从0更改为0x02800时、寄存器 HFAULTSTAT 中似乎存在"指令访问违规"位0。  我最初认为这是引导加载问题。

    我现在将对此进行故障排除、因为我的问题是由于我更改了 APP_BASE 而发生的故障。  我将随附故障信息、以防您之前遇到此类问题。  我的 PC 寄存器变成了0xFFFFFFFE、LR 也变成了0xFFFFFFF1、我还不确定应该怎么做。  我的堆栈指针指向我的1024字节堆栈中间的一个值、并且显示0x200032F0的地址。

    似乎更改 APP_BASE 确实会影响其他方面、因为当 APP_BASE = 0时该项目可以正常运行、但在0x02800时不能正常运行。   

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

    尊敬的 Robert:

     引导加载程序是否通过 USB 接口成功加载了应用程序?

     您发现的故障问题是在引导加载程序跳转到应用程序之后发生的、还是在应用程序跳回引导加载程序之后发生的问题?

     您是否可以使用内存浏览器在0x0和0x2800处查看闪存的内容? 引导加载程序是否仍在0x0处? 应用程序是否在0x2800上加载?

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

    尊敬的 Charles:

    因此、我认为该问题与引导加载程序无关。  我的第一步是获取我正在工作的应用程序项目、然后更改 APP_BASE 以验证它是否仍然有效、而更改 APP_BASE 似乎会中断该项目。  我尚未获得引导加载程序部分。  我采取的步骤如下:

    1.在我的工作应用程序项目中将 APP_BASE 更改为0x2800。  如下面的代码视图所示。

    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application.                      */
    //#define APP_BASE 0x00000000
    #define APP_BASE 0x00002800
    #define RAM_BASE 0x20000000
    
    /* System memory map */
    
    MEMORY
    {
        /* Application stored in and executes from internal flash */
        FLASH (RX) : origin = APP_BASE, length = 0x00040000
        /* Application uses internal RAM for data */
        SRAM (RWX) : origin = 0x20000000, length = 0x00008000
    }
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > APP_BASE
        .text   :   > FLASH
        .const  :   > FLASH
        .cinit  :   > FLASH
        .pinit  :   > FLASH
        .init_array : > FLASH
    
        .vtable :   > RAM_BASE
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    #ifdef  __TI_COMPILER_VERSION__
    #if     __TI_COMPILER_VERSION__ >= 15009000
        .TI.ramfunc : {} load=FLASH, run=SRAM, table(BINIT)
    #endif
    #endif
    }
    
    __STACK_TOP = __stack + 1024;
    

    2.接下来我清理和构建我的项目。

    3.使用 CCS 中的调试器进行编程、以测试 launchpad 上的应用、确认其是否仍然有效。

    4. CCS 进入调试器模式后、我只需依次点击"run"和"pause"即可看到"指令访问违规"。

    根据您的问题-我目前只是在尝试使用新的 app_base 来运行我的应用程序项目。  我在编程时确实看到引导加载程序 gong 到了地址0、但现在我甚至不这么做。 我只是尝试使用新的 APP_BASE 值使我的应用程序正常运行。   

    我认为应用程序项目加载的地址正确。  下面是0x2800处的内存视图的屏幕截图、我认为该截图显示了合理的应用程序的中断指针函数表。

    在此之后、我可以看到 main

    看起来应用程序放置正确、但在运行期间、我遇到了该指令故障。  我还认为该故障是由中断引起的、因为我可以在调试器中运行一些应用程序代码、但当 APP_BASE = 0x2800时、我从未在 SysTick 中断处理程序中遇到断点。  当我将 APP_BASE 设置为0时、一切都正常。

    此问题很难解决、因为我的链接寄存器 LR 没有您可以看到的退出代码地址。  因此、我不知道调用函数在该崩溃之前是什么。

    这更有意义吗?  我认为这与引导加载程序代码无关、只是由于更改了 APP_BASE = 0x2800而产生了错误。

    谢谢

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

    尊敬的 Robert:

     您所做的工作将不起作用。 如果您只是使用 JTAG 加载分配给0x2800的应用程序、则0x0处没有任何内容。 您可以首先使用 JTAG 加载引导加载程序、然后再次使用 JTAG 加载应用程序。 如果您在 CCS 中使用 JTAG 加载应用、它将擦除0x0处的闪存。 这就是我要求您在0x0处展示闪存内容的原因。 如果您看到所有 F、则0x0处没有引导加载程序。 处理器完成复位后、从0x0开始、查找有效的堆栈指针和0x4处的有效复位向量。 如果它们都是0xF、则会得到错误。  

     尝试使用可同时加载多个图像的 Uniflash。 通过指定这两个二进制文件、您可以从0x0开始加载引导加载程序映像并在0x2800同时加载应用程序映像。 Uniflash 则可轻松实现这一点。 你不能使用 CCS 同时加载多个图像、但解决它有一个诀窍。 首先加载引导加载程序映像。 但在加载应用程序映像之前、您需要指示 CCS 编程器不要擦除引导加载程序所在的第一个闪存扇区。 默认情况下、加载程序将首先完全擦除闪存、然后再对代码进行编程。  

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

    好的-这是我的原始计划。  我加载了引导加载程序、然后将应用程序项目配置为仅从0x2800-0x3FFFF 擦除闪存。  这现在似乎一直有效、直到我启用中断。  CPU 试图在0x528跳转至指令并崩溃。  我需要更详细地了解这一点、但在我现在启用中断之前、一切似乎都正常工作。  中断表肯定出现了问题。   

    我在主函数配置中执行的最后一项操作是"IntMasterEnable ();";一旦执行此操作、我便会使用地址0x538进行崩溃、该地址位于引导加载程序空间中、因此永远不会发生。  存在一些错误、当触发中断时、CPU 跳转到 bootloader 部分中的代码。

    希望这更易于调试、因为我在内核寄存器中获得了有用的信息。

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

    尊敬的 Robert:

     您可以尝试连接 BOOT_USB 引导加载程序吗?

    e2e.ti.com/.../tm4c123_5F00_boot_5F00_usb.zip

    在运行它时、我会看到 USB 器件端口枚举为 DFU 器件。 由于我正在使用 LaunchPad、因此也会显示 Stellaris ICDI DFU 器件。 因此、检测到两个 DFU 器件。  

    您还可以使用 dfuprog.exe 查找 DFU 器件并下载固件。  

    需要注意的一点是、如果您使用 LaunchPad 运行 USB 引导加载程序、请格外小心。 如我所示、将检测到两个 DFU 器件。 切勿误选择 ICDI DFU 来下载您的固件。 如果这样做、您会误将固件编程到 ICDI 芯片、使 ICDI 不再枚举为 ICDI 调试探针。 此步骤不可撤消。  

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

    尊敬的 Charles:

    感谢您的答复! 我想我现在已经可以正常运行了、我的问题实际上是另一个测试设置问题。  由于之前的枚举尝试失败、我使用的 vid/pid 存在一些与之相关的问题。  我通常可以手动清除注册表信息、这样就不会发生这种情况。  我成功清除了我正在处理的每个枚举的复合设备的注册表信息、并且没有出现任何问题。  但由于某种原因、DFU 不起作用。  使用相同的过程、引导加载程序仍无法枚举。

    这就像通过更改 VID 来解决这个问题一样。  我需要确定需要在注册表中清除哪些剩余数据、以便可以在示例中使用默认 vid/pid。   

    我仍将拉低您随附的项目 zip 文件并进行比较以查看可能存在的差异、但就目前来看、我似乎已经准备好运行闪存引导加载程序。

    您的组中没有任何人碰巧知道要在注册表中清除什么、从而获得具有相同 vid/pid 的新枚举?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    由于之前的枚举尝试失败,我使用的 vid/pid 存在与之相关的问题。  我通常可以手动清除注册表信息,这样就不会发生这种情况。

    尊敬的 Robert:

     您指的是什么注册表信息? 这是 Windows 注册表吗?  

    我仍将下拉您连接的项目 zip 文件并进行比较以查看可能存在的差异,但目前似乎我已经启动并运行了闪存引导加载程序。

    请尝试 attache 项目。 它使用默认的 VID / PID、适用于我。 加载闪存引导加载程序并开始运行后、我就可以在 Windows 设备管理器中看到枚举了 DFU 器件或使用 dfuprog.exe。

    您的组中没有任何人碰巧知道在注册表中需要清除什么,因此您将获得具有相同 vid/pid 的全新枚举?

    如果这是关于 Windows 注册表、那么我不知道要在注册表中清除什么以启动新枚举。