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.

[参考译文] RTOS/TM4C1294NCPDT:固件升级

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/570366/rtos-tm4c1294ncpdt-firmware-upgrade

器件型号:TM4C1294NCPDT

工具/软件:TI-RTOS

您好:)

我想通过在网站上上传 bin 文件来更新固件、如 Wifi 路由器上所示。

我制作了轻量级引导加载程序、仅提供网页并 接收新固件。 然后在引导加载程序下面的闪存区域中刷写此固件。 引导加载程序本身永远不会被触摸。  
为了刷写 Tiva I 使用了 Driverlib Librarys 和 FlashProgram (uint32_t * pui32Data、uint32_t ui32Address、uint32_t ui32Count);

现在的问题是:
我可以在代码生成中为目标固件映像选择许多.hex 文件格式。 是否有一种格式我只能使用"FlashProgramm"逐字节进行闪存而无需进一步解释?

感谢您的回答:)
谢谢、

Chris

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

    过去在引导加载程序中使用闪存实用程序的经验要求(*。bin)格式上载为256KB 页。 目标使用 FTP 从本地主机获取 bin 文件。 因此、似乎目标 http 网页必须有 FTP 服务器代码来控制从目标广播 BootP 请求开始的二进制文件传输、仅本地网络。 来自第3层网络设备的广播在路由器上停止,路由器是第2层设备。

    希望这有助于让大家产生一些想法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、感谢您的回答。

    我不想使用闪存实用程序、我想通过 HTML 传输文件上载的.bin 文件。 这对用户来说更加舒适。

    已经完成了很多工作、我现在"只"需要知道我必须选择目标固件(而不是引导加载程序)的哪个.hex 格式(如 TI-TXT)来通过 flash.c 中提供的函数直接对闪存进行编程 或者我错过了什么吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在我看来、flash.c 需要一个二进制文件来写入目标。 因此,您必须使用(Webusers/Read access)为 FTP (获取文件 C 驱动器)添加代码中指定的远程主机(打印/文件共享),以 FTP (获取\*.bin)文件。 文本文件是 ASCII 或其他格式、而不是二进制十六进制数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Chris

    无论采用哪种方法、要发送到 MCU 的数据都必须采用一种格式、其中提供了起始地址以及字节数。 然后、应后跟要编程的数据字节。 二进制文件格式可以有效地实现相同的格式。 如果使用十六进制或任何其他与 bin 文件格式不符的格式、则需要在通过网络发送文件之前执行必要的转换。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Amit、感谢您的回答。

    我不明白这一点。 我已经在 TIVaC 上接收到数据、我正在使用我自己的引导加载程序。 在交付时如何格式化数据没有任何意义-问题是我必须如何准备这些数据、 以便稍后可以在 Tiva 上执行这些数据。

    今天、我实现了以下软件:

    1.通过 http 上传从用户接收 hex 文件。

    2.将.hex 文件或其中的一部分存储在 TivaC 的 SRAM 中

    3.删除从浏览器中添加的元数据

    4.数据的先决条件<--问题

    5.使用 flashprogramm()(Driverlib、flash.c)对 TivaC 闪存进行编程

    6.跳转至刷新的映像并执行新程序

    我也在 CCS 中生成目标固件。 因此、我使用 CCS 中的.hex 生成器。 在 Tiva 闪存中存储后、.hex 应该具有什么格式(如 Intel 格式)才能执行它?  

    感谢您的回答、很抱歉造成混淆。

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

    您好!

    有关 .hex 文件格式的信息、请参阅此链接。

    下载到 RAM 后、您需要恢复为二进制格式、并将其保存到闪存中。 这是因为.hex 文件格式将每个二进制字节替换为两个 ASCII 字符、对应于字节的每个半字节。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的回答。 这就是问题、您能不能推荐十六进制格式、什么不需要后期处理? 我认为英特尔的格式是最复杂的可用格式。 每个固件的开头是否有任何序列、以便我可以测试我是否以正确的方式解码该内容?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    您只需测试/检查软件:CCS 生成的.hex 文件-使用文本编辑器将其打开、因为这是所有 ASCII 字符、请与提供的链接中的信息进行比较、并了解 TI 用于生成.hex 文件的内容。

    您还可以生成.bin 文件以与您的文件进行检查。 至于您的、请为自己编写、如果您了解链接信息、则不难做到。 使用 PC 进行此类编程并测试您编写的函数。 以 ARM 为目标。

    此外、最简单的工作是使用.bin 文件、无需辅助处理。

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

    您好、感谢您的回复。

    您说得对、我现在直接使用.bin 文件。 根本不需要生成十六进制。
    现在还有另一个问题、我的引导加载程序没有跳转到目标应用程序的正确入口点。

    我的引导加载程序是 TI-RTOS 应用程序、目标固件是 Tiva 示例中的简单闪烁程序。

    行为非常特殊:

    blinky 应用程序从0x30000成功加载到闪存中。
    当我使用引导加载程序中的以下代码跳转时、闪烁固件不运行:

    //
    //将矢量表设置为闪存中应用程序的开头。
    //
    HWREG (NVIC_vtable)= ui32StartAddr;//0x30000
    
    //
    //从应用程序的矢量表加载栈指针。
    //
    _asm (" LDR r1、[r0]\n"
    " mov SP、R1\n");
    
    //
    //从应用程序的矢量表加载初始 PC 并分支到
    //应用程序的入口点。
    //
    _asm (" LDR r0、[r0、#4]\n"
    " BX R0\n"); 

    闪烁的 IT 本身在 CCS 中正常运行、并且从0x30000的闪存开始。 因此、我可以通过调试闪烁应用来确定入口点地址、即0x000304A8。
    有趣的是、我可以手动触发 Tiva 来运行我的闪烁应用程序。 因此、我调试引导加载程序应用程序、并在运行任何其他代码之前手动将 PC 寄存器设置为0x000304A8。

    与之相关的是、入口点地址未正确编译为闪烁的二进制文件。 除了链接器中的基址之外、在闪烁的应用程序中是否还有其他需要更改的内容?

    blinky 应用程序链接器文件:

    #define APP_BASE 0x00030000
    #define RAM_BASE 0x20000000
    
    MEMORY
    {
    闪存(RX):origin = APP_BASE,length = 0x000E0000
    SRAM (rwx):origin = 0x20000000,length = 0x00040000
    }
    SECTIONS
    {
    .intvecs:> app_base
    .text:> FLASH
    .const:> FLASH
    .cinit:>闪存
    .pinit:> FLASH
    init_array:> FLASH
    
    .vtable:> RAM_base
    .data :> SRAM
    .bss:> SRAM
    .sysmem:> SRAM
    .stack:> SRAM
    }
    
    __stack_top =__stack + 512; 


    感谢您的任何帮助!

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

    您好!

    建议查看文件 Tiva/boot_loader/BL_STARTUP_CCS.s 以及来自 CallApplication 函数的文件、以便与您的代码进行比较。 提供的代码片段有一点不清楚、因为它没有显示前一 HWREG 代码行之后的寄存器内容。

    首先测试 TI 提供的引导加载程序应用程序。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Chris、
    如果有任何帮助、请执行以下操作:
    -我们还使用 CCS 创建的"plain".bin 格式。
    -更新的固件存储在闪存区域中(如果您愿意,也可以存储在外部 RAM 中)。 我们标记了一些 EEPROM 标志、引导加载程序将在下一次引导时使用这些标志。
    -引导加载程序会看到指示"新固件可用"的标志,并使用新固件交换旧固件。
    -还有一些其他技巧、即确保只接受"为该特定板构建"的固件-并且有一个看门狗需要在一段时间内由新固件复位-否则、旧固件会自动恢复 (这样您就不会有欺骗器件的风险)。
    此致
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、感谢您的回复。

    为了澄清这一点、我为我的小型 TI-RTOS 应用程序使用了"引导加载程序"一词、为.bin 文件上载以及在闪存中的某个位置启动目标应用程序提供了一个 Web 服务器。
    我将目标应用用于我的目标应用、在本例中是一个简单的闪烁应用、之后是一个 TI-RTOS 应用。

    @布鲁诺:我有类似的想法。 我非常喜欢您使用看门狗来确定新固件是否正在运行的想法。 感谢您的分享!

    我想这样做:
    -我的引导加载程序正在测试存储在闪存中某个位置的目标应用程序的校验和。
    -如果此测试成功,则启动此应用程序。
    -否则、它会在引导加载程序中挂起、直到用户上载新的目标固件。

    因此、在最坏的情况下、用户必须上载新固件、但到目前为止、他无法使器件砖型。


    我将 2014年 Amit 的帖子 用作模板。 在链接中的这些文件上:引导加载程序中的 startup_css.c 以及应用程序(自举代码)对我来说是原始的(应用程序地址除外)。

    是否有命令可直接将 PC 设置为新地址? 因为正如我说过的、固件正在运行如果我在 CCS 中调试我的引导加载程序应用程序并将 PC 设置为目标应用程序的入口点。

    如何调试此问题? 到目前为止、我只能保证目标应用程序完全位于闪存中。

    有什么想法如何继续、我可以发布什么信息进行澄清?

    此致

    Chris  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Chris、
    在本例中、更新库的传输发生在主应用程序中、而不是引导加载程序中。
    我们只需添加一个具有必要函数的.h 文件、新的 bin 即可在产品"正常使用"期间"通过任何物理连接- UART、eth 等"到达。
    我们的定制引导加载程序非常小、不处理传输-它只是在设置了适当的标志时管理交换代码块。
    对我们的情况来说,这可能是太具体了,但这是一个建议。
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好,Brun

    感谢您的澄清:)。  我使用的是主应用程序、因为我需要 Web 服务器功能。 我不必考虑使用这种方法交换代码。 此外、很难使器件砖型。 当然、对于该启动应用、我需要大量的内存。

    我将跳转到目标应用程序过程的一些屏幕截图:

    在跳转之前、 静态 uint32_t FileOneAdress = 0x00030000;

    正在加载堆栈指针:

    分支到错误地址? (目标应用入口点应为 0x000304A8、使用 CCS 进行测量)

    在目标应用程序挂起:

    有什么想法吗?

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

    我刚刚解决了。  我已经在 callApplication 函数中添加了一些附加代码、这是 CPU 的 R0寄存器的更改。  

    我现在将应用程序加载程序放入了针对 I satrt BIOS 的主函数中、以避免 TI-RTOS 出现问题。

    void CallApplication (uint_fast32_t ui32StartAddr)
    {
    //
    //将矢量表设置为闪存中应用程序的开头。
    //
    HWREG (NVIC_vtable)= ui32StartAddr;
    
    //
    //从应用程序的矢量表加载栈指针。
    //
    _asm (" LDR r1、[r0]\n"
    " mov SP、R1\n");
    
    //
    //从应用程序的矢量表加载初始 PC 并分支到
    //应用程序的入口点。
    //
    _asm (" LDR r0、[r0、#4]\n"
    " BX r0\n");
    }
    
    int main (void)
    {
    if (HWREG (FileOneJumpAdress)!= 0xFFFFFFFF)
    {
    CallApplication (FileOneJumpAdress);
    }
    (笑声) 

    谢谢、

    Chris