Спасибо. Значит, точно в порте дело. Пошёл смотреть 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 оно не работает должным образом).