Czy WinAVR radzi sobie z kodem dla ATMega128?

Z bootloaderem przygód ciąg dalszy. Na ATMega8 wszystko pięknie działa, chcę teraz zrobić podobną rzecz na ATMega128 i znowu dzieją się jakieś jaja. Bootloader jest duży, ponad

6kB, więc rezerwuję na niego największy możliwy 8kB obszar począwszy od $00F000. Dla linkera podaję adres początkowy segmentu .text jako 0x1e000, ale w pliku .hex mam :10E00000 a na dodatek pierwsza linia tego pliku wygląda tak :020000021000EC, czyli że 2 bajty zapisywane są pod adresem $000000. Po wgraniu tego pliku przy użyciu AVR Studio, nic się nie dzieje. Fuse bity ustawione prawidłowo. Jeśli adres startowy ustawię na $00000 to program działa (choć oczywiście niczego nie programuje, ale wiadomo że to nie jest jakiś zwis czy błąd w kodzie). No i teraz zupełnie nie wiem gdzie szukać błędu - w kompilatorze, linkerze, programatorze czy jeszcze gdzieś.

Dariusz Żołna

Reply to
Dariusz Zolna
Loading thread data ...

Sprawdź:

avr-objdump -h -S prg.elf >prg.lst

Powinno się sporo wyjaśnić.

Reply to
Sebastian Bialy

Sebastian Bialy pisze:

Program jest ok, zaczyna się od $1e000 i kończy na $1f762, więc jest we właściwym miejscu. Wektory przerwań (oprócz wykorzystywanego przeze mnie TWI pokazują na instrukcję skoku pod $1e000, a pod $1e000 jest skok na początek programu). Mam wrażenie, że problem leży jednak w pliku .hex, w którym brakuje jednej cyfry adresu (nie ma $1e000, jest $e000), no chyba że dla układów z flashem większym niż 64kB, pliki .hex są jakoś specjalnie obsługiwane.

Dariusz Żołna

Reply to
Dariusz Zolna

A probowałeś wygenerować plik .bin zamiast hex i załadować go?

I po drugie - czy odczyt pamięci z mikrokontrolera daje ten sam plik co zapis?

Nie wiem jak dla narzędzi avr, ale IntelHEX może być 32 bitowy i chyba taki powinien własnie tu byc.

Reply to
Sebastian Bialy

Wszystko jest OK. Wpis :020000021000EC stanowi rozszerzenie przestrzeni adresowej bo adresowanie jest 16 bitowe. Proponuję poczytać jak wygląda format IntelHEX. pozdrawiam Robert Zemła

Reply to
mojejapko

Dariusz Zolna pisze:

Tak jak poprzednio - nie wiem czy linker nie przyjmuje adresu jako slowa, a nie bajty.

Toolchain raczej bym wykluczyl, tyle osob to testowalo, ze szansa, ze nie wyszlaby do tej pory tak gruba rzecz jest zadna. Zobacz jak wygladaja wygenerowane pliki .map i .lss. Tam bedziesz mial dokladnie pokazane co jest pod jakim adresem umieszczone i jak wyglada wygenerowany kod assemblerowy. Jesli nie chcesz nam pokazac listingow programu to napisz jakis krotki programik, ktory produkuje ten sam blad. Wtedy bedzie mozna powiedziec cos wiecej.

Reply to
T.M.F.

Nie To jest extended segment address record.

Paweł

Reply to
Paweł

T.M.F. pisze:

Jako bajty. Ale ten trop też sprawdzałem, program wtedy się odpali,a le nie jako bootloader i co oczywiste nie zapisuje pamięci.

Oglądałem i wszystko jest ok.

Z pokazaniem kodu jest tylko jeden problem - jest za długi żeby tu wklejać. Ale żeby pokazać, że jest ok, wkleję co istotniejsze fragmenty.

bootloader.elf: file format elf32-avr

Sections: Idx Name Size VMA LMA File off Algn 0 .data 00000004 00800100 0001f764 000017f8 2**0 CONTENTS, ALLOC, LOAD, DATA 1 .text 00001764 0001e000 0001e000 00000094 2**1 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .bss 00000452 00800104 00800104 000017fc 2**0

[...] 0001e000 <__vectors>: 1e000: 0c 94 a4 f1 jmp 0x1e348 ; 0x1e348 <__ctors_end> 1e004: 0c 94 c4 f1 jmp 0x1e388 ; 0x1e388 <__bad_interrupt> 1e008: 0c 94 c4 f1 jmp 0x1e388 ; 0x1e388 <__bad_interrupt> [...] 0001e348 <__ctors_end>: 1e348: 11 24 eor r1, r1 1e34a: 1f be out 0x3f, r1 ; 63 [...] 1e380: 0e 94 14 f6 call 0x1ec28 ; 0x1ec28 <main> 1e384: 0c 94 b0 fb jmp 0x1f760 ; 0x1f760 <_exit> 0001e388 <__bad_interrupt>: 1e388: 0c 94 00 f0 jmp 0x1e000 ; 0x1e000 <__vectors> [...]

