您好,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()
观察到的行为
ISR 优先级 = 0(最高):MCU 从 VLPS 唤醒,但 xTaskNotifyFromISR 不工作。
ISR 优先级 = 1:xTaskNotifyFromISR 起作用,但 MCU 无法从 VLPS 唤醒。
我的理解是
BASEPRI 无法屏蔽优先级为 0 的中断,因此无法安全地调用 FreeRTOS API。
FreeRTOS API 必须从优先级为>= configMAX_SYSCALL_INTERRUPT_PRIORITY 的 ISR 中调用。
VLPS 唤醒可能需要最高优先级的中断。
问题
建议在 S32K144 上使用什么模式才能可靠地从 VLPS 唤醒 MCU 并安全地通知 FreeRTOS 任务?
恩智浦是否提供了更好的方法?
如有任何指导、参考示例或最佳实践,将不胜感激。
谢谢!
致以最诚挚的问候,
Pandiyan T
我还没有找到任何将 FreeRTOS 和 VLPS 结合起来的官方示例。
在我看来,唤醒问题很可能是由于 SysTick 仍在运行造成的。
尝试在调用 POWER_SYS_SetMode() 进入 VLPS 之前禁用 SysTick。
请记住
在 VLPS 中,由于内核时钟处于门控状态,因此 SysTick 定时器被禁用。
但是,如果连接了调试器,MCU 不会进入真正的 VLPS 模式,而是进入仿真的 STOP 模式。
此外,FreeRTOS port.c已经提供了 vPortSuppressTicksAndSleep() 的弱实现。
它会在空闲时停止 SysTick。
计算下一个刻度的重载值。
执行 __WFI()。
调用两个钩子: configPRE_SLEEP_PROCESSING() configPOST_SLEEP_PROCESSING()
这是一个弱实现,可以被你自己的实现所覆盖。
此致,
丹尼尔
感谢您的快速回复。
如果我在 POWER_SYS_SetMode()之前删除 vPortEnterCritical()调用,MCU 实际上并没有进入 VLPS 模式 - 它只是瞬间转换,然后立即唤醒。
您能否建议正确或推荐的方法,以便在运行 FreeRTOS 时正确进入 VLPS 模式?
如果可能的话,你能否分享一个示例或参考实现,演示如何从 FreeRTOS 任务上下文安全地进入 VLPS?
感谢您的支持!
致以最诚挚的问候,
Pandiyan T
你好@Panidiyan_T、
如果你能分享项目,我可以在我这边进行测试。
总之,FreeRTOS 要求调用 FromISR API 的 ISR 的优先级等于或低于 configMAX_SYSCALL_INTERRUPT_PRIORITY。
不要在 POWER_SYS_SetMode() 之前调用 vPortEnterCritical()。