McuLab jediný zdroj v čipu jsou takty

Tohle je statická kopie kapitoly pro vyhledávače. Interaktivní verze má animované obrázky, kontrolní otázky a tlačítka, která příklad načtou do kalkulačky.

Zásobník, který nikdo nedeklaruje

Statická data mají velikost, kterou spočítá linker. Halda má velikost, kterou někdo nastavil. Zásobník má velikost, kterou nikdo nezná — a přeteče do toho, co je pod ním, bez jediného varování.

statická datacelá RAM: 128 kBstatická data40960 Bzásobník576 Bpřerušení360 Bzásobník potřebuje 936 Bz toho přerušení 38 %rezerva 89176 Bvnořená přerušení se sčítají k nejhlubšímu místu hlavního zásobníku, ne vedle něj
RAM rozdělená na tři části. Přidávej vnořená přerušení a sleduj, jak rychle roste ta zlatá.

Dva sčítance, druhý se zapomíná

zásobník = hloubka volání × rámec + úrovně přerušení × rámec přerušenía to druhé nikdo nepočítá

První část je nejhlubší řetěz volání v programu. Ta druhá je to, co se na něj může navršit shora: každé přerušení si uloží kontext a zavolá obsluhu, a když je povolené vnořování, můžou se navršit všechna. Rámec obsluhy bývá větší než běžný — na Cortex-M s plovoucí čárkou má uložený kontext přes sto bajtů.

A tady je ta zákeřnost: nejhorší případ nastane, když se nejhlubší volání sejde s nejvíc vnořenými přerušeními. To se stane zřídka — takže deska funguje týdny a pak jednou spadne. Přetečení zásobníku je nejčastější příčina závady, která se nedá zopakovat.

Jak se to zjistí, když to nejde spočítat

  1. Vyplnit zásobník vzorkem (0xAA) při startu a po hodinách provozu se podívat, kam až se přepsal. Nejjednodušší a nejspolehlivější metoda, jakou embedded má.
  2. MPU jako zarážka. Nastavit oblast pod zásobníkem jako zakázanou; přetečení pak nevyrobí tichou chybu, ale výjimku s adresou.
  3. Statická analýza volacího grafu. Umí to překladač i nástroje; selže jen na ukazatelích na funkce a rekurzi — což jsou právě dvě věci, které do embedded kódu nepatří.

Flash má jiné pravidlo

Program se do flash vejde, nebo ne, a linker to řekne při překladu. Zajímavější je, že flash je pomalejší než jádro a čte se s čekacími stavy (kapitola 3). Kód, který se vejde do cache, běží znatelně rychleji než ten, který se z ní vypadává — a proto se rozpočet taktů z kapitoly 7 nikdy netrefí přesně z počtu instrukcí.

Vzorce v této kapitole

zásobník — nejhorší zásobník
zásobník = hloubka×rámec + přerušení×rámec_ISR [B] ARM Cortex-M4 TRM