Hlavní navigace

Senzory Martina Malého: O jednočipech a architektuře

Autor: Arduino
Martin Malý

Někdy čerpám vhodná témata pro svoje texty na školeních a kurzech, protože otázky posluchačů bývají velmi podnětné a zajímavé.

Na kurzu Arduino pro učitele se takhle přihlásil jeden posluchač a položil dotaz: Jak se ten program v RAMce u toho AVR spustí, jakým příkazem? Čímž předběhl lehce výklad, protože teoretickou vsuvku o rozdílech architektur máme o něco později, ale nešť, když už se zeptal, tak jsme rozdíly vysvětlili hned, ale tazatel měl ještě několik podotázek. Bohužel, nebyl prostor se tomu věnovat hned na místě, ale připadlo mi to jako zajímavé a podnětné téma.

Počítač se skládá většinou z několika základních částí: z procesoru, který řídí celý chod systému, z paměti, kde je uložený program a data, a ze vstupně-výstupních obvodů, kterými komunikuje s okolím. Existují dvě hlavní architektury, totiž von Neumannova, kde je operační paměť společná pro program a data, a harvardská, kde jsou paměti pro data a pro program oddělené. U jednočipů je častější architektura harvardská, u počítačů pro všeobecné použití zase von Neumannova.

Tomu rozumím, povídal tazatel. Ale proč? Já když měl ZX Spectrum, tak tam byl nějaký obslužný program v ROMce, byl tam BASIC, ale programy pak běžely v RAMce, když byly ve strojáku… To je hrozně nevýhodné, protože tady jsou jen dvě kila paměti, tam se nic nevejde… No, jak se to vezme. U jednočipu, třeba toho arduinského AVR, je paměť RAM opravdu určena pro ukládání zpracovávaných dat a zásobník, kód je v paměti FLASH (tedy de facto ROM). Ale pokud je třeba a je to zcela nezbytné, lze celou konstrukci pojmout tak, že ve FLASH je uložen program, který emuluje nějaký procesor a interpretuje hodnoty, uložené v RAM, jako instrukce. Ale vzhledem k tomu, že mikrokontroléry jsou primárně určené k tomu, aby dělaly jednu jedinou úlohu, která se po dobu jejich “života” v daném zařízení nijak výrazněji nemění, tak je harvardská architektura docela vhodná.

Jenže tím přicházíte o mnohé výhody a možnosti! – Jaké například? – No, třeba na tom Spectru jsem si psal programy, které samy sebe modifikovaly… Bohužel, na takovouto debatu už nebyl prostor, tak dovolte zde:

Jednočipy, až na výjimky, používají harvardskou architekturu, a je k tomu hned několik důvodů. S touto architekturou můžete pro data a pro program zvolit rozdílné typy pamětí – třeba mikrokontroléry PIC od Microchipu ze základní a střední řady (PIC10 – PIC16) zpracovávají osmibitová data, ale instrukce mají 12, resp. 14 bitů. Paměť FLASH je menší při stejné kapacitě než paměť SRAM, proto je ekonomičtější a výrobci tím snižují náklady. No a v neposlední řadě vychází volba architektury z toho, jak se jednočipy používají. Situací, kdy by bylo výhodné často měnit obslužný program, je velmi málo, a pokud nastanou, je lepší sáhnout po standardním procesoru.

A ta samomodifikace? Po pravdě řečeno naprostá většina jednočipů má možnost pomocí programových prostředků zapsat data do své vlastní paměti FLASH, respektive číst instrukce jako data (a díky tomu ukládat třeba některé konstanty do paměti programu). Přesnější by tedy bylo hovořit o modifikované harvardské architektuře. I v Arduinu je programování po sériové lince zajištěné pomocí tzv. bootloaderu, což je malý program, který se spustí po startu a očekává nějaká data po sériové lince. Pokud během krátkého časového úseku začnou chodit data, bootloader je zapisuje do FLASH, čímž de facto “programuje obvod”. Po konci sekvence se opět resetuje. Když po resetu data nepřijdou, spustí nahraný kód. Bootloader je tedy příklad “samomodifikujícího se programu”, i když notně svérázný.

Tip Content Kortanová

Upřímně řečeno – samomodifikující se programy jsou do jisté míry relikt z dob, kdy optimalizace vládla světu a kdy napsat něco takového byla často jediná možnost, jak dosáhnout požadovaného výsledku. Na druhou stranu je to technika extrémně silná, a tím pádem i extrémně nebezpečná. Tak nebezpečná, že se jí moderní procesory snaží bránit tím, že virtuálně, pomocí správce paměti, rozdělují paměť na kód a data, a pokus o zápis do paměti programu končí výjimkou. Samozřejmě že nejprivilegovanější kód může toto omezení obejít a těžit tak z výhod von Neumannovy architektury, ale běžný uživatelský proces běží v podmínkách, které napodobují modifikovanou harvardskou architekturu: zápis do samotného kódu je považován za chybu a pokus o narušení integrity kódu.

U toho jednočipu by možná omezené možnosti sváděly k tomu, že by mohlo někomu připadat jako dobrý nápad optimalizovat sebemodifikací, ale pravda je, že nezvládnutá sebemodifikace nekončí u jednočipu výjimkou (není žádný supervizor, který by dokázal nahodit vše zas na koleje), ale stavem, kterému se ve světě embedded zařízení (a nejen těch) říká trefně: bricknuto! Tedy že jste si právě ze svého zařízení udělali cihlu.

Našli jste v článku chybu?
4. 1. 2017 10:30
Klik je cvik (neregistrovaný)

Dělení na „Harvardskou“ a „Von Neumannovu“ architekturu se mi zdá vzhledem k dnešnímu stupni integrace už jen jako čistě akademická záležitost. Je však pravdou žekaždá má své výhody i nevýhody.

4. 1. 2017 14:17
JJ (neregistrovaný)

Možná by se slušelo dodat, že konkrétně z controllerů AVR se opravdu neoživitelná cihla dá udělat jen extrémně těžko, pokud to vůbec jde. I když zvořu programování fuses a nemám hodiny nebo si odstřelím SPI/JTAG apod. pořád je tu možnost připojit externí hodiny, použít HV programování apod.

Výhodou harvardské architektury je to, že i když existují prostředky pro modifikaci flash, musí je aplikace explicitně používat. Nejde jen tak podstrčit kód v nějakých modifikovaných datech, následně nechat …