2201694_zh-CN

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

2201694_zh-CN

2201694_zh-CN

S32K144 上的 VLPS 唤醒 ISR + FreeRTOS xTaskNotifyFromISR 问题

您好,NXP团队,

我正在使用 FreeRTOS 处理 S32K144 MCU,并实施超低功耗停止 (VLPS) 模式。我在 PORTB 上有一个 GPIO 开关,用于唤醒 MCU 并通知 FreeRTOS 任务。

设置:

  • 连接到 PORTB 的 GPIO 开关。

  • 按下开关时会触发信号 ISR。

  • 使用 xTaskNotifyFromISR 通知 FreeRTOS 任务。

  • FreeRTOS 配置:
    configPRIO_BITS = 4
    configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY = 0x01
    configMAX_SYSCALL_INTERRUPT_PRIORITY = (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY<< (8 - configPRIO_BITS))
    configKERNEL_INTERRUPT_PRIORITY = 255

ISR 和 NVIC 配置:
PORTB->ISFR = (1U<< SWITCH_PIN_NUMBER) // 清除开关引脚的中断标志
INT_SYS_SetPriority(PORTB_IRQn, SWITCH_IRQ_PRIORITY)
INT_SYS_EnableIRQ(PORTB_IRQn)

void PORTB_IRQHandler(void) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (PORTB->ISFR& (1U<< SWITCH_PIN_NUMBER)){
PORTB->ISFR = (1U<< SWITCH_PIN_NUMBER) // 清除中断标志
uint32_t switch_state = (((PINS_DRV_ReadPins(PTB)>> SWITCH_PIN_NUMBER)& 0x01) == 0) ?SWITCH_ON : SWITCH_OFF
xTaskNotifyFromISR(hmainTask, switch_state, eSetBits,&xHigherPriorityTaskWoken)
portYIELD_FROM_ISR(xHigherPriorityTaskWoken)
}
}

vPortEnterCritical()
status_t ret = POWER_SYS_SetMode(0, POWER_MANAGER_POLICY_AGREEMENT)
if (ret == STATUS_SUCCESS) wakeupOccurred = true
vPortExitCritical()

观察到的行为

  1. ISR 优先级 = 0(最高):MCU 从 VLPS 唤醒,但 xTaskNotifyFromISR 不工作。

  2. ISR 优先级 = 1:xTaskNotifyFromISR 起作用,但 MCU 无法从 VLPS 唤醒。

我的理解是

  • BASEPRI 无法屏蔽优先级为 0 的中断,因此无法安全地调用 FreeRTOS API。

  • FreeRTOS API 必须从优先级为>= configMAX_SYSCALL_INTERRUPT_PRIORITY 的 ISR 中调用。

  • VLPS 唤醒可能需要最高优先级的中断。

问题

  1. 建议在 S32K144 上使用什么模式才能可靠地从 VLPS 唤醒 MCU 并安全地通知 FreeRTOS 任务?

  2. 恩智浦是否提供了更好的方法?

如有任何指导、参考示例或最佳实践,将不胜感激。

谢谢!

致以最诚挚的问候,
Pandiyan T


Re: VLPS Wakeup ISR + FreeRTOS xTaskNotifyFromISR Issue on S32K144你好,Daniel,

在调用 POWER_SYS_SetMode() 之前禁用 SysTick 定时器后,系统现在无需使用 vPortEnterCritical()即可成功进入 VLPS。
此外,唤醒和来自 ISR 的通知机制都能按预期正常工作。

非常感谢你的指导!

致以最崇高的敬意,
Pandiyan
Re: VLPS Wakeup ISR + FreeRTOS xTaskNotifyFromISR Issue on S32K144

我还没有找到任何将 FreeRTOS 和 VLPS 结合起来的官方示例。
在我看来,唤醒问题很可能是由于 SysTick 仍在运行造成的。
尝试在调用 POWER_SYS_SetMode() 进入 VLPS 之前禁用 SysTick。

请记住

在 VLPS 中,由于内核时钟处于门控状态,因此 SysTick 定时器被禁用。
但是,如果连接了调试器,MCU 不会进入真正的 VLPS 模式,而是进入仿真的 STOP 模式。

danielmartynek_0-1762786752586.png

此外,FreeRTOS port.c已经提供了 vPortSuppressTicksAndSleep() 的弱实现。

它会在空闲时停止 SysTick。
计算下一个刻度的重载值。
执行 __WFI()。
调用两个钩子: configPRE_SLEEP_PROCESSING() configPOST_SLEEP_PROCESSING()

这是一个弱实现,可以被你自己的实现所覆盖。


此致,

丹尼尔

Re: VLPS Wakeup ISR + FreeRTOS xTaskNotifyFromISR Issue on S32K144

你好@丹尼尔-马蒂内克

感谢您的快速回复。

如果我在 POWER_SYS_SetMode()之前删除 vPortEnterCritical()调用,MCU 实际上并没有进入 VLPS 模式 - 它只是瞬间转换,然后立即唤醒。

您能否建议正确或推荐的方法,以便在运行 FreeRTOS 时正确进入 VLPS 模式?
如果可能的话,你能否分享一个示例或参考实现,演示如何从 FreeRTOS 任务上下文安全地进入 VLPS?

感谢您的支持!

致以最诚挚的问候,
Pandiyan T

Re: VLPS Wakeup ISR + FreeRTOS xTaskNotifyFromISR Issue on S32K144

你好@Panidiyan_T

如果你能分享项目,我可以在我这边进行测试。

总之,FreeRTOS 要求调用 FromISR API 的 ISR 的优先级等于或低于 configMAX_SYSCALL_INTERRUPT_PRIORITY。

不要在 POWER_SYS_SetMode() 之前调用 vPortEnterCritical()。


标记 (1)
无评分
版本历史
最后更新:
‎11-21-2025 05:26 PM
更新人: