Hexart 0 23 октября, 2011 Опубликовано 23 октября, 2011 · Жалоба Привет всем. Разбираюсь с UART и прерываниями. Разбираю код из примера Keil UART с обработкой прерывания. Никак не могу понять зачем там while. В других примерах нету в обработчике while. Если произошло прерывание по UART1 какое либо. Там в регистре U1IIR - есть три бита (3:1) IntId: Iterrupt identification. Но может быть записан идентификатор только одного прерывания, который выбирается в switch. После считывания значений в case'ax, нулевой бит в U1IIR, в котором записан "0", свидетельствующий о прерывании устанавливается в "1". Если во время обработки прерывания, пришло еще одно прерывание, опять по UART1, то в регистр U1IIR опять запишется значение о новом прерывании еще до выхода из обработчика? void sio_irq (void) __irq { volatile char dummy; volatile char IIR; struct buf_st *p; /*------------------------------------------------ Repeat while there is at least one interrupt source. ------------------------------------------------*/ while (((IIR = U1IIR) & 0x01) == 0) { switch (IIR & 0x0E) { case 0x06: /* Receive Line Status */ dummy = U1LSR; /* Just clear the interrupt source */ break; case 0x04: /* Receive Data Available */ case 0x0C: /* Character Time-Out */ p = &rbuf; if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) { p->buf [p->in & (RBUF_SIZE-1)] = U1RBR; p->in++; } break; case 0x02: /* THRE Interrupt */ p = &tbuf; if (p->in != p->out) { U1THR = p->buf [p->out & (TBUF_SIZE-1)]; p->out++; tx_restart = 0; } else { tx_restart = 1; } break; case 0x00: /* Modem Interrupt */ dummy = U1MSR; /* Just clear the interrupt source */ break; default: break; } } VICVectAddr = 0; /* Acknowledge Interrupt */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 23 октября, 2011 Опубликовано 23 октября, 2011 · Жалоба Если во время обработки прерывания, пришло еще одно прерывание, опять по UART1, то в регистр U1IIR опять запишется значение о новом прерывании еще до выхода из обработчика?А вы думали, UART будет ждать пока ядро выйдет из прервывания, чтобы записать значение в свои регистры? А если вы работаете без прерываний? А если второе событие произошло еще до того, как вы вошли в это прерывание? Там ведь не зря у разных источников разные приоритеты. В этом примере сделано довольно грамотно - зачем тратить время на выход из прерывания чтобы тут же попасть в него снова? Проще сразу проверить, что больше обрабатывать нечего. То, что в этом примере не используются FIFO - уже другой вопрос. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hexart 0 23 октября, 2011 Опубликовано 23 октября, 2011 · Жалоба А вы думали, UART будет ждать пока ядро выйдет из прервывания, чтобы записать значение в свои регистры? А если вы работаете без прерываний? А если второе событие произошло еще до того, как вы вошли в это прерывание? Там ведь не зря у разных источников разные приоритеты. В этом примере сделано довольно грамотно - зачем тратить время на выход из прерывания чтобы тут же попасть в него снова? Проще сразу проверить, что больше обрабатывать нечего. То, что в этом примере не используются FIFO - уже другой вопрос. Спасибо! понятно. Получается без while тоже можно, но тогда он потом туда вернется, если у него еще есть прерывания от других источников в этот момент. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться