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.

[参考译文] TM4C129ENCPDT:内核复位/系统复位--每种类型的复位何时发生?

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/602638/tm4c129encpdt-core-reset-system-reset----when-does-each-type-of-reset-occur

器件型号:TM4C129ENCPDT

因此、我的理解是、内核复位仅复位 Cortex M4内核、而系统复位则复位整个 TM4C。

除了在 CCS 中进行调试之外、是否还有其他会导致内核复位而不是系统复位的情况?

我之所以提出这一问题、是因为在内核复位后、处理器状态似乎严重混乱。 值得注意的是、堆栈指针 SP 是一些疯狂的值、通常约为0xFFFFFFFC 或0xFFFFFFFE 或其他值。 程序中的第一条指令是一个推入指令、它尝试写入不存在的存储器、这会立即使执行混乱得非常严重。 我猜它甚至不能分支到具有这种混乱状态的故障处理程序。

这是 LaunchPad 板上的 TM4C129ENCPDT。 我使用的是 CCSv7、它使用 GCC (gcc-arm-none-eabi-4_9-2015q3)和自定义链接器脚本进行编译、并启动将入口点设置为 ResetISR()、后者调用 C 库的_start()、后者调用 main()。 程序启动并运行正常,SP 整齐地设置为0x20040000 --如果并且仅当它从系统复位启动时。 由于 SP 中的神秘值(可能还有其他混乱的处理器状态)、从内核复位开始基本上是不可能的。

这种现象是否让任何人都熟悉? 我应该担心这个问题、还是它只影响调试而不影响其他方面?

***编辑***

