pole 64B na tiny s 128B SRAM

Zdarec,
nevíte někdo, proč nedokáže GCC na Tiny2313 (128B SRAM, na jiném mcu nezkoušeno) vytvořit a inicializovat pole unsigned char v delce 64 prvků?
Případné “volatile” nemá vliv.
Pole je lokální ve funkci, tudíž umístěno na zásobníku od adr. 0x9A a končí na 0xD9. Celé je vpořádku až do 56. prvku (adr. 0xD2), zbylých 7 prvků je nesprávně resp. shodné se začátkem ovšem s přebytečnou nulou…
Statické a globální prom. GCC skládá na začátek SRAM od 0x60. Kdyby mi některá z nich již zasahovala do stacku, musel by být porušen začátek tabulky. Navíc toto je stav těsně po její inicializaci…
volatile unsigned char temp] =
{ 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 15, 17,
19, 21, 24, 26, 29, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 61,
64, 67, 71, 74, 77, 80, 83, 86, 89, 92, 94, 97, 100, 102, 105, 107,
109, 111, 113, 115, 117, 119, 120, 121, 123, 124, 125, 125, 126, 127, 127, 127};
pamet_tiny.gif

Zdá se, že simulátor jenom špatně zobrazuje obsah paměti ‘data’.
Čtení z pole v simulátoru funguje správně.
bufer.gif

Mě to nefungovalo ani v reálu. Používal jsem to po naprogramování EEPROM (ponyprog ji z nějakého důvodu naprogramovat neumí a “dospělý” programátor jsem ještě neubastlil). Obsah paměti byl shodný s tím, co mi ukázal simulátor :frowning:

Zkus deklarovat to pole jako statické.

static unsigned char temp[64] = 

Vlastnost automatické lokální proměnné, že uvolní místo po opuštění funkce,
se tady stejně nemůže uplatnit, protože program z funkce main() nikdy nevyjde.

Tomu nerozumím, mně Ponyprog programuje eeprom bez problémů.

Kdyz je static, tak je vpořádku. Stejně mi ale není jasné, proč je nestatické špatně.
Ponyprog se mi tváří, že EEPROM programuje, ale žádná data v ní nejsou. Zato smazat ji umí bezvadně - když kliknu o ikonku vedle, tak ji můžu plnit znova…

Proměnná static se inicializuje pouze jednou, při prvním vstupu do funkce. Existuje od prvního volání až do ukončení programu. Jde v podstatě o globální proměnnou.
Ostatní proměnné se inicializují s každým průchodem jeli deklarace uvnitř cyklu tedy i uvnitř Main.

Proč? Zásobník se plní od vyšších adres k nižším, takže by musel být poškozen konec tabulky.

Ta tabulka je na staku odzadu - na konci staku (spodních adresách v SRAM) je začátek pole, na jeho začátku (nejvyšší adresy) je konec pole (poškozený). Je to vidět na tom prvním obrázku. Chybějící hodnoty jsou čísla 125~127, což je konec tabulky (dle deklarace). Tedy alespoň dle simulátoru v AVR studiu.

Překladač zachází s inicializovaným nestatickým polem takto:

  1. Uloží ho do Flash paměti.
  2. Po resetu se překopíruje z Flash do oblasti RAM.
  3. Na začátku funkce, ve které je pole deklarováno, se překopíruje z této oblasti do stacku.

Takže pole se musí vejít do RAM dvakrát.
Plus musí zůstat místo pro další funkce stacku, proměnné atd.
Čili jeho použití v main() je plýtvání místem, protože obě kopie pole zůstanou v RAM po celou dobu běhu programu…

Statické pole je uloženo v RAM jenom jednou.
Jak píše Technik, neliší se od globální proměnné (kromě viditelnosti).

Proto pole 64 bajtů jako statické funguje, jako nestatické ne.

To bude ono… pole je po startu v ram za globálními proměnnými, tedy o par bytů výše než 0x60. Při jeho kopii na zásobník mu zásobník kousek ukousne aby se pole vešlo a začne kopírování. Když dojde ke konci, kopíruje z adres původního pole, na kterých už je nyní rozlezlý zásobník a je tam začátek toho pole. Tudíž to na konec nakopíruje začátek sebe sama…
Nádhera…
Naštěstí ho nepotřebuju pro program samotný, slouží mi jen občas pro naplnění EEPROM(kde ja tato tabulka uložena) když se náhodou poškodí obsah. Jinak je celá funkce zakomentovaná a neokupuje ono nepatrné množství zdrojů, které jsou k dispozici :slight_smile: