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.

[参考译文] TM4C123AE6PM:使用 PWM 时出现硬故障

Guru**** 2465890 points
Other Parts Discussed in Thread: TM4C123AE6PM, TM4C123GH6PM

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1548652/tm4c123ae6pm-hard-fault-using-pwm

器件型号:TM4C123AE6PM
Thread 中讨论的其他器件: TM4C123GH6PM

工具/软件:

我初始化脉冲宽度为 0 的 PWM;一切都正常运行。  一段时间后,我改变脉冲宽度,系统继续一段时间,然后发出一个硬故障;此时 CFSR 是 0x00020000,这是“指令非法使用 EPSR。  HFAULT 寄存器是 0x40000000、这是“强制故障、请参阅其他寄存器来确定源“、但从 CFSR 中可以看出、BFSR 和 MMFSR 都是 0。  代码如下:

   SysCtlClockSet (SysCtl_SYSDIV_2_5 | SysCtl_XTAL_20MHz | SysCtl_USE_PLL | SysCtl_OSC_MAIN); // 80MHz

   SysCtlPeripheralEnable (SYSCTL_PERIPH_GPIOE);

   SysCtlPeripheralEnable (SYSCTL_PERIPH_PWM1);

(在此处延迟一点)

   GPIOPinTypePWM ( GPIO_Porte_base、PD_Pwm1_2_bit);

   GPIOPinConfigure (GPIO_PE4_M1PWM2);

   SysCtlPWMClockSet (SYSCTL_PWMDIV_64);            // 1250KHz PWM 时钟。

   PWMGenConfigure (PWM1_BASE、PWM_GEN_2、PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);

   PWMDeadBandDisable (PWM1_BASE、PWM_GEN_2);

   PWMGenPeriodSet (PWM1_BASE、PWM_GEN_26250);    // 200Hz

   PWMPulseWidthSet (PWM1_BASE、PWM_GEN_2、0);       // 0%占空比

   PWMOutputUpdateMode (PWM1_BASE、PWM_OUT_4_BIT | PWM_OUTPUT_MODE_NO_SYNC);

   PWMGenEnable (PWM1_BASE、PWM_GEN_2);

过了一段时间我发出:

   PWMPulseWidthSet (PWM1_BASE、PWM_GEN_2、69);      //~10%

过了一段很长的时间后出现了硬故障。

