AVR + GCC + EEPROM = problem...

Witam,

Mam zaadeklarowana w programie zmienna: uint16_t ee_delay_period __attribute__ ((section(".eeprom"))) = 0x3000;

Potem mam taka linijke: _delay_loop_2( eeprom_read_word( adres_ale_jak ) );

Jak podac argument dla ``eeprom_read_word'' prawidlowo, aby wskazywal na ``ee_delay_period'' dokladnie tak, jak zostala ona wlozona przez linker (czy inne ustrojstwo). Raczej zakladam, ze nie wiadomo w momencie kompilacji, jaki jest jej adres, bo mogly pojawic sie inne zmienne wczesniej, albo cos zostalo zoptymalizowane... A moze jest sposob, aby z eepromu wartosc zostala zmirorrowana w ramie podczas inicjalizacji. Zaznaczam, ze chodzi mi o ktorys blok wykonany przed ``main()'', a wsadzany przez kompiulator automatycznie (jesli cos takiego istnieje).

TIA

Reply to
Roland
Loading thread data ...

Deklaracja powinna wygl±daæ tak: const uint16_t ee_delay_period __attribute__ ((section(".eeprom"))) = 0x3000;

a u¿ycie jak tak jak ka¿dej innej zmiennej w C:

_delay_loop_2( eeprom_read_word( &ee_delay_period ) );

Po to siê u¿ywa C, ¿eby takimi "duperelami" jak adresy bezwzglêde nie zaprz±taæ sobie g³oowy.

Pozdrawiam,

--
Artur Lipowski
Reply to
Artur Lipowski

No wlasnie o to chodzi, ze tak nie pojdzie... Ponizej zamieszczam fragment kodu w C i to co wygenerowal GCC. Zaznaczylem miejsce wywolania ``eeprom_read_word'' i przekazany parametr nijak ma sie do adresu 0x10 (taki specjalnie zadeklarowalem, zeby byl nadany dla tej zmiennej w EEPROM-ie).

/* * EEPROM Locations */

uint16_t ee_delay_period __attribute__ ((section(".eeprom=0x10"))) = 0x3000;

/* . . . */

void main( void ) { uint8_t value = 1; direction_t direction = UP;

while( 1 ) { _delay_loop_2( eeprom_read_word( &ee_delay_period ) );

/* . . . */

00000058 : 58: cf ed ldi r28, 0xDF ; 223 5a: d0 e0 ldi r29, 0x00 ; 0 5c: de bf out 0x3e, r29 ; 62 5e: cd bf out 0x3d, r28 ; 61 60: c1 e0 ldi r28, 0x01 ; 1 62: ff 24 eor r15, r15

; TUTAJ JEST WYWOLANIE FUNKCJI ``eeprom_read_word''

64: 80 e0 ldi r24, 0x00 ; 0

; POWINNO BYC ; 64: 80 e0 ldi r24, 0x10 ; 16

66: 90 e0 ldi r25, 0x00 ; 0 68: 18 d0 rcall .+48 ; 0x9a

; . . .

0000009a :

; . . .

b2: 08 95 ret

Pozdrawiam

Roland

Reply to
Roland

... A gdzie i jak to zadeklarowa³e¶?

BTW> A po co deklarowa³e¶ konkretny adres w EEPROM-ie? Tak na szybko to trudno mi znale¼æ zastosowanie dla takiego czego¶.

Pozdrawiam,

--
Artur Lipowski
Reply to
Artur Lipowski

No ale jak zadeklarowa³e¶ aby ta zmienna by³a pod adresem 0x10? Podziel sie wiedz± >:->

Widzê, ¿e chyba mylisz warto¶æ w EEPROM-ie z adresem w EEPROM-ie. Deklaracja w Twoim programie mówi o pocz±tkowej warto¶ci zmiennej, anie o jej adresie - wszystko zgodnie ze standardem jêzyka C.

Mo¿e nie zauwa¿y³e¶, ale kompilator prawid³owo wygenerowa³ kod, bo Twoja zmienna jest pod adresem 0 i taki adres przekaza³ do funkcji eeprom_read_word.

BTW> staraj siê nie umieszczac danych w EEPROM-ie AVR-a pod adresem 0.

Pozdrawiam,

--
Artur Lipowski
Reply to
Artur Lipowski

tez

Zamieszczam caly kod: Zwroc uwage, ze zapis ".eeprom=0x10" lokuje pod zadanym adresem 0x10

#include #include #include #include #include #include

/* * EEPROM Locations */

/*** zapis ".eeprom=0x10" lokuje pod zadanum adresem 0x10 ***/

uint16_t ee_delay_period __attribute__ ((section(".eeprom=0x10"))) = 0x3000;

/* * Types */

typedef enum { UP, DOWN } direction_t ;

/* * Function prototypes */

void main( void );

void init_system( void ) __attribute__ ((naked)) \ __attribute__ ((section(".init8")));

void main( void ) { uint8_t value = 1; direction_t direction = UP;

while( 1 ) { _delay_loop_2( eeprom_read_word( &ee_delay_period ) ); outb( OCR1AL, value ); switch( direction ) { case UP : if( ++value == 0xFF ) direction = DOWN; break;

case DOWN : if( !--value ) direction = UP; break;

default : break; } /* switch( ... ) */ } /* while( 1 ) ... */ } /* main( void ) */

void init_system( void ) { /* Timer #1 PWM Mode Setup */ outb( TCCR1A, (1 > testach zawsze jest podejrzane, bo ciezko jest stwierdzic co tak na prawde

Mysle, ze jednak dobrze rozumuje... Zwlaszcza jak popatrzysz na asma, to jest to logiczne. Do rejestrow r25:r24 lokuje sie adres komorki EEPROM, ktora chce sie odczytac i wywoluje procedure odczytu. Przytocze ja rowniez, aby bylo jasniej. To jest oczywiscie kod wygenerowany przez kompilator!

0000009a : 9a: e1 99 sbic 0x1c, 1 ; 28 9c: fe cf rjmp .-4 ; 0x9a 9e: 9f bb out 0x1f, r25 ; 31 a0: 8e bb out 0x1e, r24 ; 30 a2: e0 9a sbi 0x1c, 0 ; 28 a4: 01 96 adiw r24, 0x01 ; 1 a6: 0d b2 in r0, 0x1d ; 29 a8: 9f bb out 0x1f, r25 ; 31 aa: 8e bb out 0x1e, r24 ; 30 ac: e0 9a sbi 0x1c, 0 ; 28 ae: 80 2d mov r24, r0 b0: 9d b3 in r25, 0x1d ; 29 b2: 08 95 ret

Wlasnie, ze jest pod adresem 0x10. Chyba, ze jestem slepy... Wtedy prosze mi wybaczyc ;-) Przytaczam kod do EEPROM-a:

:020000000030CE :00000001FF

Moze jednak sie myle???

No niby tak, ale oni to dawno powinni fixnac.

Rowniez

Roland

Reply to
Roland

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.