Спасибо. Значит, точно в порте дело. Пошёл смотреть csrw 0x504.
В оригинальном коде от WCH:
#define portYIELD() NVIC_SetPendingIRQ(Software_IRQn)
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portYIELD(); } while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portSET_INTERRUPT_MASK_FROM_ISR() xPortSetInterruptMask()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) vPortClearInterruptMask(uxSavedStatusValue)
#define portDISABLE_INTERRUPTS() __asm volatile( "csrw mstatus,%0" ::"r"(0x7800) )
#define portENABLE_INTERRUPTS() __asm volatile( "csrw mstatus,%0" ::"r"(0x7888) )
#define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical()
#define GET_INT_SP() __asm volatile("csrrw sp,mscratch,sp")
#define FREE_INT_SP() __asm volatile("csrrw sp,mscratch,sp")
У меня:
#define portYIELD() NVIC_SetPendingIRQ(Software_IRQn)
#define portEND_SWITCHING_ISR( xSwitchRequired ) do { if( xSwitchRequired ) portYIELD(); } while( 0 )
#define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
#define portDISABLE_INTERRUPTS() do{ __asm volatile ( "csrw mstatus,%0" ::"r"(0x7800) ); __asm volatile( "fence.i" ); }while(0)
#define portENABLE_INTERRUPTS() __asm volatile ( "csrw mstatus,%0" ::"r"(0x7888) )
#define GET_INT_SP() __asm volatile("csrrw sp,mscratch,sp")
#define FREE_INT_SP() __asm volatile("csrrw sp,mscratch,sp")
Как в свежем core.h, где они в отключение прерываний, добавили fence.i (но и без fence.i оно не работает должным образом).