谢谢、Doug

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

    尊敬的 Doug:

    [引述 userid=“333787" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1548652/tm4c123ae6pm-hard-fault-using-pwm

    过了一段时间我发出:

       PWMPulseWidthSet (PWM1_BASE、PWM_GEN_2、69);      //~10%

    过了一段很长的时间后出现了硬故障。

    [/报价]

     除 PWM1_GEN_2 之外、其他哪些外设运行?  

     硬故障发生需要多长时间? 在这里、您说过、经过了很长时间。 您能量化吗?  

     我怀疑改变 PWM 占空比会导致器件出现硬故障。 它很可能是由其他原因造成的。

     您当前的栈大小是多少? 您能尝试增加堆栈大小吗? 它有什么不同吗?

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

    其他外设:UART1、UART4、EEPROM、PWM0、PWM1、 CAN1、所有 GPIO。  不知道多久、当我设置脉冲宽度并在故障时关闭时、可以在 GPIO 上产生脉冲、这样就会让您知道。  我的调度器处于循环中、并使 CPU 处于睡眠状态、直到中断为止、在本例中只是每 10ms 触发一次的系统计时器。  设置脉冲宽度后、我跟踪调度员运行了一段时间。  当前栈大小 1024 字节。  我们将运行一些测试并返回给您。

    我很惊讶 TI 或其他人没有为 FaultISR 编写更好的故障处理程序、它会查询寄存器和栈、并在一些存储器位置放置一些有意义的诊断消息、然后进入可在调试器中查询的 while (1) 循环。  当我试图完成工作、花半天或更多时间研究和了解如何调试此问题时、这是一种痛苦、在我的案例中、到目前为止还没有足够的了解发生了什么。

    谢谢、Doug

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

    尊敬的 Doug:

     要解开导致故障的违规代码行、您可以按照本应用手册进行操作。  诊断 StellarisRegistered微控制器中的软件故障

     在下面的文章中,切斯特提供了一个解决方案,使用 gel 脚本展开违规行,我觉得这很有用。   

    https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/810598/ccs-tm4c1294kcpdt-how-do-i-get-the-stack-unwound-in-exception-handlers/3026599#3026599

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

    尊敬的 Charles:

    查看示例 GEL 文件、并有几个问题。  即使 TM4C 是 Cortex M4、它似乎使用的是 CortexM3.util.gel、是正确的?  我找不到如何使用修改后的 CortexM3.util.gel、文档说明它是通过 Tiva TM4C123AE6PM.ccxml 文件加载的、但没有引用.gel 文件。

    谢谢、Doug

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

    尊敬的 Doug:

     M3 和 M4 在架构上基本相同。 主要区别在于在 M4 上增加了 DSP 指令支持、以及支持 FPU 的选项。 CortexM3.util.gel 只是 继承自前代产品的文件名。 如果需要、您可以将其重命名为 Cortexm4.util.gel 等任何内容。  

    目标配置文件指定 tm4c123gh6pm.gel、tm4c123gh6pm.gel 指定 CortexM3_util.gel。  

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

    啊,我不知道。  谢谢

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

    好吧、对.gel 文件所做的更改很好地跟踪了这一点(为什么这不是 CCS 的标准部分?)、错误发生在 strcmp () 调用中、其中一个地址是非法的。  它被调用是因为函数返回到错误的地址 — 为什么发生这种情况是一个大头划伤器。

    此函数接收已发出命令的消息、并扫描显示器命令首字母缩略词以查找要运行的命令。

    当我运行导致故障的命令时、它不会在该函数上的最后一个命令(称为命令)之后返回到、而是返回到绿色突出显示的行、并且 strcmp() 导致故障。  这是被调用的函数:

    如果我注释掉 Validate1or2uintParams()、则不会发生故障。  以下是该函数:

    也已使用过其他几个项目。

     下面是“堆栈使用情况“图形、我将堆栈从 1024 提升到 2048、这些图形看起来仍然是 1024。

    ???  想法?  谢谢、Doug

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

    似乎是被人搞砸了。  当我现在启动调试会话时、不是在 main() 停止、而是显示以下内容:

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

    我为 Ducks 创建了一个新的工作区、并将其添加到文件中、并手动将参数设置为其他工作区中的参数。  异常行为仍然存在。

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

    尊敬的 Doug:

    [引述 userid=“333787" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1548652/tm4c123ae6pm-hard-fault-using-pwm/5963067

     下面是“堆栈使用情况“图形、我将堆栈从 1024 提升到 2048、这些图形看起来仍然是 1024。

    [/报价]

    您是否也在链接器命令文件中相应地更改了堆栈指针? 请参阅以下示例。

    很重要

    .intvecs:> app_base

    .text :> flash
    .const :> flash
    .cinit:> FLASH
    .pinit :> flash
    .init_array:> flash

    .vtable :> ram_base
    .data :> sram
    .bss :> sram
    .sysmem :> sram
    .stack :> sram


    }

    __STACK_TOP =__STACK + 2048 ;

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

    无论链接器命令文件中设置了什么、.map 文件都会显示栈为 2048。

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

    尊敬的 Doug:

     必须具有 __STACK_TOP =__STACK +  2048 定义栈开始的位置。 您可以声明为 ex。 8KB 栈、但如果栈指针仍指向 512B 而不是 8KB、则不会解决任何栈问题。 SP 是处理器在复位后读取的第一个内容。 除非您已经调整了 SP 并且仍然遇到硬故障、否则 需要在链接器命令文件中更改此值。  

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

    尊敬的 Doug:

     必须具有 __STACK_TOP =__STACK +  2048 定义栈开始的位置。 您可以声明为 ex。 8KB 栈、但如果栈指针仍指向 512B 而不是 8KB、则不会解决任何栈问题。 SP 是处理器在复位后读取的第一个内容。 除非您已经调整了 SP 并且仍然遇到硬故障、否则 需要在链接器命令文件中更改此值。  

     我还建议您尝试使用较大的大小(如 4KB)、如果可行、您可以将大小减小到适合所需的大小。  
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将两者设置为 4096、行为相同。

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

    这有点奇怪。 我不知道为什么会出现故障、因为您说在 PWM 中断后需要一段时间。 如果您创建一个 使用  Validate1or2uintParams 的小程序、它会失败吗?

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

    我正在使用 strtok 和 stoi 编写我自己的 sscanf() 函数的过程中、我将在 SetPWM 程序本身中告诉你明天的结果。

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

    尊敬的 Doug:

     当遇到硬故障时、 Validate1or2uintParams 是否第一次被调用? 或者 Validate1or2uintParams 已被多次调用而没有出现问题、直到它最后一次被调用并出现故障?  

     我将建议您在  Validate1or2uintParams 中放置一个断点 、并单步执行反汇编窗口以找出哪个指令是导致故障的违规指令。  

     我也想给你们一个机会,我将在下星期离开办公室。 我的回复可能会出现延迟。  

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

    尊敬的 Charles:

    这是第一次被调用。  我将尝试使用它的另一个命令,看看会发生什么(你的好主意)。  我有几件事要尝试。  它的作用类似于改变堆栈中的返回 PC。  我将了解是否能找到查看调用堆栈的方法。

    我会想念你的!

    %-) Doug

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

    非常有趣。  如果使用 strtok() 和 atoi() 解析命令行、则一切正常。  如果我使用 sscanf()(不调用 Validate1or2UintParams())、它会以相同的方式崩溃、Setpwm() 函数会返回到相同的错误地址。  调用使用 Validate1or2UintParams() 的不同函数可以正常工作。

    我找到了!!  显然堆栈正在以某种方式被丢弃。  Validate1or2UintParams 的一个参数是一个枚举、我将它强制转换为 uint*以进行工作调用、根据我读过的关于 C 的内容、C++可以将枚举转换为 int、很明显、编译器对枚举使用了不同的大小、可能是 8 位或 16 位值。  由于这两个参数是 Setpwm() 的局部参数、因此它们在堆栈中、并且由于转换、返回地址被交换。  每天学习新东西。

    希望您下周将度假、如果是、祝您度过愉快的时光。

    谢谢、Doug

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

    尊敬的 Doug:

    我找到了它!!  显然堆栈正在以某种方式被丢弃。  Validate1or2UintParams 的一个参数是一个枚举、我将它强制转换为 uint*以进行工作调用、根据我读过的关于 C 的内容、C++可以将枚举转换为 int、很明显、编译器对枚举使用了不同的大小、可能是 8 位或 16 位值。  由于这两个参数是 Setpwm() 的局部参数、因此它们在堆栈中、并且由于转换、返回地址被交换。  每天学习新东西。

    很高兴您找到了这个问题。 我还在学习一些新内容、因为我  以前没有使用过 Validate1or2UintParams。  

    [引述 userid=“333787" url="“ url="~“~/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1548652/tm4c123ae6pm-hard-fault-using-pwm/5967691

    希望您下周将度假、如果是、祝您度过愉快的时光。

    [/报价]

    谢谢! 非常感谢。