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.

[参考译文] CCS/CC1352R:突然调试停止

Guru**** 2558810 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/959386/ccs-cc1352r-suddenly-debugging-stops

器件型号:CC1352R

工具/软件:Code Composer Studio

当我调试程序时、调试似乎停止了。 我猜是我在处理器中设置了一个"不应设置"的寄存器。 之后、Code Composer 窗口中的 SUSPEND 按钮被禁用。 我只能终止调试。 处理器似乎也会执行某种停止。 至少再也没有发生任何事情了。

从优秀的旧 Atmet 处理器和 Studio、我知道我可以一直暂停/暂停执行、而 Studio 会向我展示处理器的位置。 实际上、CPU 正在执行某个操作、程序计数器指向某个操作。 另外一个问题是程序计数器后面的指令是否有意义。

我使用 TI-RTOS、甚至在异常处理程序中有一个断点。 但这也不会触发。

我是否可以通过某种方式禁用调试支持本身? 还是处理器由于错误而进行复位、但在复位后无法开始运行?

那么、我甚至无法通过 XDS110调试器暂停/暂停执行的状态可能是什么?

此致
Erwin

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

    您好!

    [引用 user="Erwin Ahlers"]当我调试程序时、调试似乎停止了。 我猜是我在处理器中设置了一个"不应设置"的寄存器。 之后、Code Composer 窗口中的 SUSPEND 按钮被禁用。 我只能终止调试。 处理器似乎也会执行某种停止。 至少再也没有发生任何事情。[/引述]

    如果我不得不猜测、您似乎没有 正确的调试上下文。 您能否确认 在调试视图中选择了正确的上下文

    谢谢

    Ki

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

    我现在看到以下情况:

    ISET 我的代码中的断点。 调试时、它在该断点处停止。 我想显示的调试上下文看起来不是很糟糕:

    如果我继续运行几秒钟、挂起按钮仍然被启用、但按下它会导致

    我的器件不执行任何操作、我只能停止调试。 这种情况与禁用挂起按钮但结果相同的情况略有不同。 我无法停止使用器件来了解我想在哪里猜到我为什么会使用该解决方案。

    指向另一个问题的链接显示了具有一些连接的项目的属性页。 在我的案例中、并非所有内容都已填充。

    这会是个问题吗? 当我按下 Verify... 出现一个窗口、告知一切正常。

    我很确定我的代码中有一个问题、该问题会将器件置于显示此行为的状态。 但我不知道这可能是什么。 正如所写的、我认为使用调试器时、我始终可以暂停执行。 当然、仅当它连接时。 但在这里、器件似乎断开了与 XDS110的连接。 PC 和 XDS110之间的连接(由于这种"不幸"的虚拟 COM 端口行为、这种连接非常脆弱)仍然正常;至少我很确定。

    此致

    Erwin

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

    我认为这样、当我在器件停止工作之前没有断点时、"暂停"按钮永远不会启用。

    到目前为止、我对它进行了调试、以便在我对 I2C 进行清理时停止执行。 我使用 I2C、但在使用后用光笔将其解析。 我是这样

    HW.SignalPoint (4);
    HWREG (I2C0_BASE + I2C_O_SIMR)= 0;
    HWREG (I2C0_BASE + I2C_O_Soar)= 0;
    //Eventuell Vohandene 中断挂起位/标志 löschen
    HWREG (I2C0_BASE + I2C_O_SICR)= I2C_SICR_STOPIC + I2C_SICR_STARTIC + I2C_SICR_DATAIC;
    //主消融。 Der sollte zwar schon disabledsein、kostet aber auch nicht viel。
    HWREG (I2C0_BASE + I2C_O_MCR)= 0;
    HWREG (I2C0_BASE + I2C_O_MCTRL)= 0;
    HW.SignalPoint (5);
    
    //DIE 端口功能(数据和时钟) DER 引脚 zurücksetzen
    HWREG (IOC_BASE +(4*24))= IOC_IOCFG0_PULL_CTL_DIS;
    HWREG (IOC_BASE +(4*25))= IOC_IOCFG0_PULL_CTL_DIS;
    //HWREG (GPIO_base + GPIO_DOE31_0)&=~(1 << 25);
    HW.SignalPoint (6); 

    您可以看到、我实现了一些使 LED 闪烁的信号点。 程序运行到第5点。 当我注释这两行时、我将使用的引脚再次置于正常模式、程序也会运行到 signalPoint 6。 我还在此行设置了一个断点、并开始在汇编器级别单步执行。 从那看来、我的硬件实例似乎突然消失了。 在汇编器代码中、SignalPoint 函数应以参数6启动、步进停止、不再起作用。 但是、当对象存在于 SignalPoint 5时、它也应该存在于第6点、对吧?

    对象在函数中创建、因此应驻留在栈上。 我没有运行内存管理系统。 这可能是一个问题吗? 本地创建的对象是否也会调用需要堆的新/alloc 函数? 但我没有堆。

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

    [引用用户="Erwin Ahlers"]

    如果我继续运行几秒钟、挂起按钮仍然被启用、但按下它会导致

    [/报价]

    此错误表示调试器无法将 CPU 置于调试模式:

    https://software-dl.ti.com/ccs/esd/documents/ccs_debugging_jtag_connectivity_issues.html#device-hung

    原因可能会有所不同。 虽然我不确定、但这可能是您的应用程序存在一些争用问题。

    我将向器件专家介绍此主题。 他们可能会提供更多建议。

    谢谢

    Ki

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

    阅读提供的有趣链接会让我看到另一个可能的问题。 CC1352具有第二个射频内核。 在本例中、我在前两三秒内完全忽略该内核。 那么、我们可以在这里遇到任何类型的多核问题吗? 我应该对此射频内核进行一些初始化还是针对该射频内核进行一些初始化? 准备好硬件、两个内核之间不会发生竞争?

    Erwin

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

    我还观察到、当我使用调试器启动器件时以及当我在没有调试器的情况下启动器件时、器件的行为是不同的。 我们以前已经对此进行过处理、但后来突然、这种不同的行为消失了。 我尝试找到一些信息、当我使用连接的调试器运行我的器件时以及当它在没有调试器的情况下启动时、有何区别。 不幸的是,我没有成功。 您能否为我提供一些信息来源、以了解有何区别?

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

    您好、Erwin、  

    是否可以共享项目? 由于您选择了使用寄存器级访问自行执行实现、因此很难为您提供可能出现的问题的指示。 您是否检查了 IO 重新配置是否产生了任何意外中断?

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

    抱歉、我无法分享整个项目。 但是、为了让您了解我所做的事情:我需要一个通过 I2C 获取数据的专用引导加载程序。 为此、我在最后一个闪存页中创建了一个特殊的代码段、然后放置引导加载程序、该加载程序可以覆盖正常应用程序所在的所有其他闪存页。 启动配置使处理器跳转到最后一个闪存页中的引导加载程序启动代码。 因此、不会从应用程序执行硬件初始化、我必须使用较少的其他函数来执行此操作、以使引导加载程序保持较小的尺寸(对于所有代码、我只有不到一个闪存页)。 我在 C++中执行该实现、所有引导加载程序对象都在一个函数内创建、以便将它们放在栈上。 执行引导加载程序功能后、会自动调用这些对象的析构函数、并再次释放所有存储器。

    我已经拥有了可以接收和发送 I2C 数据的功能、但当调用析构函数时、我认为我需要在硬件中进行清理、以完成我在引导加载程序功能中完成的所有未设置操作。 我没有想到这一点(之前已经有过)、我发现了剩余应用程序启动时的问题、并假设存在 HW 默认状态。 由于应用程序使用 TI RTOS、我不确定它是否需要 HW 默认状态。

    当我在析构函数中执行清理(或者 在调用析构函数之前执行的特殊清理函数中执行清理、这没什么区别)时、我看到执行会停止。 就在几分钟前、我观察到以下情况。 我已经为 TI RTOS 提供的异常处理程序是使用寄存器位 CPU_SCS_CFSR_BFARVALID 和 CPU_SCS_CFSR_IMPRECISERR 调用的。 然后、我更改了异常处理程序内的显示例程。 现在不再调用异常处理程序本身。 奇怪。 我想它有一些时序问题、可能是与射频内核有关?

    您提到了我是否检查了不需要的中断。 我该怎么做? 那么、如果在我没有找到中断服务例程的情况下发生中断、会发生什么以及如何检测到这种情况?

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

    Erwin、因为看起来您不使用 I2C 驱动程序、有什么原因?  

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

    在我们的应用中、我们还使用我们自己的 C++ I2C 驱动程序、该驱动程序也用于与 Atmel 处理器配合使用的其他项目。 但在引导加载程序中、我可以尝试另一个 I2C 驱动程序。 您能给我一个如何使用它的提示吗? 如前所述、我在闪存使用方面受到限制、所有这些引导加载程序内容都在初始化的第一个全局 C++对象的构造函数中执行。 所以,在 main 之前,它是 startet。

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

    您好、Erwin、

    我怀疑这与射频代码相关、它不会触发不精确的错误。 如果您将其保留并忘记再次注册、则可能会给您带来"意外中断"、但情况似乎并非如此。

    您是否曾尝试解码异常以跟踪原点? 以下站点对于继续讨论该主题非常有帮助: https://interrupt.memfault.com/blog/cortex-m-fault-debug#how-to-debug-a-hardfault-on-an-arm-cortex-m-mcu

    在无法依赖 TI-RTOS ROV 视图进行解码的情况下(例如在引导加载程序情况下)、我通常会使用这一代码段:

    /*
    
    \brief 调试堆栈指针。
    \param sp 堆栈指针。
    从提供的堆栈指针提供 CPU 状态的视图。
    /
    静态空
    debugHardfault (uint32_t sp)
    {
    volatile uint32_t r0;/< R0寄存器/
    volatile uint32_t R1;/< R1寄存器/
    volatile uint32_t R2;/< R2寄存器/
    volatile uint32_t R3;/volatile
    uint32_t R12;/< R12_t 寄存器
    /< LR 寄存器/
    volatile uint32_t PC;/< PC 寄存器/
    volatile uint32_t PSR;/*< PSR 寄存器*/
    (void)(r0 = sp[0]);
    (void)(r1 = sp[1]);
    (void)(r2 = sp[2]);
    (void)(r3 = sp[3]);
    (void = r4)(void);(void)(void)(r4)
    (void)(lr = sp[5]);
    (void)(pc = sp[6]);
    (void)(psr = sp[7]);
    
    //输入无限循环。 /
    for (;;;;){/ hang /}}}-->-----------------
    
    //
    
    
    \brief CPU 故障 ISR。
    这是当处理器接收到故障
    中断时调用的代码。 使用当前堆栈指针设置对 debugStackPointer 的调用。
    在这种情况下、堆栈指针将是导致 CPU
    故障的 CPU 状态。
    /
    static void
    faultISR (void)
    {
    asm volatile
    (
    "tST lr、#4. \n"ite
    eq "mrseq
    r0、MSP \n"mrsne
    r0、PSP \n"BX
    %0 \n":/
    输出/:/
    输入*/"r"(debugHardfault)
    
    );}
    

    请注意、它是为 GCC 编写的、因此您可能需要根据您使用的工具链调整内联汇编。  

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

    您好!

    我将整个项目缩减为可以共享的项目。 问题仍然存在、我的所有引导加载程序内容都在实际版本中的已剥离版本中。 我将所有内容放入 all.zip 中。 iCall 目录通常只包含链接、因此无法添加到 zip 文件中。 因此、我插入了文件 dummy.txt、实际上可以忽略它。

    在 C++构造函数的范围内、我现在创建了一个简单的 I2C 驱动程序、该驱动程序甚至可以正常工作。 但实际的 I2C 功能不在已剥离的项目中使用。 当不再需要引导加载程序中的 I2C 驱动程序时、我想清除我之前所做的所有操作。 在此清理中、CPU 停止与调试器通信。 当我在 Code Composer 中打开寄存器视图时、也会发生寄存器无法读取的情况、当目标没有响应时、这是有道理的。 不幸的是、我也不时(不经常)看到、当我单步执行程序时、一切都能正常工作。 但在 I2Cdriver.Cleanup 功能中、步进大多停止。

    如果这个问题能够得到解决,将会非常有益(即使对我来说也是绝对必要的)。

    e2e.ti.com/.../All.zip

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

    您好、Erwin、

    感谢您的分享。 我将仔细查看您的代码、看看我是否能够发现可能发生的情况。

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

    您好、Erwin、

    这是 PRCM 操作导致您头疼、我可以告诉您、PRCM 修改后的"加载"呼叫应跟进、等待加载完成。 尝试添加:

    while (!(HWREG (PRCM_BASE + PRCM_O_CLKLOADCTL)& PRCM_CLKLOADCTL_LOAD_DONE));

    拨打以下电话:

    HWREG (PRCM_BASE + PRCM_O_CLKLOADCTL)= PRCM_CLKLOADCTL_LOAD;

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

    您好、M-W、

    首先、很抱歉、我现在才看到您的答案。 我收到的电子邮件通知被误解了、因此我仍然处于"等待应答"状态。

    我对上述问题是有疑问的。 有一个带有 asm (" nop")指令的255匝循环。 这样、我们通常等待足够长的时间、以便将更改执行。 但我同意并得出了同样的结果、即这样一个 while 循环会好得多。 感谢您确认我的理解是正确的。

    但我发现了真正的问题。 在我的清理代码中、行 HWREG (PRCM_BASE + PRCM_O_PDCTL0)= 0;

    因此、我禁用外设、串行和 RFC 电源域。 之后、我尝试执行 GPIO 操作。 但 GPIO 是外设电源域的一部分、因此无法实现。 当保持外设电源域处于活动状态时、调试不会停止、我的应用程序会按预期继续。

    现在有趣的是、这种配置错误的后果是调试器无法再工作。 JTAG DAP 是 CPU 电源域的一部分、不能禁用(原因很好)。 那么、CPU 是内部的、还是更好的硬件、处于等待 GPIO 模块中从未出现的状态变化的状态? 这种状态没有保护机制?

    没关系、我很高兴应用程序现在可以按预期工作。

    BTW:我现在是否应该像实际那样把我的答案评价为"这解决了我的问题"?

    此致
    Erwin

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

    您好、Erwin、

    有趣的是、我在您发送的代码中发现的唯一禁用了电源域的部分是"HwDeInit"、而在我看来、这似乎是一个实际上从未运行的函数(换句话说、我认为禁用电源域没有问题)。 在这方面、如果您实际上在自己的一侧之前碰巧禁用了电源域、那么这将解释故障。 访问未上电的寄存器在行为上是高度未定义的、在某些情况下、它会导致器件断开 JTAG 连接(除其他外)。

    请注意、CPU 电源域可作为 PRCM 中的 PDCTL1寄存器供电。 实际上、我们的电源驱动器始终会实施这种做法。 由于大多数 JTAG 都在 AON 空间内、因此从调试的角度来看也很好。 这假设器件未完全崩溃(就像您的情况一样)、因为 JTAG DAP 可能无法访问。 这种"调试器崩溃"通常仅在访问未通电外设等错误时发生。