Цитата(_dem @ Dec 28 2007, 17:18)

Глубоко переделать драйвер - потерять совместивость со следующими версиями стека.
А не нужно глубоко, мне видится, что ваша проблема зарыта довольно мелко.
Пришёл к этому выводу, просматривая коды обработчиков EMAC прерывания uC-TCPIP и lwIP/FreeRTOS.
Эти фрагменты относительно приёма. Что внутри if, сейчас не так интересно
В первом примере статус прерывания просто вычитывается и далее не используется,
потом идёт разбор событий по значениям в специализированных регистрах. Авторы еррату не читали, а может этой проблемы не существует в некоторых чипах из ряда AT91SAM7X256, AT91SAM9260, AT91SAM9263, & AVR32, для коих этот драйвер написан
uC-TCPIP
Код
isr_status = MACB_ISR;
rsr_status = MACB_RSR;
if ((rsr_status & MACB_RSR_REC) == MACB_RSR_REC) {
NetNIC_RxISR_Handler();
MACB_RSR = MACB_RSR_REC;
}
А это код из примера с FreeRTOS (стек lwIP). Здесь видно, что проверяются флаги и в общем
регистре, и в специализированном
Код
/* Find the cause of the interrupt. */
ulIntStatus = AT91C_BASE_EMAC->EMAC_ISR;
ulEventStatus = AT91C_BASE_EMAC->EMAC_RSR;
if( ( ulIntStatus & AT91C_EMAC_RCOMP ) || ( ulEventStatus & AT91C_EMAC_REC ) )
{
/* A frame has been received, signal the lwIP task so it can process
the Rx descriptors. */
xSwitchRequired = xSemaphoreGiveFromISR( xSemaphore, pdFALSE );
AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
}
Во втором случае, описанная вами проблема, не возникает, а код хорошо согласуется с fix/workaround
from errata
41.3.1.1 EMAC: Possible Event Loss when Reading EMAC_ISR
If an event occurs within the same clock cycle in which the EMAC_ISR is read, the corresponding
bit might be cleared even though it has not been read at 1. This might lead to the loss of this
event.
Problem Fix/Workaround
Each time the software reads EMAC_ISR, it has to check the contents of the Transmit Status
Register (EMAC_TSR), the Receive Status Register (EMAC_RSR) and the Network Status
Register (EMAC_NSR), as the possible lost event is still notified in one of these registers.