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:当基本应用程序地址被改变时、RTOS 任务触发出现问题。

Guru**** 2524550 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/1046056/tm4c1290ncpdt-problem-with-rtos-task-firing-when-base-application-address-is-changed

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

大家好、

我对 TI RTOS 非常陌生、现在正在解决一个问题、即一旦我更改应用代码基址、计时器中断回调就不会触发。 我有一个心跳回调函数、每500ms 切换一次 LED。 当二进制文件在0x00闪存时、一切正常。  

然后、我尝试将上述二进制文件与自举以及其他一些需要应用二进制文件从0x44100开始的内容捆绑在一起。 我 在 RTOS 配置文件中适当地设置复位矢量地址"m3Hwi.resetVectorAddress = 0x44100"、并且可以在观察二进制文件时正确地看到它放置在那里。 启动后、自举会成功跳至应用程序代码并运行(心跳之前的一些预期 LED 活动证明了这一点)。 但是、我的心跳信号从未运行。 如果我调试并在回调函数中放置一个断点、它永远不会命中。 相反、如果我对0x00处的二进制文件执行相同的操作、则回调会命中并执行检测信号。

对我来说、这表示计时器问题或版本中不起作用的中断配置问题(更改了应用程序基址)。 它还会向我表明、无论问题是什么、都与应用程序地址更改直接相关。 我想知道是否有人对问题可能是什么有任何想法。  在 m3Hwi.resetVectorAddress 之外、是否有任何与需要更改的中断相关的东西? 在0x00时、RTOS、时钟或中断是否需要在不在0x00时进行设置或配置?