nt main( void ) { 1ec28: 1f 93 push r17 // u16 i;

cli(); 1ec2a: f8 94 cli TIMSK = 0; // disable timer interrupts 1ec2c: 17 be out 0x37, r1 ; 55

/* Enable change of interrupt vectors */ MCUCR = (1<<IVCE); 1ec2e: 11 e0 ldi r17, 0x01 ; 1 1ec30: 15 bf out 0x35, r17 ; 53 /* Move interrupts to boot flash section */ MCUCR = (1<<IVSEL); 1ec32: 82 e0 ldi r24, 0x02 ; 2 1ec34: 85 bf out 0x35, r24 ; 5

[...]

Pliki .hex (zapisany i odczytany) wyglądają ok. A może jest coś czym musi się różnić bootloader na ATMega128 od tego dla ATMega8?

Dariusz Żołna

Reply to
Dariusz Zolna

Dnia Sat, 24 Jan 2009 23:45:50 +0100, Dariusz Zolna napisał(a):

Nieśmiało spytam, bo nie śledziłem - M103C = 1 ?

Pozdrawiam

Reply to
Marcin Stanisz

Marcin Stanisz pisze:

Nie. Ale właśnie się wyjaśniło. Kompilator nie ostrzega, że pgm_read_byte() działa tylko z krótkimi adresami, bootloader siedzi powyżej 64k, a ja wszystkie dane typu teksty/grafika trzymam we flash, no i jak tylko program dochodził do miejsca, w którym powinien wyświetlić testowy napis, procek się resetował. No i jak zwykle nie tam gdzie szukałem :)

Dariusz Żołna

Reply to
Dariusz Zolna

Dariusz Zolna pisze:

No to pozostaje korzystać z pgm_read_byte_far() i podobnych. Uważaj też na funkcje typu strcpy_P, printf_P, memcpy_P itd - nie zadziałają bo trzeba im podać wskaźniki 16- a nie 32-bitowe. Podobnie bez dodatkowego "obejścia" nie zadziałają wskaźniki na funkcje, używane np. w tablicach skoków. Ot taka "zaleta" dużej pamięci w procku bądź co bądź

8/16-bitowym. Przerabiałem to ostatnio w zdwojonej formie walcząc z jeszcze większym ATmega2561.
Reply to
Adam Dybkowski

Adam Dybkowski pisze:

Tak, już napisałem swoje wersje tych wszystkich funkcji (przynajmniej tych, które używam). Szkoda tylko, że kompilator nie przypomina o tym. A właśnie, jak zrobić wskaźniki do funkcji w tablicach? Wprawdzie teraz nie korzystam z tego, ale może się przydać na przyszłość. Dla wskaźników w parametrach funkcji mam zrobione makro (choć też troche upierdliwe w użyciu, bo stringi muszę teraz mieć ponazywane, a nie umieszczone jako PSTR("...") bezpośrednio w wywołaniu funkcji).

Dariusz Żołna

Reply to
Dariusz Zolna

Co do wskaznikow na funkcje to nie wydaje mi sie, zeby w ATMega128 byl z tym problem. CALL wykorzystuje adres slowa, czyli w 16 bitach moze skakac po calym 128 kB obszarze. Problem zaczyna sie w ATMega256. Wewnetrzne tabele skokow generowane przez gcc odbywaja sie poprzez ICALL i rejestr Z, czyli tez maja mozliwosc skoku po calych 128kB. Niestety w gcc nie ma zaimplementowanych modeli pamieci, implementacja

24-bitowych wskaznikow ze wzgledu na strukture gcc tez jest trudna, a 32-bitowe to marnotrawstwo. Ale widze, ze powoli jednak rozwoj avr-gcc idzie w kierunku modeli pamieci i bedziemy mieli cos znane z czasow Borlanda i 80286.
Reply to
T.M.F.

Dariusz Zolna pisze:

Nie ma jak. Zobacz jak wyglada definicja tych funkcji. Jedyna mozliwosc to wywalanie ostrzezenia przez sama biblioteke przy wywolywaniu ich na procesorach z >64kB FLASH. Co zreszta ma maly sens, bo gcc domyslnie umieszcza stale na poczatku programu, czyli dopoki one nie przekrocza

64kB korzystanie z wersji near tych funkcji jest zupelnie ok. Z kolei wersje far sa bezpieczne (chociaz nie wiem czy dzialaja na procesorach do 64kB FLASH), ale czasochlonniejsze i FLASHochlonniejsze. Natomiast jesli korzystales z wersji near, a wskaznik miales zadeklarowany prawidlowo jako 32-bitowy to kompilator musial wywalic ostrzezenie (chyba, ze je blokujesz). Tak czy siak, winny byles ty :)

Np. tak: const FuncPtr FuncPtrTable[] PROGMEM= {f1, f2, f3};

I wywolanie: FPtr=(FuncPtr)pgm_read_word(&FuncPtrTable[funcno]);

*FPtr();

BTW. A propos twojego bootloadera. Piszesz, ze jest strasznie dlugi. Wiesz, ze w tej sekcji musi byc tylko maly fragment wykonujacy SPM, raptem pare bajtow, cala reszta moze byc w normalnej pamieci, co ogranicza rozmiar bootloadera.

Reply to
T.M.F.

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.