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.

[参考译文] MSP432P401R:如果在 GoToSleep 函数期间发生 IRQ、如何防止 IRQ 期间的睡眠?

Guru**** 2589300 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/625925/msp432p401r-how-to-prevent-sleep-during-irq-if-irq-happened-during-gotosleepfunction

器件型号:MSP432P401R

标题说明了一切。 基本上、我们有一个非常复杂的系统、需要在可能的情况下随时进入睡眠状态。

我制定了一种机制来调节这种情况、但我无法防止的唯一事件是下一个事件:

我调用函数 PCM_gotoLPM0、在该函数期间会发生 IRQ。
在 IRQ 中、我需要告诉 MCU、它必须在 main 中执行一些操作。
IRQ 结束、但这意味着器件完成 PCM_gotoLPM0函数 并进入睡眠模式。

有什么可以防止这种情况的呢?

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

    为了在退出 ISR 后使主代码能够正常工作、请确保在器件和代码/的外设初始化期间使用以下函数调用禁用 ISR 退出时的睡眠

    MAP_Interrupt_disableSlepOnIsrExit();
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的问题不是在和 ISR 期间退出睡眠、而是在 ISR 进入睡眠期间发生 ISR 时阻止睡眠。

    MAP_Interrupt_disableSlepOnIsrExit()是否可以防止此问题? 您的答案是一个简单的含糊之处。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您似乎在描述唤醒竞态:中断在您执行 WFI 之前改变全局状态。

    标准 Cortex-M 方法是(a)禁用中断(b)检查工作(c) WFI (d)启用中断。 如果 NVIC 中断挂起、WFI 将不会休眠、但禁用 CPU 中断后、不会调用 ISR (直到您重新启用)。 为了获得最佳结果、请将其置于循环中。

    我似乎找不到 gotoLPM0的来源、因此我不知道它的作用是多少。

    一种懒惰的替代方法是依靠一些其他周期性(例如1ms 计时器)中断来唤醒您。 这具有更高的(虽然有界)延迟、但不需要特别的软件注意事项。

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

    我的问题似乎已经解决了,因为你的解释而得到了解决。 睡眠有两个功能。 第一个是 PCM_gotoLPM0 (),第二个是 PCM_gotoLPM0InterruptSafe ()。
    我知道第二个职能的存在,但我理解它是另一种工作方式。  

    我阅读了描述并理解 InterruptSafe 函数只能防止中断被错过、但仍然会进入 LPM。 现在您给了我这个解释、我找到了 InterruptSafe 函数的源代码、如下所示:

    bool PCM_gotoLPM0InterruptSafe (void)
    {
    bool slHappenedCorrect;
    
    /*禁用主中断。 在 Cortex M 中、如果中断被启用、则为
    主机中断被禁用、WFI 将会发生一个 WFI
    立即退出。 *
    interrupt_disableMaster();
    
    "改正"附录= PCM_gotoLPM0();
    
    /*非常快速地启用和禁用中断,以便
    处理器捕获任何挂起的中断*/
    interrupt_enableMaster();
    interrupt_disableMaster();
    
    返回"改正"附录;
    }
    

    我只是不明白 为什么它会在最后再次禁用主中断