-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Bug
LogMessage() claims to be ISR-safe via LogIsInISR() check (MIPS Status register EXL/ERL bits), but it fails to detect ISR context when called from the USB interrupt handler chain:
USB_Handler (ISR)
→ DRV_USBHS_InterruptHandler
→ DRV_USBHS_Tasks_ISR
→ F_USB_DEVICE_EventHandler
→ UsbCdc_EventHandler
→ LOG_D() → LogMessage() → xQueueSemaphoreTake → configASSERT failure
The MIPS EXL/ERL bits appear to get cleared deeper in the Harmony USB driver call chain, so LogIsInISR() returns false even though we're still in interrupt context. The mutex take then triggers a FreeRTOS assert in vTaskEnterCritical.
Workaround: Don't use LOG_D/LOG_I/LOG_E in USB event handlers. USB log level reverted to LOG_LEVEL_ERROR.
Proposed Fix: Deferred ISR Logging
Implement a deferred logging mechanism similar to how we already use FreeRTOS deferred interrupts (e.g., AD7609_DeferredInterruptTask, MC12bADC_EosInterruptTask):
- ISR-safe queue: Use
xQueueSendFromISR()with a small ring buffer of log entries - Deferred task: A low-priority task that drains the ISR log queue into the main log buffer (which uses the mutex)
- API: Either fix
LogIsInISR()detection, or add an explicitLOG_FROM_ISR()macro that callers in known ISR contexts can use
Option 3 (explicit macro) is simpler and avoids the unreliable MIPS status register check. The ISR macro would use xQueueSendFromISR directly, bypassing the mutex entirely.
References
- Logger ISR check:
firmware/src/Util/Logger.c:257(LogIsInISR) - USB event handler:
firmware/src/services/UsbCdc/UsbCdc.c:216(UsbCdc_EventHandler) - Existing deferred interrupt pattern:
firmware/src/HAL/ADC/AD7609.c
Priority
Low — workaround in place (no logging from USB ISR). Only needed if USB event debugging is required in the future.