mai napi C változó elérhetőség wtf

 ( skynetpro | 2010. június 9., szerda - 14:03 )

Ü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ás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

volatile-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).