Плата с lpc2388 под управленим freeRTOS. Получаю сообщение по CAN1 - вваливаюсь в обработчик прерывания. Если дальше выполнять пошагово в дебаггере (jtag) то всё хорошо работает, но если запустить (RUN), то раз в ~10 сообщений вываливается в Pabt. Причём вываливается после выхода из обработчика прерывания. В R14(LR) при этом чаще всего 0x286e9b12. Поскольку прерывание может пробуждать другие task'и, то оформлял как оформлено прерывание от UART след. образом:
vCAN_ISREntry
portSAVE_CONTEXT ; Save the context of the current task.
LDR R0, =vCAN_ISR ; Call the ISR routine. MOV LR, PC BX R0
portRESTORE_CONTEXT ; Restore the context of the current task - ; which may be different to the task that ; was interrupted.
Далее текст главной функции прерывания:
void vCAN_ISR(void) //__irq { portBASE_TYPE xHigherPriorityTaskWoken; CANStatus = CAN_RX_SR; if ( CANStatus & (1 << 8) ) { CAN1RxCount++; xHigherPriorityTaskWoken = CAN_ISR_Rx1(); } if ( CAN1GSR & (1 << 6 ) ) { /* The error count includes both TX and RX */ CAN1ErrCount = (CAN1GSR >> 16 ); } VICVectAddr = 0; /* Acknowledge Interrupt */ /* Actual macro used here is port specific. */ portEXIT_SWITCHING_ISR(xHigherPriorityTaskWoken); }
И подпрограмма обработки приёма по CAN
portBASE_TYPE CAN_ISR_Rx1( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; xCANMsg * pMsg = ( xCANMsg * ) pvPortMalloc( sizeof( xCANMsg ) ); if(pMsg == 0){ vSerialPutString( NULL, "No memory avalible", 25); xSerialPutChar( NULL, CR, comNO_BLOCK); while(1){}; } pMsg->Frame = CAN1RFS; pMsg->MsgID = CAN1RID; // ID //change by gongjun pMsg->DataA = CAN1RDA; // Data A pMsg->DataB = CAN1RDB; // Data B xQueueSendToBackFromISR( receiveCANQueue, ( void * ) &pMsg, &xHigherPriorityTaskWoken); CAN1RxDone = TRUE; CAN1CMR = 0x04; // release receive buffer return xHigherPriorityTaskWoken; }
|