wska?niki do flash w WinAVR

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:

  1. Czy byte powinno byc typu char czy prog_char?
  2. 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?

Reply to
slawek7
Loading thread data ...

W dniu 2012-07-25 08:15, slawek7 pisze:

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

Reply to
max441

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:

char string[] PROGMEM = "inny tekst"; PGM_P tab[] PROGMEM = { string };

Odczyt, kopiowanie itp. takich ciągów to już inne zagadnienie.

Reply to
Artur M. Piwko
<->

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.

Pozdrawiam.

Reply to
WTK

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)?

Reply to
Artur M. Piwko

W dniu 2012-07-27 11:18, Artur M. Piwko pisze:

Bardzo ciekawe, a niby dlaczego przytoczone przeze mnie przykłady mają umieszczać "inny tekst" w data space a przytoczone przez kolegę:

char string[] PROGMEM = "inny tekst";

już nie, skoro to jest dokładnie to samo co moje:

prog_char tab[] = {"inny tekst"}; lub char PROGMEM tab[] = {"inny tekst"};

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:

char *string_table[] PROGMEM = { "String 1", "String 2", "String 3", "String 4", "String 5" };

faktycznie umieści "String 1", "String 2" itd. w data space i w tym przypadku trzeba zrobić to dwuetapowo:

char string_1[] PROGMEM = "String 1"; char string_2[] PROGMEM = "String 2"; char string_3[] PROGMEM = "String 3"; char string_4[] PROGMEM = "String 4"; char string_5[] PROGMEM = "String 5";

PGM_P string_table[] PROGMEM = { string_1, string_2, string_3, string_4, string_5 };

Jednak pytanie w wątku dotyczyło umieszczania jednego stringa w program space.

Reply to
max441

In the darkest hour on Mon, 30 Jul 2012 10:45:44 +0200, max441 snipped-for-privacy@wp.pl screamed:

Może wróć do artykułu inicjującego wątek i sprawdź kto pierwszy i gdzie użył konstrukcji {"foo"}, do której się odnosiłem.

(ciach oczywistości)

Reply to
Artur M. Piwko

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.