Прерывания от порта PIO становятся в очередь, если прерывание возникло во время работы обработчика?
Обработчик:
CODE
__ramfunc void irq_Receive()
{
volatile unsigned int dummy;
volatile unsigned int source; //источник прерывания
source = regs->PIOA_PDSR&0x780; //Накладываем маску прерывания
switch(source)
{
case 0x200 : {PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG;
recA = recA>>1; i_shA++; recA = recA|0x80000000; break;} //A1
case 0x400 : {PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG;
recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF; break;} //B1
case 0x80 : {PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG;
recB = recB>>1; i_shB++; recB = recB|0x80000000; break;} //A2
case 0x100 : {PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG;
recB = recB>>1; i_shB++; recB = recB&0x7FFFFFFF; break;} //B2
case 0x280 : {PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG;
recA = recA>>1; i_shA++; recA = recA|0x80000000; PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG; recB = recB>>1; i_shB++; recB = recB|0x80000000;
break;} //A1,A2
case 0x500 : {PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG;
recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF; PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG; recB = recB>>1; i_shB++; recB = recB&0x7FFFFFFF;
break;} //B1,B2
case 0x300 : {PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG;
recA = recA>>1; i_shA++; recA = recA|0x80000000; PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG; recB = recB>>1; i_shB++; recB = recB&0x7FFFFFFF;
break;} //A1,B2
case 0x480 : {PauseTimerBase2->TC_CCR = AT91C_TC_CLKEN; PauseTimerBase2->TC_CCR = AT91C_TC_SWTRG;
recB = recB>>1; i_shB++; recB = recB|0x80000000; PauseTimerBase1->TC_CCR = AT91C_TC_CLKEN;
PauseTimerBase1->TC_CCR = AT91C_TC_SWTRG; recA = recA>>1; i_shA++; recA = recA&0x7FFFFFFF;
break;} //A2,B1
default: {;}
}
dummy = AT91C_BASE_PIOA->PIO_ISR;
}
При изменении уровней порта PIO в соответствии с маской 0x780, возникает прерывание, которое обрабатывается обработчиком irq_Receive(). В зависимости от содержимого источника прерываний source в буфера recA и recB записывается 1 или 0 и происходит их сдвиг, а также запускаются таймеры 1 или 2, которые контролируют паузу между принимаемыми битами. То есть этот обработчик принимает данные от двух каналов. Когда данные поступают на порт PIO от 2-х каналов не одновременно, то возникают сбои при приеме данных и прнимаются не те данные. То есть, возможна ситуация, когда обработчик считывает данные в буфер канала А recA, а в этот момент приходит очередной импульс на порт PIO от канала B, но прерывание занято, следовательно, бит данных пропадает. Такое может быть или же сучествует очередь для одинаковых прерываний?
Причина редактирования: Уменьшение видимого размера цитаты исходника.