Jak na to, když si chci ve Windows něco přidat k mašinerii Arduina a nechci, aby se mi to při aktualizaci Arduino IDE ztratilo?
tl;dr: UAC Virtualization.
Představme si takovou situaci: vytvoříme si vlastní desku pro Arduino, a k tomu pak potřebujeme podporu v IDE. To se zařídí souborem boards.local.txt (a dalšími, ale to teď není podstatné), který se umístí vedle boards.txt v instalaci Arduina. Jenže pak se nám to při nejbližší aktualizaci ztratí – instalátor Arduina nejdřív odinstaluje starou verzi, čímž snaže všechno, a pak nainstaluje novou. Takže po aktualizaci si musíme vzpomenout, že jsme tam měli nějaké své věci a dát je tam znovu. To si ale musíme vzpomenout už před aktualizací, že tam nějaké své věci máme, protože při té aktualizaci bychom o ně přišli a nebylo by je odkud znovu vzít (instalátor sice předtím řekne, že jestli tam něco mám, tak si to mám schovat, ale já si určitě po nějaké době už nevzpomenu, že jsem si tam něco přidával). Například soubory s lokálním doplněním té konfigurace boards.local.txt (definice vlastních desek) nebo platform.local.txt (nějaké vlastní nastavení, třeba na kopírování HEX a EEP po kompilaci, viz starší článek .lst, .hex a .eep v Arduino IDE).
Jak na to? Jednak si můžeme metodicky všechny takové věci schovávat někde vedle a napsat si někam poznámku, že a kde to máme a kam to po aktualizaci zase uložit, a pak to podle toho po aktualizaci provést. No, to je dost nereálné, když jsem bordelář a sklerotik.
Anebo můžeme využít vlastností Windows, že podstrkává aplikacím jejich data, když si je „omylem“ zapíšou, kam nemají – například do Program Files. V takovém případě Windows data uloží jinam, do uživatelova prostoru, aby tím neovlivnily jiné uživatele. No a když pak aplikace chce k těm datům přistoupit, tak jim je podstrčí místo toho, co tam vidí normální ostatní uživatelé.
Příklad snad vše osvětlí:
Situace A – nepříjemná:
Vytvořil jsem si vlastní desku a napsal jsem si soubor boards.local.txt, který jsem uložil tam, kde má být, tedy do adresáře C:\Program Files\Arduino\hardware\arduino\avr, k tomu jsem vytvořil její mapování na Arduino piny do souboru C:\Program Files\Arduino\hardware\arduino\avr\variants\mojedeska\pins_arduino.h.
Pak jsem po čase pustil instalaci nové verzi Arduina. Ta mi řekla, že smaže nejdřív starou a že jestli tam něco mám, že si to mám schovat. Jenže já jsem starej sklerotik, takže si nepamatuju, že jsem si tam ten boards.local.txt dal a klidně instalátor nechám pokračovat.
Po instalaci nové verze s hrůzou zjišťuji, že moje geniální deska už nemá v Arduinu podporu a já si to nastavení už nepamatuju.
Situace B – funkční ale nereálná:
Vytvořil jsem si vlastní desku a napsal jsem si soubor boards.local.txt, který jsem uložil … atd.
Pustil jsem instalaci nové verze Arduina, při ní jsem si vzpomněl, že tam ten soubor mám a okopíroval jsem si ho na chvíli vedle. Pak jsem instalátor nechal všechno smazat a nainstalovat načisto.
Po instalaci nové verze přemisťuji soubor na správné místo.
Situace C – metodická ale nereálná:
Vytvořil jsem si vlastní desku a napsal jsem si soubor boards.local.txt, který jsem uložil … atd.
Okopíroval jsem si boards.local.txt tam, kde si schovávám instalační soubory, a k tomu jsem si připsal poznámku, že s novou verzí Arduina se to má okopírovat do C:\Program Files\Arduino\… atd.
Pustil jsem instalaci nové verze Arduina, nechal jsem všechno smazat a nainstalovat načisto.
Po instalaci nové verze zkontroluju poznámky, protože si je dělám vždy, když něco instaluji nebo doinstaluji. Nalézám poznámku a ten soubor a kopíruju ho na správné místo.
Situace D – prasečina, ale prefíkaná a funkční:
Vytvořil jsem si vlastní desku a napsal jsem si soubor boards.local.txt. Ten ovšem ukládám bez administrátorského oprávnění do adresáře C:\Program Files\Arduino\hardware\arduino\avr, což Windows zařídí tak, že mi ho místo toho uloží do C:\Users\David\AppData\Local\VirtualStore\Program Files\Arduino\hardware\arduino\avr. Podobně s tím souborem s mapováním pinů.
Windows ho pak vždycky předhodí Arduinu, když se Arduino ptá, jestli náhodou v C:\Program Files ten soubor není (dělá to při startu IDE).
Pak reinstaluju Arduino jak chci, a i když se adresář v C:\Program Files smaže, tak ten VirtualStore ne.
(situace A, B a C jsou tím horší, čím je souborů víc)
Obdobným způsobem jsem si rozšířil schopnosti základní funkčnosti na čtení analogových vstupů. To nemá vlastní knihovnu, je to součástí „jádra“ Arduina jako funkce analogRead. Standardně tahle funkce vrací třeba na ATmega128 10bitovou hodnotu ve dvoubajtové proměnné, kde 6 nejvyšších bitů je nulových. Pokud nepotřebuji plné desetibitové rozlišení, tak by mi stačil třeba 1 bajt, ve kterém bude 8 vyšších bitů z těch 10 bitů výsledku. Můžu je z té dvoubajtové proměnné získat třeba posunem doprava o 2 bity, ale taky můžu AD převodník nastavit tak, aby těch 10 bitů vracel zarovnaných v těch 2 bytech doleva, ne doprava (je to bit ADLAR v registru ADMUX), a pak číst jen ten horní bajt výsledku (registr ADCH). Do zdrojáku C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino\wiring_analog.c jsem si proto připsal nastavování toho bitu (ono to tam totiž je natvrdo nastavené na zarovnávání doprava) a zdroják jsem uložil do C:\Users\David\AppData\Local\VirtualStore\Program Files\Arduino\hardware\arduino\avr\cores\arduino\wiring_analog.c . No a odteď mi ho Arduino kompiluje, a i když jsem už mezitím několikrát při aktualizacích přeinstalovával Arduino, tak tenhle zdroják tam zůstává a při nové instalaci se zase použije.
Má to ovšem jeden háček – až jednou do toho zdrojáku Autoři Arduina hrábnou a třeba přidají něco skvělého, tak mě se při další aktualizaci sice nová verze nainstaluje, ale při kompilaci se přeplácne tou mojí hacknutou verzí a já budu marně přemýšlet a hledat, jaktože mi nová funkčnost knihovny nefunguje…
Není to žádná novinka. Je to využití „UAC Virtualization“ které funguje už od Windows Vista: When an application modifies a system-global location in the file system or registry and that operation fails because access is denied, Windows redirects the operation to a per-user area; when the application reads from a system-global location, Windows first checks for data in the per-user area and, if none is present, permits the read attempt from the global location.
Krátký popis třeba zde: UAC Virtualization and how it affects your Installers
Jestli vám to nepřipadá srozumitelné, nevadí. Akorát pak se v tom teda radši nehrabte, a hlavně pak u mě nereklamujte, že jsem blbě poradil a „ono“ „se“ to rozbilo.