Плата с 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;
}