Wracając jeszcze do wskaźników w WinAVR. Powiedzmy że mam funkcję viod funkcja(byte *ptr) { char=read_pgm_byte(ptr); // np robi cos takiego }
A teraz jej wywołanie funkcja(PSTR("cos do wyświetlenia bez sensu")); lub tak funkcja(tab); z tym że prog_char tab[] PROGMEM={"inny tekst"};
Pytanie takie:
Czy byte powinno byc typu char czy prog_char?
Czy tab powinna mieć dwie deklaracje umieszczające łańcuch we Flash? czy albo używa się prog_char czy albo PROGMEM?
Skoro prog_char jest zmienną z atrybutem PROGMEM to czy należny tego używać podwójnie? TAk samo wskaźnik w funkcji powinien być zmienną to czy deklarowanie go jako zmienna będąca we flash ma sens?
Powinno być prog_char, albo właściwie const prog_char. Można używać zdefiniowanego w <avr/pgmspace.h> PGM_P, definicja wygląda tak: #define PGM_P const prog_char *.
Można tak: prog_char tab[] = {"inny tekst"}; albo tak: char PROGMEM tab[] = {"inny tekst"};
Nie.
Wskaźnik powinien wskazywać na stałą w pamięci flash, czyli coś takiego: const prog_char *ptr albo prościej PGM_P ptr
In the darkest hour on Fri, 27 Jul 2012 07:45:33 +0200, max441 snipped-for-privacy@wp.pl screamed:
Nie można ani tak ani tak. W GCC atrybuty dotyczą tylko elementu, przy którym występują. Dzięki powyższym deklaracjom umieścisz tab w program space, ale "inny tekst" nadal będzie w data space. Trzeba to zrobić dwuetapowo:
Jesteś pewien? Mam w programie, między innymi, taką kostrukcję: prog_char znak [12]={'0','1','2','3','4','5','6','7','8','9','*','#'}; Gdy zmienię deklarację na: char znak [12]={'0','1','2','3','4','5','6','7','8','9','*','#'}; to .data rośnie dokładnie o 12 bajtów... Wg tego co piszesz chyba nie powinno.
In the darkest hour on Fri, 27 Jul 2012 13:40:02 +0200, WTK snipped-for-privacy@witekh.rubikon.pl> screamed:
Rozpatrywaliśmy tablicę stringów i tego dotyczyła moja wypowiedź. Przetestuj podobny przypadek na {"0","1","2",...}.
Z tego co widzę (obecnie siedzę w ARM-ach) trochę już się zmieniło w zakresie prog_charów w avr-gcc - teraz muszę dodawać makro __PROG_TYPES_COMPAT__ (avr-gcc 4.7.1 i avr-libc 1.8.0-2).
Zrobiłem testy i widzę, że conieco się zmieniło w tej materii. Obecnie deklaracja tablicy w .text powoduje, że elementy będące stringami dołączane są do .text.
Dawniej było tak, jak piszą w:
formatting link
Sekcja: "Storing and Retrieving Strings in the Program Space".
Którą masz wersję gcc i libc? Mógłbyś sprawdzić ten przykład w swojej wersji (jeśli jest starsza)?
Nie rozumiem po co dodatkowo tworzyć jednoelementową tablicę wskaźników do program space, skoro już takim wskaźnikiem jest samo string. Czyli w przytoczonym przez kolegę przykładzie tab[0]=string i możemy skopiować tekst do zmiennej w data space na 2 sposoby:
char buffer[20]; strcpy_P(buffer, (PGM_P)pgm_read_word(&(tab[0]))); //lub zamiast &(tab[0]) w tym przypadku można użyć samo tab
lub dużo prościej bez używania tab
char buffer[20]; strcpy_P(buffer, string);
Przytoczony przez kolegę przykład ma sens jeśli chcemy zadeklarować tablicę wskaźników do kilku stringów w program space. Wtedy taka konstrukcja:
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.