Fórumok
Üdv! GCC/libavr-rel fejlesztek egy Atmega88-ra. A helyzet a következő:
Adott egy, függvényen kívül definiált változó (struktúra) az rxbuf. Van egy megszakításkezelő függvény, ami ebbe a struktúrába pakol, ok. Debug okokból visszalövi nekem UART-on az rxbuf méretét, stimmel.
Adott a main függvény fő while loopja. Ugyanígy kitolja UART-ra az rxbuf méretét, ami mindig nulla. WTF.
A kérdéses kódrészletek:
ez a program tetején van, mindenen kívül, tehát globális, ha jól tévedek.
#define BUFFER_SIZE 20
struct buffer {
uint8_t data[BUFFER_SIZE];
uint8_t rpos;
uint8_t wpos;
} rxbuf;
interrupt kezelő
/* // USART RX interrupt */
ISR(USART_RX_vect) {
#ifdef DLED
DLEDPORT ^= _BV(DLED);
#endif
buf_push(&rxbuf, UDR0);
TransmitByte(' ');
TransmitByte(48+buf_size(&rxbuf));
TransmitByte(' ');
}
a ringbuffer kezelő függvény (buf_push) és a méret kezelő fv (buf_size)
void buf_push(struct buffer *buf, const uint8_t data) {
buf->data[buf->wpos++] = data;
if (BUFFER_SIZE <= buf->wpos) {
buf->wpos = 0;
}
}
uint8_t buf_size(struct buffer *buf) {
if (buf->wpos >= buf->rpos) {
return (buf->wpos - buf->rpos);
} else {
return (BUFFER_SIZE - buf->rpos + buf->wpos);
}
}
a main fv. (részlet)
int main() {
/* (...) */
sei();
#ifdef DEBUG
initUART();
#endif
/* (...) */
while(1) {
#ifdef DEBUG
TransmitByte(48+buf_size(&rxbuf));
/* (...) */
#endif
}
}
segítsetek, ha tudtok, köszi!
Hozzászólások
-kent deklaralni azokat a valtozokat, amiket az interrupt handler modosit?
köszi, ez jól jött :)
szerk: az előttem hozzászólónak igaza lehet...
Bár, én azért megnézném, hogy mi van, ha a mainloop-ban a TransmitByte(...) lé teszel egy buf_push(...) -t.
Ha a buf_push/size/stb fuggvenyeket interrupt -bol es interrupt -on kivulrol is hivod, nem artana egy interrupt elleni vedelem belejuk. A mostani problemadra ez nem megoldas, de a kesobbikre igen ;)
Ha a kulonbozo kontextusokbol csak az egyik oldalt hasznalod (interrupt csak push, nem interrupt csak pop) akkor csak a buf_size() lehet problemas. Pl, ha az if kiertekelese utan becsap egy interrupt es wpos erteke megvaltozik erdekes eredmenyeket kaphatsz.
Amugy ha a BUFFER_SIZE ketto hatvanya (pl 1u<<5) buf_size() kinezhetne igy:
return ((buf->wpos - buf->rpos)&(BUFFER_SIZE-1));
ha BUFFER_SIZE 0x100 akkor az & -t a hardware megcsinalja neked (tulcsordulas).