ATmega128 i zewnętrzna pamięć

Jun 14, 2004 6 Replies

Cześć!



W programie zabrakło mi SRAM'u, toteż musiałem dołożyć atmedze pamięci. Użyłem układu U6264DC z latchem 74HC573. Pamięć wydaje się działać, jednak mam z nią dziwny problem.



Napisałem sobie w C program sprawdzający pamięć.



Najpierw alokuję dużą tablicę, potem piszę do niej określone wartości, a nastepnie sprawdzam czy są ok. Jeśli nie to wyrzucam na wyświetlacz numer "komorki" tablicy i jej zawartość (funkcją debug(...)).



Kod wygląda mniej-więcej tak:



#v+ #define TAB_LENGTH 0x7FFF #define TEST_VAL 0xAA



u8 tab[TAB_LENGTH];



int main() { u16 i; debug_init(); avr_memory_init(); for (i = 0; i < TAB_LENGTH; i++) { tab[i] = TEST_VAL; } for (i = 0; i < TAB_LENGTH; i++) { debug(1, (i >> 8) & 0xFF, i & 0xFF); if (tab[i] != TEST_VAL) { delay_ms(500); debug(1, (tab[i] >> 8) & 0xFF, tab[i] & 0xFF); delay_ms(2000); } } } #v-



Problemy są takie:



  1. Jeśli próbuję zaalokować tablicę większą niż 0x7FFF kompilator wyrzuca błąd: $ make all avr-gcc -g -mmcu=atmega128 -Wall -Os -o main.elf main.c delay.o debug.o avr_memory.o main.c:13: error: size of array `tab' is too large main.c:13: error: storage size of `tab' isn't known Pytanie... dlaczego? Przecież m128 adresuje do 64k zewnętrzej pamięci (objętość = 64k * 8 [bajtów]).


  1. Dwanaście "komórek" tablicy podczas czytania ma inną wartość niż wcześniej została do nich zapisana. Co dziwniejsze, są to zawsze te same wartości! Komórki, które sprawiają kłopoty to 0x0FF4 - 0x0FFF.



komórka | wartość



0x0FF4 0x01
0x0FF5 0x2C
0x0FF6 0x0F
0x0FF7 0xF7
0x0FF8 0x0F
0x0FF9 0xF9
0x0FFA 0x00
0x0FFB 0xBB
0x0FFC 0x0F
0x0FFD 0xFD
0x0FFE 0x00
0x0FFF 0x9C

Uwaga: "komórki" to nie są adresy w pamięci tylko indeksy kolejnych danych w tablicy tab. Niestety, słabo posługuję się asemblerem, więc patrzenie w kod asm niewiele mi pomogło. Ale wyrzuciłem go tu:

formatting link



- może zechcecie zerknąć? Może na jego podstawie ktoś życzliwie powie mi, dlaczego 12 komórek pamięci "nie działa"?



Zauważylem jeszcze coś. jak zmieniam wartość TEST_VAL, zmieniaja się również wartości komórek 0x0FF5, 0x0FFB i 0x0FFF. Reszta jest taka sama.



Pozdrawiam i czekam na rady, voice


Czyli ta pamiec to 8kB

Czyli TAB_LENGTH to 32kB - to jest jeden błąd

formatting link

A jak myslisz gdzie jest stos umieszczony ? To jest drugi blad

MK

No tak, masz rację. Zasugerowałem się objętością pamięci... 8k x 8 = 64kB

- ale to przeciez nie jest ilosc adresów.

Zgadza sie. Dzięki! Zmieniłem TAB_LENGTH na 0x2000 ale w dalszym ciągu otrzymuję te same wyniki. to pewni wina drugiedo błędu...

W wewnętrznym SRAM'ie, o ile się orientuję. Niestety, jak pisałem, z asemblerem jestem trochę na bakier i może dlatego nie rozumiem pewnych rzeczy...

Napisz mi, proszę na czym polega drugi błąd, bo sam niestety nie mogę na to wpaść. W jaki sposób mogę go rozwiązać?

Pozdrawiam, voice

Tue, 15 Jun 2004 00:57:14 +0200, na pl.misc.elektronika, voice napisał(a):

Tak on ma - tablice są ograniczone. Używaj wskaźnika do zapisu pod kolejne adresy.

Nie sprawdzaj od zera, bo włazisz na wewnętrzną pamięć kostki - zaczynaj od pierwszego adresu zewnętrznego ( = rozmiar wewnętrznej pamięci ).

Ale dlaczego? Czy po dołączeniu dodatkowego SRAM'u, nie zwiększa się po prostu przestrzeń pamięci na stos, stałe itd.?

To znaczy, mam rozumieć, że cała pamięć (wewnętrzna i zewnętrzna) nie jest "ciągła"? Czyli, jeśli zadeklaruję np. 2 tablice:

unsigned char tab1[0x0C00]; // 3/4 wewnętrznego SRAM'u (0x1000) unsigned char tab2[0x0C00];

to gdzieś w okolicy 1/4 drugiej tablicy pojawią mi się jakieś krzaki?

Jeśli tak, to co zrobić, żeby tego uniknąć?

Pozdrawiam, voice

Tue, 15 Jun 2004 12:02:10 +0200, na pl.misc.elektronika, voice napisał(a):

Zbyt ogólnikowo napisałem. Pamięć jest ciągła oczywiście. Ale gcc przy starcie ustawia wskaźnik stosu na koniec pamięci wewnętrznej (RAMEND ), natomiast obszar danych zaczyna się zaraz za rejestrami. Jeśli w takim ( domyślnym ) układzie zajmujesz dużo danych to wchodzisz na stos - kompilator przed tym nie ostrzega. Zazwyczaj przerzuca się sekcję danych na początek pamięci zewnętrznej, przesuwanie stosu jest raczej niewskazane ze względu na mniejszą szybkość dostępu. Zobacz najlepiej w manualu avr-libc - tam obszary i używanie pamięci są dokładnie rozrysowane.

Dziękuję za rozjaśneinie tematu! Manual jak zwykle okazał się nieocenioną kopalnią wiedzy :)

Zainicjowałem XMEM w sekcji .init1, a linkerowi powiedziałem, żeby wszucił sekcję .data właśnie do XMEM. Teraz wszystko działa jak trzeba (na razie).

Pozdrawiam i dziękuję za pomoc, voice

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required