Umístění řetězce do SRAM

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

Umístění řetězce do SRAM

#1 Příspěvek od mtajovsky »

Po letech na Unixu a Windows to chci zase zkusit na mikrokontrolérech. V AVR studiu s instalovaným pluginem WinAVR jsem v C zkusil následující:

#include <avr\io.h>
#include <string.h>


int main(int argc, char* arvg[])
{
char* ahoj = "ahoj";
char* ptr;

ahoj[2] = PINB;
ptr = strchr(ahoj, 'h');
PORTC = *++ptr;
}

problém je, že prográmek pracuje jinak , když není nastavena optimalizace (-O0) a jinak když je nějaká nastavena - třeba -Os.
Je-li optimalizace nastavena, kompilátor umístí řetězec ahoj do kódového segmentu a jelikož tam nelze zapisovat, tak vynechá celé řádky se čtením z portu B a s funkcí strchr() . Přitom není vydáno žádné varování, i když gcc má zapnuto -Wall .

Jak donutit kompilátor dávat řetězec do SRAM - přišel jsem na jediné:

volatile char* ahoj = "ahoj";

což se mi ovšem nepozdává, vzhledem k tomu, že volatile má primárně jiný význam. Existuje nějaký konformnější způsob?

Uživatelský avatar
Zmije
Příspěvky: 1513
Registrován: 30 čer 2005, 02:00
Bydliště: Pardubický kraj

#2 Příspěvek od Zmije »

Moc se v tajích optimalizace nevyznám, ale nepomohlo by nadeklarovat nejdříve prázdné pole(třeba samé nuly) pro řetězec a naplnit ho až během programu? Takhle si to kompilér vyhodnotí jako konstantní řetězec.

Uživatelský avatar
Zmije
Příspěvky: 1513
Registrován: 30 čer 2005, 02:00
Bydliště: Pardubický kraj

#3 Příspěvek od Zmije »

Tak jsem se informoval, volatile znamená zákaz optimalizací při práci s danou proměnou, což celou věc vysvětluje. Pokud to uděláš jak jsi napsal, bez volatile, tzn. při deklaraci tringu uložíš rovnou hodnotu a už s ní v celém programu nehýbeš, tak ji kompilér v rámci zrychlení a ušetření pamětí považuje za konstant char, ikdyž mu to nespecifikuješ, ale záměnou se nic nestane, pokud ale hodnotu alespoň jednou během programu změníš, už by záměna neplatila, použitím volatile se možností záměny ani nebude zabývat.

Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 01:00

#4 Příspěvek od AB1 »

char* ahoj = "ahoj";
Obvykle se používá deklarace
char ahoj[] = "ahoj";
která bude v tvém kódu fungovat.

Budou chodit i varianty

char* ahoj = "ahoj";
int main()

nebo

int main()
static char* ahoj = "ahoj";

V Avr-gcc funkce main() nepřijímá žádné argumenty (nemá odkud).

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#5 Příspěvek od mtajovsky »

AB1 << dik, je to OK. S tou funkcí main() je to jasné, jenže zvyk je železná košile :)

Uživatelský avatar
mtajovsky
Příspěvky: 3694
Registrován: 19 zář 2007, 02:00
Bydliště: Praha

#6 Příspěvek od mtajovsky »

Zmije píše:Moc se v tajích optimalizace nevyznám, ale nepomohlo by nadeklarovat nejdříve prázdné pole(třeba samé nuly) pro řetězec a naplnit ho až během programu? Takhle si to kompilér vyhodnotí jako konstantní řetězec.
Jasně, že by to šlo, ale elegance se vytratí. Všechny varianty od AB1 fungují, to je OK, jenom by gcc mohl dát nějaké varování, že aplikace chce zapisovat někam, kde to nejde, když už s proměnnými cvičí po segmentech,

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“