wska?niki do flash w WinAVR

Jul 25, 2012 6 Replies

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?


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

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.

<->

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.

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

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.

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)

Join the Discussion

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

Didn't find your answer?

Ask the community — no account required