prechod z ASM na C

Proč si myslíš, že jde o ještě větší a pomalejší kód? Zřejmě vycházíš z praxe, kdy přilinkováním nějakého objetu neúměrně naroste kód. Jenomže se nesmí zapomenout na to, že ty objekty někdo tvořil za účelem maximální variability a použitelnosti a ve výsledku to mnohdy vypadá jinak. Uvedu jednoduchý příklad:

Vytvoříš čistý projekt ve windows bez čehokoli jen rámeček a přeložíš. Zjistíš velikost přeloženého kódu. Přidáš do projektu jeden oběkt-tlačítko a přeložíš. Přeložený kód naroste o x KB. Přidáním dalšího tlačítka už nenaroste výsledný kód o X KB, ale bude zhruba stejný. Nebude se zvětšovat ani přidáním 100 tlačítek. Tlačítko představuje třídu a má svoji instanci. Přidáním dalšího tlačítka se vytváří jen další instance téže třídy takže není důvod nárůstu kódu, ale jen dat.

Tohle by se v C dělalo jen těžko, navíc obsluha každého tlačítka by vyžadovala, aby program obcházel všechny, jestli na ně někdo nekliknul. To by pak ve výsledku byl velmi líný program.

O tom, že programy vytvořené na základě objektů jsou rychlejší než neobjektové, např. dosovské aplikace, se můžeš snadno přesvědčit. Otevři ve WINDOWS 20 průzkumníků a ve správci úloh se podívej na vytížení procesoru. Pak spusť třeba jen 2 dosovské programy a počítač bude neobyčejně líný.

Je to dáno tím, že neobjektové programování vychází z nekonečné smyčky MainLoop, ve které se sekvenčně zpracovávají jednotlivé procedůry, které sami mnohdy obsahují vlastní smyčky. V nich se ztrácí většina výkonu a proto je výsledek žalostný.
Objekty pracují na jiném principu a popsat je pomocí vývojových diagramů prakticky nelze. Pracují s tzv. handlery a událostmi. Vznikne-li údálost, např. kliknutí na tlačítko, zpracovává se handler tedy něco jako přerušení. Nenastane-li žádná událost, žádný kód se nevykonává, takže procesor není zatěžován.

Podobného principu lze užít i na AVR a vytváčet pro něj třídy, objekty. Ty však bude nutné šít na míru tak, aby jejich kód nebyl zbytečně velký. Jde o jiný princip, o jiný pohled na programování, který přináší své ovoce hlavně v aplikacích, kde se požaduje zpracování několik úloh současně.

To co pise Technik je velmi zaujimave. Mozno by teda stalo za uvahu sa nad tym zamyliet i pre 8b, aspon v podobe testovacieho progamu. Moj popis bol inspirovany hlavne tymi porovnavaniami kodu v spomynanej knihe, kde pre podobne tiredy uloh vysiel kod pisany v C++ cca 3x vacsi oproti C. Zdrojaky tam nie su, je tam len taka mala tabulka. Otazne je, ci by sa tento pristup nehodil prave na tie “tlacitka” ako spomyna Technik pre obsluhu grafickych displayov. Prave tieto je dobre obsluhovat principialne inak, ako 2x16znakov. Kod bude urcite vacsi ako v ASM, ale aspon na skusku.

Nedalo mi to, a taky napíšu něco k věci.

2 Technik: To co ty píšeš, je zajímavé. Ale nepřehlédl si náhodou to, že program nemusí očuchávat všechna tlačítka jen proto, že to za něj dělá systém? Mám ten pocit, že i kdybys program pro třeba mega8 napsal v C++, že dojdeakorát ke zpomalení celého programu. Do toho procesůrku se bude muset nahrát nějaká část programu, která bude dělat za nás “špinavou práci” - třeba “očuchávat” tlačítka - a pokud zjistí, že nějaké bylo zmáčknuté, zavolá příslušný obslužný podprogram, nebo vytvoří novou událost.
Nic proti C++, ale takhle už dlouho píšu i v ASM. Hlavní smyčka pouze kontroluje např. tlačítka, čidla, senzory, a kdovíco ještě, a pokud nastane “něco” (stisknuté tlačítko, překročení teploty), tak se volá obslužný podprogram. Na tohle opravdu objektový Cčko nepotřbuju. Vpohodě si vystačim na tohle s ASM, a navíc mi to poběží 5x rychleji.

Tento typ programů s obsluhou “událostí” je docela dobrá věc, bohužel našly by se i případy, kam to napasovat nelze.

Ještě lepší, je události bufferovat, a v hlavní části programu vytvořit dva, jakoby nezávislé bloky, navazující na sebe. První část, hlídá události, a druhá část provádí užitečnou práci. Jako příklad mi poslouží například přehrávání zvuku:
Pomocí přerušení jsou data pravidelně odesílána do DAC.
V Hlavní smyčce programu se kontrolují události vyvolané uživatelem (třeba tlačítka), a hned po kontrole může probíhat část programu, která například míchá zvuková data ze dvou kanálů do jednoho. Tyto dvě části programů běží po sobě v neustálém cyklu.

