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/TM4C1294KCPDT:TM4C1294KCPDT

Guru**** 2556210 points
Other Parts Discussed in Thread: SYSBIOS

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/777520/rtos-tm4c1294kcpdt-tm4c1294kcpdt

器件型号:TM4C1294KCPDT
Thread 中讨论的其他器件:SYSBIOS

工具/软件:TI-RTOS

您好!

我正在尝试为 TM4C1294电路板开发定制的引导加载程序。 由于我们需要启动加载程序中除固件更新之外的其他一些功能、我们的计划是使用 TI-RTOS 本身开发启动加载程序。

是否可以从基于 TI-RTOS 的引导加载程序跳转到应用程序映像(也是使用 TI-RTOS 开发的)?

此致、

Sooraj

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我真的不明白为什么不这么做。
    请查看此帖子、该帖子可能也会有所帮助。
    e2e.ti.com/.../679617
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    感谢你的答复。
    我访问了您分享的链接、并在其中进行了讨论。
    此外、我尝试从 TI-RTOS 应用程序跳转到复制到闪存存储器不同位置的固件映像。 它的工作原理。

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

    我使用 TIRTOS 开发了一个简单的应用程序、可以将映像二进制文件复制到闪存并跳转到闪存。

    我创建了两个二进制映像来切换 LED、一个映像具有 TIRTOS、另一个映像是裸机。 它构建为从0x00200000位置运行。
    我使用此代码将裸元映像复制到闪存、并尝试跳转到该映像。 当我跳转到图像的起始位置时失败、但当我将跳转位置更改为函数_c_init00的位置时、它有效。

    当我尝试使用 TI RTOS 构建映像时、在这两种情况下都无法运行。
    我尝试了在您共享的讨论中建议的方法来指定 RTOS 矢量。 仍然失败。

    var ti_sysbios_family_arm_m3/hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    TI_SYSBIOS_family_ARM_m3/Hwi.vectorTableAddress = 0x4000;

    您能回答以下问题。

    当我跳转到图像的起始地址时、如何使其运行?

    基于 RTOS 的映像会出现什么问题?

    在基于 RTOS 的映像中、是否需要在除以外的任何位置指定映像地址
    CMD 文件和.cfg 文件?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您是否希望应用程序从0x200000开始? 为什么您有 ti_sysbios_family_arm_m3/hwi.vectorTableAddress = 0x4000?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    很抱歉、我直接从您分享的讨论中复制了该错误。
    在我的代码中、我将地址0x4000替换为0x200000。

    此致、
    Sooraj
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    很抱歉迟到了。 您的问题是否已解决。 如果您仍然对从引导加载程序调用 TI-RTOS 应用程序有疑问、我将向我们的 TI-RTOS 专家提出问题、以获取建议。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我没有听到你的反馈。 希望您能够解决该问题。 我现在将关闭该线程。 如果您有新问题、您可以打开新主题。 如果您解决了问题、您还可以与社区分享您的方法和发现、让寻求相同解决方案的人受益。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    很抱歉耽误您的回答、

    我管理了将执行分支到从引导加载程序代码加载到闪存中的映像。

    我按照以下步骤执行此操作。
    1.已将新固件映像的前4个字节加载到堆栈指针。 为此、我们将映像所在的闪存地址保留在寄存器 r0中。
    asm (" ldr sp、[r0]");

    2.将接下来的4个字节加载到处理器寄存器(此处为 r0本身)并分支执行到该位置(这是_c_int00的地址)。
    这类似于 boot.asm 文件中的代码。
    asm (" LDR r0、[r0、#4]");
    asm (" bx r0");

    但我没有成功地从 C 代码将地址正确地传递到寄存器 r0。

    我注意到、当我向函数传递整数参数时、该参数会复制到寄存器 r0。

    那么、我所做的是、向其写入一个具有整数参数的函数。
    在函数内部、将 r0指向的位置中的数据移动到 sp、然后跳转到下4个位置指向的位置。 因此、该函数将与此类似、

    例如:void funcname (unsigned int argName)

    asm (" ldr sp、[r0]");//此处是 r0中 argName 的内容,即使没有特别移动到它*/

    asm (" LDR r0、[r0、#4]");
    asm (" bx r0");


    我想验证这些步骤、
    您能否确认这种方法是否正确?
    此外、是否确定函数'argName'参数中的内容始终复制到寄存器 r0?
    如果没有,我们如何做到这一点?

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

    是的、在 C 语言中调用函数时、第一个参数始终在 R0中传递。

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

    尊敬的 Bob Crosby:

    感谢您的确认。

    此致、
    Sooraj

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

    现在我面临一个新问题。
    从引导加载程序加载的应用程序将运行几秒钟并停止运行。
    当我检查处理器寄存器时、我注意到 PSR 中的异常编号25。
    如果我使用 JTAG 运行应用程序、它将不会出现任何问题。

    我的引导加载程序构建为从地址0x0000 0000和应用程序到0x0001 0000运行。
    我使用 TI-RTOS 创建了示例应用。
    我修改了应用项目的链接器命令文件、如下所示、

    存储器

    Flash_boot (RX):origin = 0x00000000,length = 0x00010000
    Flash_app (RX):origin = 0x00010000,length = 0x00060000
    SRAM (rwx):origin = 0x20000000、length = 0x00020000


    部分

    .text:> flash_app
    .const:> flash_app
    .cinit:> flash_app
    .pinit:> flash_app
    init_array:> flash_app

    .data :> SRAM
    .bss:> SRAM
    .sysmem:> SRAM
    .stack:> SRAM


    __STACK_TOP =__STACK + 512;

    和应用项目的配置文件(XXX.cfg)、我添加了以下行:

    var ti_sysbios_family_arm_m3/hwi = xdc.useModule('ti.sysbios.family.arm.m3.Hwi');
    TI_SYSBIOS_family_ARM_m3/Hwi.resetVectorAddress = 0x00010000;

    从引导加载程序调用应用程序的函数的实现方式如下所示、
    void func (unsigned int arg)

    asm (" ldr sp、[r0]");
    asm (" LDR r0、[r0、#4]");
    asm (" bx r0");


    调用函数时、应用程序固件的地址传递给函数。 例如:func (0x00010000);

    您能在该实现中发现任何问题吗?

    此致、
    Sooraj
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    将控制传输到引导加载程序的代码看起来不错。 您是否已验证是否已将正确的堆栈地址编程到位置0x10000中、并在0x10004中获得正确的起始地址? 此外、0x10004处的地址需要为奇数、因为 M4仅使用 Thumb 2代码。 如果应用程序开始运行、然后失败、则可能是由中断引起的问题。 下面是一个应用手册、指导您完成查找中止根本原因的过程:
    www.ti.com/.../spma043.pdf
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    感谢您的回复、
    我介绍了您共享的应用手册。

    分析完程序停止运行时的处理器寄存器(如文档中所述)后、我可以发现定时器1触发的中断导致了问题。

    我通过禁用应用程序映像中的计时器来尝试、我没有遇到任何问题。 然后、我将用于禁用计时器的代码移动到引导加载程序中、这次它也没有出现任何问题。

    我没有启用代码中的计时器、我想知道为什么未启用的计时器会触发中断。
    当我尝试禁用定时器1时、我必须首先通过调用函数'SysCtlPeripheralEnable (SYSCTL_Periph_Timer1)'来启用外设。

    由于引导加载程序代码与应用程序代码保持独立、因此将来有机会在应用程序代码中启用计时器以使用它、那么它会产生什么问题吗?

    您能再确认一点吗、禁用计时器是否是解决此问题的正确方法?

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

    由于主例程可能启用了其他中断源、我建议您在 NVIC 上禁用它们、如在 boot_demo.c 示例中所做的那样 在调用引导加载程序之前、最好在应用程序代码中完成此操作:

    //
    //我们必须确保在进入之前关闭 SysTick 及其中断
    //引导加载程序!
    //
    ROM_SysTickIntDisable();
    ROM_SysTickDisable();
    
    //
    //禁用所有处理器中断。 而不是禁用它们
    //一次一个,直接写入 NVIC 即可禁用所有功能
    //外设中断。
    //
    HWREG (NVIC_DIS0)= 0xffffffff;
    HWREG (NVIC_DIS1)= 0xffffffff;
    HWREG (NVIC_DIS2)= 0xffffffff;
    HWREG (NVIC_DIS3)= 0xffffffff;