Код
void vI2C_ISR_Wrapper( void )
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Call the handler. This must be a separate function from the wrapper
to ensure the correct stack frame is set up. */
vI2C_ISR_Handler();
/* Restore the context of whichever task is going to run next. */
portRESTORE_CONTEXT();
}
{
/* Save the context of the interrupted task. */
portSAVE_CONTEXT();
/* Call the handler. This must be a separate function from the wrapper
to ensure the correct stack frame is set up. */
vI2C_ISR_Handler();
/* Restore the context of whichever task is going to run next. */
portRESTORE_CONTEXT();
}
без оси так:
Код
void vI2C_ISR_Handler( void )
{
asm("STMDB SP!,{R0-R12,LR}"); // пролог для IRQ
...
VICVectAddr = 0; /* Acknowledge Interrupt */
asm( "LDMIA SP!,{R0-R12,LR} \n" // эпиолог для IRQ
"SUBS PC,LR,#4 ");
}
{
asm("STMDB SP!,{R0-R12,LR}"); // пролог для IRQ
...
VICVectAddr = 0; /* Acknowledge Interrupt */
asm( "LDMIA SP!,{R0-R12,LR} \n" // эпиолог для IRQ
"SUBS PC,LR,#4 ");
}
Прерывания в обоих случаях внутри обработчиков запрещены. Начинка прерывания была взята из примеров с сайта NXP, хотя немного переделана. Параллельно с работой I2C прерывания работает FIQ с частотой 8 КГц. FIQ работает стабильно под осью и без оси, и на глюки в обоих вариантах (с осью/без) не влияет.
Вопрос: куда копать? Может кто описать особенности "написания программы" под FreeRTOS ? В том смысле, что вот этого например делать нельзя, или на вот это нужно обратить особое внимание, или ещё что-нить. Проект большой, так что выложить бОльшие куски кода пока не могу.