NXPチームの皆様、こんにちは。
私は FreeRTOS を使用して S32K144 MCU を操作し、Very Low Power Stop (VLPS) モードを実装しています。MCU を起動して FreeRTOS タスクに通知することを目的とした GPIO スイッチが PORTB にあります。
設定:
GPIO スイッチが PORTB にコネクテッド。
スイッチが押されると 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 << スイッチピン番号)) {
PORTB->ISFR = (1U << SWITCH_PIN_NUMBER) // 割り込みフラグをクリア
uint32_t switch_state = (((PINS_DRV_ReadPins(PTB) >> SWITCH_PIN_NUMBER) & 0x01) == 0) ?スイッチオン: スイッチオフ
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 から起動しません。
私の理解では:
優先度 0 の割り込みは BASEPRI によってマスクできないため、FreeRTOS API を安全に呼び出すことはできません。
FreeRTOS API は、優先度 >= configMAX_SYSCALL_INTERRUPT_PRIORITY の ISR から呼び出す必要があります。
VLPS ウェイクアップには、最高優先度の割り込みが必要になる場合があります。
質問:
MCU を VLPS から確実に起動し、FreeRTOS タスクに安全に通知するために、S32K144 で推奨されるパターンは何ですか?
NXP が提供するより良いアプローチはありますか?
あらゆるガイダンス、参考例、ベストプラクティスをいただければ幸いです。
ご回答をお待ちしています。
よろしくお願いします、
パンディヤンT
FreeRTOS と VLPS を組み合わせた公式の例はまだ見つかりませんでした。
私の見るところ、ウェイクアップの問題は SysTick がまだ実行されていることが原因である可能性があります。
VLPS に入るには、POWER_SYS_SetMode() を呼び出す直前に SysTick を無効にしてみてください。
留意点:
VLPS では、コア クロックがゲートされているため、SysTick タイマーは無効になります。
ただし、デバッガーがコネクテッドされている場合、MCU は真の VLPS にはならず、エミュレートされた STOP モードになります。
さらに、FreeRTOS port.cすでに vPortSuppressTicksAndSleep() の弱い実装を提供しています。
アイドル時に SysTick を停止します。
次のティックのリロード値を計算します。
__WFI() を実行します。
2つのフックを呼び出します: configPRE_SLEEP_PROCESSING() configPOST_SLEEP_PROCESSING()
これは弱い実装であり、独自の実装によって上書きされるCANがあります。
よろしくお願いいたします。
ダニエル
こんにちは@danielmartynek
迅速なご対応ありがとうございます。
POWER_SYS_SetMode() の前に vPortEnterCritical() 呼び出しを削除すると、MCU は実際には VLPS モードに入らず、一時的に遷移してからすぐに起動します。
FreeRTOS の実行中に適切に VLPS モードに入るための正しいまたは推奨される方法を提案していただけますか?
可能であれば、FreeRTOS タスクコンテキストから VLPS に安全に入る方法を示す例またはリファレンス実装も共有していただけますか?
サポートありがとうございます!
よろしくお願いします、
パンディヤンT
こんにちは@Panidiyan_Tさん、
プロジェクトを共有していただければ、私の側でテストすることができます。
とにかく、FreeRTOS では、FromISR API を呼び出す ISR の優先度が configMAX_SYSCALL_INTERRUPT_PRIORITY 以下である必要があります。
POWER_SYS_SetMode() の前に vPortEnterCritical() を呼び出さないでください。