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.

[参考译文] MSP430FG6426:在函数调用后、从寄存器处理的嵌套函数参数不会恢复

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1105294/msp430fg6426-nested-function-parameters-handled-from-registers-are-not-restored-after-a-function-call

器件型号:MSP430FG6426

尊敬的团队:

我有一个函数(function_1)可调用另一个函 数(function_2)、在执行最后一个叶函数并返回到调用方函数时、不会恢复局部函数参数。 我有一些 ISR 也并行运行(计时器、SPI、ADC)

我注意到、函数参数存储在寄存器中、这就是问题所在。 如果我尝试将这些参数移动为全局变量、那么我不会看到问题、 但我现在无法为我的完整软件执行此操作、并且希望在其根目录下修复问题、因为我看到下面的示例是有效的 C 用例、并希望它能够正常工作。

我在其他较小的项目中没有注意到这个问题、但当我开始构建较大的项目时、我的闪存大小达到31KB、现在我开始看到前面正常工作的代码出现这个问题。

如果我可以做些什么来使我的项目重新运行而不出现此问题、您可以在这里提供帮助吗?

CCS 版本- 9.2.1

示例:

函数_2 (uint32_t 参数3)

  //使用 Param3执行一些操作

函数_1 (uint32_t param1、 uint32_t param2、 uint32_t paramM3)

 //注意:编译器将这些参数值保存在寄存器中

 for (i=1;i<10;i++)

 {

   PARAM3 = PARAM3 + param1 + param2;//根据 param 1和2对参数3变量进行一些计算

   Function_2 (PARAM3);

   //注意:返回此函数_2后,不会恢复 Param1、2、3的原始值,从而导致故障

 }

MAIN ()

 while (1)

 {

  Function_1 (1、2、3);

 }

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

    我无法从您的代码框架中真正了解任何内容。

    寄存器被分组为已保存的调用方和被调用方保存的寄存器。 这为每个函数提供了一组可用于其操作的寄存器、而无需担心保存和恢复这些寄存器。 C 编译器非常适合观察这一点(可以绕过这一点、因为 gcc 具有"裸"函数属性)、因此您的问题几乎肯定是由其他因素造成的。 但如果没有违反的代码、就不可能说什么。

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

    我同意 David 的说法、他无法从发布 的代码框架中告诉任何内容。

    您是否能够:

    1. 发布显示问题的完整项目。
    2. 如果  您可以识别编译器生成的汇编器中的问题、请将信息发布到如何提交编译器测试用例中。

    由于中断处理程序必须将寄存器保存在堆栈上、因此问题可能是由堆栈损坏引起的、例如由于堆栈空间不足或程序写入无效指针。

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

    大家好、

    感谢您的回答。 我知道、框架代码不能帮助预见问题。  

    我将我的项目附在这里、我开始看到存储器 IC 处理(W25Q)的这个问题、它在项目太小之前就开始工作、而现在项目接近完成时又添加了大量内容、我看到这一损坏问题正在发生 随机地。 我注意到、当我的代码在无限循环中达到这种状态时、我注意到局部指针在从函数调用返回后损坏、未按预期恢复。

    当 我从"W25qxx_WritePage"中嵌套的"MEM_CalcFreeSpace (MEM_STORAGE)"和"void SPIFlash_ReadData (char* dat、uint16_t len"调用此函数时、我会在2种情况下看到这种情况。 一旦发生这种情况、中断 ISR 也不会执行、直到我进行复位。  

    当我通过调用 main ()[显示、外部 USB、键盘..."的更多功能使我的项目变得更大时、就会发生这种情况。 当我刚有一个包含 W25Q 存储器驱动程序和一些小功能的小项目时、也是如此。

    我还看到堆栈大小已达到100%(116字节)、我不确定这是否也是一个问题。 我尝试将默认堆栈大小增加到256字节、但我在这里仍然看到相同的内容。

    我担心生产过程中会发生这种随机的腐败案例、如果您能根据您在这里的经验为我提供合适的解决方案、这将非常有帮助。  

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

    很抱歉错过了附加项目。 我已在我的驱动器上复制了可在此处访问的完整项目。

    https://drive.google.com/file/d/1gk1Cy0cFmULcUVJQT5eiVQMrwxHeVKEF/view?usp=sharing

    再次感谢您的大力支持

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

    请记住、设置堆栈大小绝不会限制堆栈的增长。 您可以这样做、但它会在每个函数的开头添加要检查的代码。 然后、当堆栈空间用完时、您会遇到什么问题。 停止并着火?

    我从未看过、但我假设动态内存分配代码(malloc()和 Friends)会检查它是否运行在保留的堆栈空间中。 如果堆栈达到该限制、则效果会很好。

    我不会检查您的所有代码、而是查看了一些代码、我必须说我讨厌计时器 ISR。 首先、零需要设置间隔并再次启动计时器。 它仍在运行。

    然后、有各种节拍计数器和时间间隔围绕这些变化。 只需增加1ms 节拍计数器、并让关心此类事情的前台例程将其计算出来。 您在这里所做的就是浪费大量的时钟周期。  更好的是、让您的主循环调用进入低功耗模式、并让此 ISR 在每个节拍将其唤醒。

    但如果 RAM 为10K、则应具有足够的堆栈空间。 需要注意的另一个问题是通指针。 您应该能够设置观察点。 它会在修改该位置时导致断点。

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

    再次感谢您的提示。 首先、我将改进计时器 ISR、并将采纳您的所有建议。

    写入时的断点是一个很好的选择、我现在将尝试它。

    谢谢、祝你度过美好的一天!

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

    您好 Surya、

    此问题是否已解决? 还是仍需要支持?

    谢谢!

    此致

    Johnson

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

    尊敬的 Johnson:

    我希望现在是这样。 我使 ISR 更小、并且内部仅具有所需的处理功能、直到现在为止、我看不到任何问题。

    如果我看到同样的奇怪行为,更详细的调查,我肯定会回来。  

    谢谢

    Surya