ATmega128 i stringi w pamieci programu

May 06, 2004 9 Replies

Pisze sobie jak zwykle:



printf_P (PSTR ("Hejho\r\n"));



a tu nagle stringi przestają się wypisywać. :-o



Po bliższej analizie okazuje się, że przekroczyłem magiczną granicę 64KB kodu i stringi umieszczone w górnej połówce pamięci programu się nie wypisują. Problem w tym, że do funkcji printf_P przekazywany jest tylko



16-bitowy adres stringu, do tego wewnątrz zagrzebanego vfprintf kolejne literki pobierane są z pamięci programu przy pomocy makra PRG_RDB (tożsamego z pgm_read_byte_near, które nie umie sięgać powyżej 64KB).

Macie jakieś błyskotliwe rozwiązanie tego problemu? Niby normalnie stringi leżą na początku programu, za wektorami przerwań. Ale w bootloaderze wszystko jest już wysoko (od 0x1e000), a i tam chciałbym korzystać z dobrodziejstw funkcji printf_P, nie zaśmiecając przy tym pamięci danych (czyli nie zwykły printf).


U¿ytkownik "Adam Dybkowski" snipped-for-privacy@amwaw.edu.pl> napisa³ w wiadomo¶ci

Witam. Niestety nie znam C, ale z tego co mi sie wydaje nie mam mozliwosc zadresowania w Atmega128 niczego powyzej FFFFh. Jest tak poniewaz pamiec ma ogranizacje 16bit wiec ralanie masz 64k slow i adresujesz s³owo adresem

16bit. Jest tak we wszystkich AVRach.

U¿ytkownik "Marcin Kubiak" napisa³ w wiadomo¶ci

Przepraszam pomylilem sie. Przez ELPM mozna adresowac pojedyncze bajtyw pamieci programu. Nie wiem natomiast czemu kompilator C sobie z tym nie radzi.

Afair jezeli uzywa LPM to nie dostaniesz sie do drugiej polowki pamieci. Zeby dostac sie ponad 64KB, musi uzywac ELPM i bitu RAMPZ. A nie da sie go zmusic do uzywania pgm_read_byte_far. W GCC zdefiniowany w pgmspace.h ??

#ifdef RAMPZ

/** \ingroup avr_pgmspace \def pgm_read_byte_far(address_long) Read a byte from the program space with a 32-bit (far) address.

\note The address is a byte address. The address is in the program space. */

#define pgm_read_byte_far(address_long) __ELPM((unsigned long)(address_long))

/** \ingroup avr_pgmspace \def pgm_read_word_far(address_long) Read a word from the program space with a 32-bit (far) address.

\note The address is a byte address. The address is in the program space. */

#define pgm_read_word_far(address_long) __ELPM_word((unsigned long)(address_long))

We wlasnym kodzie to zaden problem. Ale zeby dzialala zwykla funkcja printf_P, to by chyba wymagalo zmian w bibliotece libc (a dokladniej w funkcji vfprintf) i przekompilowania jej. Ma ktos prostsze pomysly?

Pewnego dnia Adam Dybkowski przemówił ludzkim głosem:

Nie znam gcc, ale może dane, przed linkowaniem są umieszczane w jakimś bloku danych typu .text i może da się w jakiś sposób skłonić linkier do umieszczenia tego bloku przed granicą 32k słowa ?

W standardowym skrypcie linkera wlasnie tak jest - dane umieszczane w pamieci programu (sekcja AFAIR ".progmem") leza na poczatku pamieci, tuz za wektorami przerwan. I wszystko jest OK (jezeli nie przekroczymy 64KB tej sekcji).

Ale w bootloaderze, ktory caly musi sie zmiescic na koncu pamieci, wszystko zaczyna sie od wysokiego adresu (np. 0x1e000). Wtedy wysoko musi lezec i kod programu, i te nieszczesne stale lokowane w pamieci programu.

BTW: Obilo mi sie o oczy, ze znaczna czesc biblioteki libc-avr pisal Polak. Moze warto do niego napisac z prosba o niezbedne poprawki w funkcji vfprintf?

Sat, 08 May 2004 00:56:13 +0200, na pl.misc.elektronika, Adam Dybkowski napisał(a):

Tam juz jest taki mechanizm - vprintf wystepuje w kilku wersjach ( podstawowa - w glownej libm.a , rozszerzona dla float i minimalna dla niewielkich kostek ) . Wersje zamienna lokujemy wylaczajac vsprintf z linkowania opcja -u i dolaczajac odpowiednia dodatkowa biblioteke. Ale napisac nastepna wersje dla odwolan far juz trzeba samemu.

Pewnego dnia Adam Dybkowski przemówił ludzkim głosem:

To w końcu piszesz bootloader, który siedzi na końcu pamięci, czy "zwykły" program, który przekroczył 64kB ? Bo jeśli zwykły program, to najprostszym obejściem problemu (przynajmniej tak mi się wydaje) jest wymuszenie umieszczania stałych poniżej granicy 64KB.

Artur Lipowski, ale najprościej byłoby zadać pytanie na liście mailingowej avr-libc-dev:

formatting link

Bootloadera nie pisze sie tylko z samej radosci pisania, obok powstaje reszta programu. :) A problem ze stringami odczytywanymi z pamieci programu objawil sie u mnie wlasnie w bootloaderze.

Join the Discussion

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

Didn't find your answer?

Ask the community — no account required