感谢您的任何帮助。 谢谢。

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

    尊敬的 Mike:

    我认为、根据您描述应用二进制地址的方式、您的向量表不会与页边界对齐。

    请参阅以下 TivaWare 中闪存引导加载程序的摘录、其中提供了良好的背景:

    //*****************************************************************************
    //
    // The address at which the application locates its exception vector table.
    // This must be a multiple of 1024 bytes (making it aligned to a page
    // boundary).  Typically, an application will start with its vector table and
    // this value should be set to APP_START_ADDRESS.  This option is provided to
    // cater for applications which run from external memory which may not be
    // accessible by the NVIC (the vector table offset register is only 30 bits
    // long).
    //
    // Depends on: None
    // Exclusive of: None
    // Requires: None
    //
    //*****************************************************************************
    #define VTABLE_START_ADDRESS    0x4000

    如果您真的无法将应用程序设置为0x44000、则需要将其设置为加载到0x48000并从0x48000开始。 我认为这应该解决你的问题。

    此致、

    Ralph Jacobi

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

    您好、Jacobi、

    首先、我非常感谢您的回答。 我喜欢你的想法。 虽然这很可能是真的、但这种结构与我们拥有的其他 TI 芯片上正常工作的其他固件(相同的地址、引导加载程序等)所使用的结构相同、这是奇怪的。不过、不同的应用程序)。 我想,如果这是问题,我们会到处看到它。 不过、我仍会尝试这种方法。

    我注意到了一些新情况。 当二进制文件加载到0x00时、所有文件都按预期运行。 当在我们的自定义地址加载时、当我单步执行代码时、所有内容看起来都已正确初始化(使用 RTOS 对象查看器)、但从未发生任何变化。 在进一步检查后、代码无限期地运行空闲任务。 这再次看起来可能是一个中断问题、就好像没有任何东西改变空闲任务的流程一样。

    但是、ROV 中的 HWI 在工作时看起来与列表完全相同。

    我注意到的一个奇怪现象是、我们的 RTOS 配置中的 halHwi.checkStackFlag = true。 此流程经常从空闲任务中断以运行 ti_sysbios_hal_HWI_checkstack(),并且似乎每次都指示有溢出。

    图片中的堆栈大小为2048、我尝试增加到4096、但没有成功。 我怀疑堆栈大小是实际的问题、因为相同的配置在0x00工作。 此结果是否会产生任何天线? 我假设 HWI 堆栈溢出肯定会使 HWI 功能混乱、从而导致时序/回调。

    再次感谢您的帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="189615" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1046056/tm4c1290ncpdt-problem-with-rtos-task-firing-when-base-application-address-is-changed/3869539 #3869539">如果您真的无法将应用程序设置为0x44000、则需要将其设置为从0x48000加载并启动。 我认为应该解决您的问题。[/引述]

    TM4C1294NCPDT:RTOS:BIOS 不工作 是一项不同的调查、显示 TI-RTOS 使用  的 m3Hwi.resetVectorAddress 是0x8100、它只有256字节对齐。

    [引用 userid="501982" URL"~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1046056/tm4c1290ncpdt-problem-with-rtos-task-firing-when-base-application-address-is-changed "]在0x00时、RTOS、时钟或中断需要在不是0x00时设置或配置吗?

    自举是否使用中断或应用程序使用的任何外设?

    如果是、则自举在调用应用程序之前会做什么?

    只需尝试排除  m3Hwi.resetVectorAddress 的更改 是问题所在。

    在上面引用的线程中发现了一个问题:如果在启动应用程序之前调用了 IntMasterDisable()的启动加载程序,SYS/BIOS 应用程序将在所有中断被禁用时启动,这与处理器复位时的初始状态不同。

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

    尊敬的 Mike:

    老实说、这些高级 RTOS 主题很难提供帮助、因为我们团队的知识主要集中在 TM4C 硬件本身的外设等方面。因此、当涉及到与 BIOS 更相关的 RTOS 元素时、 我们没有广泛的知识可供借鉴。 您已经使用所有合适的工具来调查根本原因。 堆栈溢出问题当然是我想象中会影响事情的问题、但我还不确定根本原因。 我将尝试搜索类似的问题、看看我是否可以通过这种方式找到有价值的东西。

    与此同时、切斯特比我有更好的记忆、并挖掘出了一条类似的线索、他能够帮助解决客户问题。 我建议检查您的应用是否同样的情况。

    此致、

    Ralph Jacobi

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

    你(们)好。 感谢您的周到回应。

    首先、我同意您的观点。 我知道使用相同引导加载程序/闪存地址设置在同一芯片组上运行的其他固件。 理论上唯一不同的是应用程序代码本身。 包装引导加载程序和闪存结构相同。 我在非页对齐地址加载时看到其他应用程序成功运行。

    遗憾的是、这有点像双刃剑、因为引导加载程序在成功加载并跳转到同一地址的其他基于 TI-RTOS 的固件时被视为"黄金"。 尽管如此、我返回查看了引导加载程序代码、它不执行任何主要操作、例如禁用中断。 本质上只需最小的时钟初始化、基本代码验证(CRC)、然后跳转到代码。

    我意识到我在上面所说的"应用程序代码问题"、我不会对此作出裁决。 对于该固件和 TI-RTOS 的新功能需要大量的消化、尤其是在遇到类似的奇怪问题时。 现在我将研究我在上面回答的空闲循环/HWI 溢出错误、因为这似乎会影响时钟模块/时序正常运行的能力。 由于我在0x00没有看到该错误、因此以某种方式将其与地址更改相关联。 我还将查看链接的主题以了解相关想法。

    老实说,这个问题是一个很好的方法来学习 TI-RTOS 并更新我的低级内存技能:)。 感谢您的反馈。

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

    我明白 Ralph 不用担心。 这些主题很复杂,更难通过论坛帖子传达问题:)。 我将仔细观察这些柱、并不断挖掘、我每天会稍微深入一点。 感谢您的帮助!

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

    ---------- 更新了---

    找到解决方法后、我想提供有关导致此问题的原因的更新。  

    阅读链接后、Chester 将我转至: https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1024278/tm4c1294ncpdt-rtos-bios-not-working/3787593#3787593

    我决定在输入应用程序时检查 PRIMASK 寄存器。 出于某种原因、该值设置为1。 我在两种情况下都验证了应用程序在0x00加载且在不同芯片上完全不同的固件(使用相同的引导加载程序和闪存结构)、在程序进入时 PRIMASK 为0。

    为了测试它,我调用 IntMasterEnable();在我不工作的应用程序代码方案的开头,代码/检测信号开始执行。 这就像 PRIMASK 为1时一样、它禁用了使 RTOS 系统接地的所有中断。

    我现在要探讨的问题是、为什么 PRIMASK 在本例中设置为1 (大概由引导加载程序设置)、但设置为0、在其他情况下使用相同的引导加载程序可以正常工作。 如果 PRIMASK 设置为1是在应用程序代码之前发生的(这种情况看起来是这样的)、那么如果将相同的引导加载程序、闪存设置和芯片用于其他无需修改即可工作的固件、为什么不会发生这种情况。

    如果有人在该主题上遇到相同的问题、请在应用程序启动时检查 PRIMASK 值、并确保该值不为1。

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

    尊敬的 Mike:

      在跳转到引导加载程序之前、我会在您的引导加载程序或应用程序内部查找 IntMasterDisable 调用或 CPUcpsid。

    我相信您已经在引导加载程序中查找了前者、因此可能是后来被调用的、但我认为可能是在应用程序本身内部调用它。   在跳转到引导加载程序之前、有人调用 IntMasterDisable 并不少见。  

    此致、

    Ralph Jacobi

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

    你(们)好。 感谢您的建议。 自从这篇文章以来、我发现 PRIMASK 实际上是由我们的引导加载程序在某个位置设置的。 仍不清楚在哪里。 实际上、我们很幸运、我们的固件"正常工作"在 BIOS 启动之前由于不相关的原因进行了使能中断调用。

    我认为这必须是永久性的"权变措施"、因为引导加载程序在许多地方都使用、更新起来会很复杂。 出于好奇、我试图弄清引导加载程序在何处设置 PRIMASK。 正如我之前说过的、它只是执行一些基本的振荡器设置。  

    我注意  到、我们写入必须处理中断的 SYSCTL_MISC 和 SYSCTL_RIS 寄存器。 但从数据表中、我没有看到这些寄存器中的任何位字段明确指出了更改 PRIMASK 值的结果。 除此之外、它还需要大量 RCC 寄存器写入、这看起来并不重要。 引导加载程序在尝试单步调试时不合作。

    我认为可以肯定的是、最初的问题已经解决了、这只是出于好奇而继续存在。 感谢您和 Chester 的帮助。

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

    尊敬的 Mike:

    也许您可以在 PRIMASK 的源代码上执行一个协议搜索。 即使 是 CPUcpsid API 也会将其用于汇编代码:

    uint32_t
    CPUcpsid(void)
    {
        //
        // Read PRIMASK and disable interrupts.
        //
        __asm("    mrs     r0, PRIMASK\n"
              "    cpsid   i\n"
              "    bx      lr\n");
    
        //
        // The following keeps the compiler happy, because it wants to see a
        // return value from this function.  It will generate code to return
        // a zero.  However, the real return is the "bx lr" above, so the
        // return(0) is never executed and the function returns with the value
        // you expect in R0.
        //
        return(0);
    }

    此致、

    Ralph Jacobi