Existuje možná o něco lepší metoda správce událostí. Má ale jednu větší nevýhodu, a to, že se ovládací prvky (např. tlačítka) kontrolují jen jednou za čas. Jistě si domyslíte, že kontrola např. tlačítek probíhá v přerušení.
Tuto variantu jsem rozpracoval kdysi více do hloubky. Docela často jsem jí používal na x51, nyní jsem přešel na AVR, se kterými zatím začínám, a zaučuji se s nimi pracovat. Uvidíme, jaké nové metody na nich vymyslím :slight_smile:

Operační systém to nedělá a ani neví kolik má aplikace tlačítek. Po kliknutí myši nad aplikací se předá zpráva, jež obsahuje souřadnice. Až OS přidělí čas aplikaci, začne zpracování zprávy tak, že se prohledávají všechny objekty v aplikaci, tedy i tlačítka a zjistí se, kterému objektu ono kliknutí patří. Následně se zavolá příslušný handler.

Na mega8 nemá velký smysl dělat objekty, protože by se každý typ vyskytoval jen jednou. Na mega644, který má 2 USARTy, už to má smysl. Jeden objekt na 2 nezávislé SIO. Samotné C++ ani objekty neurčují, jak se celý program bude chovat, to je na programátorovi.

Já také a možná ani netušíš, že si při tom vytvořil takový malý objet, nebo alespoň jeho zárodek. A pokud ho vezmeš do clipboradu a vložíš do nového projektu a něco k tomu ještš přidáš, udělal si něco podobného, co se v C++ nazývá dědičností s tím, že napojení na takový objekt musíš udělat ručně, zatímco C++ si to zorganizuje samo.

Ještě by se vrátil k tlačítkům. Pokud by šlo o tlačítka připojená k MCU, lze handler vytvořit přinejmenším dvojím způsobem:

  1. aktivovat přerušení pin change, které reaguje na jakoukoliv změnu vybraných pinů.
  2. Softwareově třeba takto:

in R16,PINA lds R17,StavPred cpse R16,17 call HandlerKyeboard sts StavPred,R16
Tato část může být umístěna v hlavní smyčce, té se asi nikdy nevyhneme, ale podstatné je to, že pokud nebylo stisknuto tlačítko, zpracování smyčky se urychlí. Součástí hl. symčky mohou být instrukce WDR a SLEEP. Pokud se vykonávání instrukcí nevráti do výchozího bodu ve stanoveném limitu, je hlavní vlákno zaseklé a nezbývá než reset. Pokud se vráti brzy, procesor si v instrukci SLEEP “odpočine” a probudí ho interupt nebo timer. Tím se teké sníží spotřeba, takže to pak funguje podobně jako na PC. Čím víc práce, tím více energie spotřebuje.
Pokud bych program napsal třeba takto:

ldd R16,Y+KEYPORT ldd R17,Y+STAVPRED ldd ZL,Y+HANDLERL ldd ZH,Y+HANDLERH cpse R16,R17 icall std Y+STAVPRED,R16
To už je to zárodek objektu - třídy, která má svoji instanci adresovanou pointrem Y. Je jasné, že bude muset existovat nějaký program - konstruktor, který vyplní instanci daty a ještě program, který bude přepisovat stav portů do Y+KEYPORT, protože rozsah instrukce LDD to neumožňuje. Odměnou za to bude nepatrný nárůst kódu pro obsluhu X klávesnic. Stačí jen měnit Y a x-krát volat tuto část, resp. uzavřít ji do cyklu. Lze to napsat i pro jednotlivé piny, vložit do toho filtraci zákmitů, vyhodnocení dlouhého držení tlačítka a autorepeat.

2 Technik, zdá se že se vyznáš, v C(++) na kompech nedělám, dělám ale ve FreePascalu - má to syntaxi pascalu, jinak to má vše co C++. Objekty, třídy, nač si vzpomeneš. Bohužel ještě jsem neměl tu možnost objekty pořádně nastudovat (neměl jsem potřebu). ALe mám tu na to knížku, takže to nebude problém.

Ten první příklad kodu, to jak ukazuje zrychlení programu v tom, že se uchovává původní hodnota, a případné další podmínky probíhají jen došlo-li ke změně, to znám, párkrát jsem to i použil.

u obou příkladů m it o trochu komplikuje to, že s AVR ještě začínám, tudíž neznám všechny instruukce, a furt je musím hledat, ale přibližně jsem pochopil, oč jde.

“Prohledávají všechny objekty” - jasný, říkal jsem, že bez toho, aniž bys jeden objekt po druhym prohledal, se to neobejde. Já si jen myslel, že tohle edělá za programátora systém, na kerém aplikace běží. (to je ta neznalost OOP a WinAPI) :slight_smile:

Nemusí se prohledávat jeden po druhém. Pokud klikneš myší nad nějakým objektem, zjistí se podle hlavního rámčku, které aplikaci patří. Tím se vyloučí stovky dalších objektu, které jsou momentálně ve windows aktivní. A i v té aplikaci jsou ikony na nějaké liště, takže se určí konkrétní lišta a teprve potom se hledá ta odkliknutá ikona. Je to podobné, jako když hledáš soubor v adresáři a znáš cestu.

Něco jiného je, když musím programově “očuchávat” všechna tlačítka, jestli není některé stisknuté. Neustálým dotazováním procesor ztrácí čas a ze signálu, který obdrží, musí lokalizovat konkrétní talčítko a to i vpřípadě, že žádné není stisknuto.