它不仅仅是堆栈指针。 它也是程序计数器和链接指针。 在某种程度上、当发生内核复位时、处理器就会被响应。 我觉得这不应该发生。 请参阅屏幕截图--这是内核复位后或开始调试会话(我假设编程后执行内核复位)后的确切状态:


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    您是如何启动内核复位的? 内核复位由您的代码通过写入 APINT 寄存器中的 VECTRESET 位来启动。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在这种情况下、内核复位通过 CCSv7启动、以便在加载程序时进行调试、和/或通过按下工具栏中的内核复位进行。 我目前还不知道向 VECTRESET 写入任何内容。

    当发生系统复位时、程序启动良好。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    我认为 CCS 中的"内核复位"只是将 PC 移动到地址0x0。 它不会真正复位内核。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果是这种情况、那么我希望 PC 等于0x00000000。 但它等于0xFFFFFFFE。

    实际上、不能是这种情况、因为地址0x00000000应该包含初始堆栈指针、地址0x00000004应该包含程序入口点。 如果您打算内核复位从0x00000004读取该值并将程序计数器设置为该值,则应跳转到 ResetISR()。 它会执行该操作、所有操作仅在完成系统复位时才有效。 因此、无论内核复位执行什么操作、都会使其混乱、以至于程序代码无法控制。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    虽然我认为您的问题值得思考、但我想知道您为什么不只是执行系统复位。

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

    虽然我也(分享)海报 Robert 的(系统复位缺失)好奇心-您的"写信给 VECTRESET"是否能提供进一步的见解?    很难为这种蓄意的"绕过"辩护。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我试图确定是否值得追查这个问题的原因。

    我原来的问题是:在什么情况下会发生内核重置? 我的推理是、如果只有在 CCS 中进行调试时才发生内核复位、那么我们只能进行系统复位。

    但我后来发现、由于多种原因、包括软件请求、可能会发生内核重置。 某些 MCU 需要软件复位才能在引导加载程序和应用程序之间跳转、因此这对我们来说是一个问题。

    即使我们不必在软件中请求内核复位、跟踪此情况也很重要、因为这种奇怪的行为表明有些事情是不正确的、要么我们找到什么并修复它、要么它将继续通过其他方式对我们进行计时。 数据表非常清楚、内核复位后、PC 和 SP 加载了 VTABLE 中的值。

    我检查了 MCU 是否确实"卡住"、或者调试器是否显示错误信息。 我通过使软件中的 LED 闪烁来执行此检查。 如果在调试器显示 MCU 卡死时 LED 闪烁正常、则说明调试器有缺陷。 如果 LED 停止、则调试器正确且 MCU 实际上卡滞。 我执行了此检查、LED 停止闪烁、表示调试器正常、MCU 确实卡滞。

    我发现有一个矢量表偏移量(VTABLE)寄存器、该寄存器可以指示 MCU 在不同的存储器位置(在1024字节边界上对齐)查找矢量表。 这会使 SP 和 PC 混乱、因为任何类型的复位都会从 VTABLE 中加载这些值。 如果 VTABLE 最终重定位到未编程的闪存或其他包含垃圾的存储器、这将说明 PC 和 SP 等于0xFFFFFFFF 或类似值。 所以我触发了这个问题并检查了这个寄存器、希望发现它被弄乱了、但是发现它包含0x00000000。 那么、这不是。

    我列出了从简单且可能到困难和远距离检查的一系列事项。 到目前为止、该列表是:

    1.检查它是否仅是调试器(如上所述已经完成)

    2.检查 VTABLE (已如上所述完成)

    3.检查勘误表

    4.检查 BOOTCFG.EN (控制跳转到引导加载程序)

    5.检查 APINT (中断和复位控制)

    6.检查 RESBEHAVCTL (复位行为控制)

    7.检查 RESC (复位原因)

    8. GNU C library _start()函数的作用是什么? 跳过它是否允许程序在内核复位后运行而不触发此问题?

    9.我们的 UART 代码是否干扰内核复位?

    10.检查我们的二进制文件以验证 intvecs 的前2个 DWORD (但我相信它们会很好,因为它在系统复位后工作良好)

    11.检查目标配置或创建新配置

    12.在不使用项目的情况下启动调试器

    13.检查时序问题--重置是否需要太长时间?

    我将发布我找到的内容...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    好的、那么我继续、并且确实做到了这一点。 我在主循环中添加了以下代码:

    NVIC_APINT_R |= NVIC_APINT_VECT_RESET;

    这是使用来自 inc/tm4c129encpdt.h 的 TivaWare 目录下的定义。 它们的定义如下:

    #define NVIC_APINT_R (*((volatile uint32_t *) 0xE000ED0C))
    #define NVIC_APINT_VECT_RESET 0x00000001 //系统复位

    最奇怪的事情... 它似乎没有效果! 该程序会继续愉快地运行、使 LED 闪烁。

    我不知道这个 VECTRESET 东西可以信任多少、因为数据表中说:"这个位保留用于调试、读数为0。 该位必须写为0、否则行为不可预知。"

    嗯...

    我做错了吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为您应该只是调用 SysCtlReset。 您可能还想查看 SysCtlResetCuse

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

    首先-非常感谢您的专注努力。    我(现在)的期望是 、您对这些数据的展示将:

    • 鼓励该供应商进行进一步(或许更深入)审查
    • 识别您的"代码加法"中的任何问题  (我的公司从未雇用过、也没有雇用过)

    @我(曾在本论坛(几乎一直))从未注意到这种"核心重置" 受到重视...   (确实-几乎没有证据...)

    我们将救生艇抛在公海上、等待(供应商)救援。   (可能)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    @CB1_MOBILE、您是否在内核复位方面遇到过类似的问题?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我喜欢你的名单。 我立即想知道#9以及在不合适的时间中断的影响。 不过、我不希望这种情况能够定期重复。

    可能值得检查 SysCtlReset 采用的防护措施。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是对的、我应该调用 SysCtlReset()。 我在对写入寄存器的原因进行一些真正的擦除、但我记得有保护措施。 您必须首先写入密钥、即使是这样、除非您处于特权模式、否则它也不起作用。 顺便提一下、我如何知道我是否处于特权模式、并在这两者之间切换? 我仍然没有找到答案。

    总之、我完全忘记了 TivaWare 提供的功能可使这些操作变得简单。

    结果如下:我执行了 SysCtlReset(),它完全按照它应该做的那样:它复位到启动矢量(ResetISR())。 我多次尝试、每次都能正常工作。

    然后、我尝试运行该程序、暂停该程序、并通过调试器启动内核复位。 奇怪的是,这也是正确的,这与昨天的情况不同。

    昨天、调试器的内核复位相当可靠地触发了该问题。 如今、它工作正常。

    每次重新刷写程序后、问题仍然会立即触发、每次启动调试器时都会自动发生。

    昨天和今天之间的另一个区别是、昨天这个问题似乎只在使用 GCC 而不是 TI 编译时触发;今天、这两个问题的触发方式完全相同。

    由于行为似乎在变化、但我没有对软件进行任何更改、我目前认为它不是软件。 这更像是间歇性问题、与调试器执行的计时和/或特定事件序列相关。 我将查看我的调试设置:

    所有程序/存储器加载选项均已选中:
    *加载其他程序时禁用所有断点
    *程序终止时停止(需要设置断点)
    *启用 CIO 函数使用(需要设置断点)
    *启用半主机(需要在 SVC_Handler 处设置断点)

    除了第一个之外、我不确定其他三个因素是否合理。

    验证当前设置为快速验证。 (完全验证将回读闪存内容并对其进行比较、对吧?)

    连接选项有两个灰显选项、加上"在连接时重置目标"、未选中。 也许我应该检查一下吗?

    相比之下、"Reset the target on a program load or restart"(在程序加载或重新启动时重置目标)被选中。

    启动选项已选中"在调试器启动时连接到目标"和"从以前的会话恢复断点"。 "如果未选中目标连接或程序加载失败、则继续调试启动。"

    闪存设置是关键设置、我认为... 晶振频率设置为8MHz 并选中"程序加载到闪存存储器期间的复位目标"。 它设置为擦除整个闪存、空白检查整个闪存、CRC32整个闪存
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    喜欢您已确定/考虑和呈现的细节。    "不"-就像您一样-我们没有超越对"SysCtlReset()"的调用-它一直为我的组提供良好的性能。

    Robert 建议"深入探讨""SysCtlReset()"-寻求"保障措施"似乎确实值得...

    在  这种"核心重置"方面、我还有一个可能"值得考虑"的要点、即"供应商有限 CCS"的"能力"。   Robert 和我的团队都使用 IAR (我的团队同时使用编译器和 IDE)和备受推崇的"J-Link 和 J-Flash"(JTAG/SWD Pod) -但不使用海报的 MCU。    这是否是"供应商受限" IDE 实现的(另一个)限制?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我不希望 UART 中断与内核复位发生混乱、但 TM4C 存在一个问题、即内核复位不会禁用外设中断、因此在软件正确初始化之前可能会发生伪中断。 TM4C 论坛上的 Sticky POST 中有一种解决方法、即在启用外设之前禁用和复位外设、但我认为这还不够、因为中断仍可以在启动代码期间更早地发生。 我想、在将数据从闪存复制到 SRAM 或清除 BSS 之前、程序中的第一条指令应该是禁用所有中断。 然后在初始化完成后,应在 main()中显式启用它们。 但我必须先进一步研究。

    就 UART 干扰复位而言、导致我考虑这一点的是我在研究此问题时发现的另一篇文章。 我不记得当时的情况、但他们的问题最终以某种方式与 UART 相关。

    我猜是 UART 信号以某种奇怪的方式与调试信号混合。 过去、我们在原型板上遇到了最奇怪的问题、但结果却是最愚蠢的事情、例如、有人只在 MCU 的几个引脚上进行预焊接、忘记焊接其余的引脚、然后我们就像这样运行、对其进行编程、 想知道为什么会出现间歇性故障——大多数引脚是接触式的,但没有焊接!! 我认为这里不是这样。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12PM"]意外、如何知道我是否处于特权模式、并在两者之间切换? 我仍然没有找到答案。

    您将保持特权/监控模式、直到您关闭电源。 因此、除非您已切换到用户模式 、否则您将处于管理员模式。

    Robert   

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

    [引用 user="12ve12pm"]我想,在将数据从闪存复制到 SRAM 或清除 BSS 之前,程序中的第一条指令应该是禁用所有中断。 然后,在初始化完成后,应在 main()中明确启用它们。

    如果内核复位没有禁用中断、那么是。 否则、只有在拆分一个配置并启动另一个 A'la 引导加载程序时才需要该文件。

    我认为你使用 SysCtlReset 进行的测试已经有效地布局了、以避免在过程中产生无关中断的想法。

    Robert