jon_newcomb wrote on Tuesday, July 20, 2010:
Hi… I am trying to track a problem that is causing system instability on my SAM7S IAR port ~ once every 2 week period.
Ages ago I rewrote the PIT ISR in C, to allow the debug UART to be used… (as it shares the same interrupt as the PIT. tut tut.)
See postings above…
Previously it was…
vPortPreemptiveTick:
portSAVE_CONTEXT ; Save the context of the current task.
LDR R0, =vTaskIncrementTick ; Increment the tick count - this may wake a task.
mov lr, pc
BX R0
LDR R0, =vTaskSwitchContext ; Select the next task to execute.
mov lr, pc
BX R0
LDR R14, =AT91C_BASE_PITC ; Clear the PIT interrupt
LDR R0,
LDR R14, =AT91C_BASE_AIC ; Mark the End of Interrupt on the AIC
STR R14,
portRESTORE_CONTEXT ; Restore the context of the selected task.
END
Now it is….(with the usual ASM wrappers)
__arm void vPreemptiveTick( void );
__arm void vPreemptiveTick( void )
{
unsigned portLONG ulDummy;
if (AT91C_BASE_PITC->PITC_PISR & AT91C_PITC_PITS)
{
/* Increment the tick count - this may wake a task. */
vTaskIncrementTick();
/* Find the highest priority task that is ready to run. */
vTaskSwitchContext();
/* Clear the AT91C_PITC_PITS flag */
ulDummy = AT91C_BASE_PITC->PITC_PIVR;
}
else
{
/* Possible interrupt caused by the DBGU. AT91C_US_RXRDY and
AT91C_US_TXRDY checked & cleared within UartDbguIsr */
extern __arm void UartDbguIsr(void);
UartDbguIsr();
}
/* End the interrupt in the AIC. */
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
}
I’d appreciate a glance over it to see if anyone can spot any cracks in the code. Its was a change I consider high risk.
Also, I notice some people end the ISR differently… Which is the correct way??
portEND_SWITCHING_ISR (xTaskWokenByPost);
AT91C_BASE_AIC->AIC_EOICR = 0;
}
…or…
AT91C_BASE_AIC->AIC_EOICR = 0;
portEND_SWITCHING_ISR (xTaskWokenByPost);
}
Also, I looked at the ARM9 IAR port for ideas / differences - vPortTickISR() - its very different… there seems to be no ASM wrapper…
But, the last comment says /* The AIC is cleared in the asm wrapper, outside of this function. */
Which I found confusing…
Why is a standard C function vPortTickISR not declared as an __interrupt and written to the interrupt vector. See
AIC_ConfigureIT( AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, vPortTickISR );
Where is the following equivalent instruction in the ARM9 port at the end of the ISR
AT91C_BASE_AIC->AIC_EOICR = ulDummy;
It seems to break many of the rules on using interrupts under FreeRTOS with IAR
If anyone can enlighten me and others, I would be grateful.
Thanks.