Přeskočit na hlavní obsah

16 článků s tagem "Embedded"

Vývoj embedded softwaru

Zobrazit všechny tagy

Ladění HardFaultu na Cortex-M: od záhady k řádku kódu

· 10 minut čtení

Každý embedded vývojář zná ten okamžik: firmware běžel, a pak najednou neběží. Debugger ukazuje, že program sedí v nekonečné smyčce se jménem jako HardFault_Handler nebo Default_Handler, a call stack tvoří pár nic neříkajících rámců. Ta smyčka je výchozí handler ze startup kódu a o tom, co se stalo, neříká absolutně nic. Chyba má ale příčinu a procesor si ji už zapsal: v osmi registrech na zásobníku a ve čtyřech stavových registrech. Stačí je jen přečíst.

Tento článek ukazuje, jak z té smyčky získat řádek zdrojového kódu, na dvou skutečných příkladech, které jsem spustil v QEMU (model desky se STM32F4) a prozkoumal pomocí GDB: volání ukazatele na funkci s hodnotou NULL a zápis na adresu, kde nic není. Všechny výstupy jsou skutečné.

Spuštění skutečného firmwaru bez hardwaru: simulátor v CI

· 8 minut čtení

V článku o unit testování s Unity a CMock jsem řekl, že testy na PC nenajdou „rozdíly mezi PC a MCU". Tento článek je o těchto rozdílech a o nástroji, který je najde: simulátoru, který spouští skutečný binární soubor. Ne logiku přeloženou pro PC, ale přímo .elf, který vytvořil překladač ARM, se skutečným startup kódem a skutečným linker scriptem, na modelu procesoru a jeho periferií.

Ukážu dva experimenty, které jsem spustil: tentýž zdrojový kód testu, který na PC projde a na Cortex-M4 selže, a firmware, který zapisuje do registrů USART na skutečných adresách STM32F4 a jehož text se objeví v terminálu. Na konci je upřímný seznam toho, co vám simulátor neřekne.

Reprodukovatelné buildy: připněte nástroje, připněte zdroje, odstraňte hodiny

· 9 minut čtení

Zákazník volá kvůli firmware, který jste dodali před čtrnácti měsíci. Vyberete tag, přeložíte ho, nahrajete a chyba tam není. Zmizela chyba, nebo je to jiný firmware? Pokud váš build není reprodukovatelný, nedokážete to říct. Nikdo to nedokáže, protože binárka, kterou jste právě přeložili, se od dodané liší způsoby, které nevidíte ani nedokážete vysvětlit: jiná verze překladače, knihovna aktualizovaná na PC, cesta ke složce, denní doba.

Reprodukovatelný build má jednoduchou definici: stejné vstupy dají stejné bajty. Tento článek ukazuje, jaké jsou vstupy buildu firmware, jak je platforma Embedbits připíná (Artifacts Handler) a experiment, který jsem udělal: dva buildy stejného zdroje, ve dvou složkách ve dvou různých časech, dají dvě různé binárky. Po třech změnách pak dají tu samou, co do posledního bitu.

Návrh API periferie: osm rozhodnutí za modulem Gpio

· 9 minut čtení

GPIO je nejjednodušší periferie mikrokontroléru: pin je high nebo low. Právě proto je dobrým tématem pro článek o návrhu rozhraní. Není tu žádná hardwarová složitost, za kterou by se dalo schovat, a každé rozhodnutí je volbou návrháře: jak se pin jmenuje, co funkce vrací, kde žije polarita LED. Modul Gpio z MCAL v Embedbits BSP je skutečný příklad se skutečnými odpověďmi a projdu je jednu po druhé, včetně alternativ a ceny.

Kód z modulu je citován z větve STM32H5 repozitáře Bsp-Mcal-Gpio. Příklady, které ho používají, byly přeloženy a spuštěny proti skutečným Gpio_Port.h a Gpio_Types.h, s malou náhradní implementací, aby bylo možné API vyzkoušet na PC.

Doxygen pro embedded C: dokumentace, na kterou nelze zapomenout

· 7 minut čtení

Každý projekt má dokumentaci a každý projekt má dokumentaci, která lže. Word soubor s popisem rozhraní byl správný v týdnu, kdy vznikl. Komentář nad funkcí je poctivější, protože je pár řádků od kódu, který popisuje, ale píší ho tytéž lidé, kteří zapomínají. Cesta ven nevede přes větší disciplínu, ale přes nástroj, který komentáře přečte, sestaví z nich dokumentaci a shodí build, když něco chybí. Tím nástrojem je Doxygen.

Tento článek ukazuje, jak vypadá zdokumentovaný modul v mých projektech, jak se generuje a jak z dokumentace udělat součást CI, kterou nelze přeskočit. Příklady vznikly s Doxygen 1.9.8 a Graphviz a výstupy jsou skutečné.

CMake pro embedded firmware: build, který se dá číst

· 10 minut čtení

Projekt v IDE je soubor, který nikdo nečte: několik tisíc řádků XML, které IDE zapíše a IDE přečte a které nelze zrevidovat v pull requestu. Build pak existuje jen na počítači, kde ho někdo naklikal. CMake to řeší jinou filozofií: build je text, který čtete, revidujete, verzujete a spouštíte v CI úplně stejně jako u svého stolu.

Build systém platformy Embedbits (EmBi_Platform) je postaven na CMake a tento článek vysvětluje části, které potřebuje každý embedded build v CMake, na malém projektu, který jsem sestavil a spustil: toolchain file, pojmenované flagy, typy buildu, moduly jako knihovny, linker script, soubory po linkování a test, který spouští firmware v simulátoru. Všechna čísla a výstupy jsou skutečné.

Přerušení a main(): jak bezpečně sdílet data

· 9 minut čtení

Obsluha přerušení a hlavní smyčka jsou dva programy, které běží ve stejné paměti a o sobě nevědí. Překladač C neví, že přerušení existuje, a CPU neví, že dvě proměnné patří k sobě. Ví to jen programátor a chyby, které z toho vznikají, jsou ty nejhorší: objeví se jednou za tisíc běhů, zmizí, když připojíte debugger, a při code review se nikdy neukážou, protože kód vypadá správně.

Tento článek prochází tři problémy sdílených dat, jeden po druhém, s kódem, který selhává, a potom ukazuje vzory, které fungují. Experimenty běží na Cortex-M4 (v QEMU, na modelu desky s STM32F4) nebo na PC a výstupy jsou skutečné.

Konečné automaty v praxi: tlačítko s debounce a dlouhým stiskem

· 9 minut čtení

V prvním článku o konečných automatech jsem vám dal šablonu a skončil jsem slovy „pokračování příště“. Tohle je to pokračování a nejlepší způsob, jak pokračovat po teorii, je problém. Vybral jsem takový, který má každý embedded projekt a který nikdo nenapíše správně na první pokus: tlačítko.

Tlačítko vypadá triviálně: pin, high nebo low. Jenže mechanický kontakt zakmitává, takže pin udělá 1 0 1 1 0 1, než se ustálí, a produkt obvykle chce od stejného tlačítka dvě různé věci: krátký a dlouhý stisk. Napsané pomocí příznaků a čítačů v hlavní smyčce to skončí jako pár ifů, které na sobě závisejí způsobem, který po měsíci nikdo nevysvětlí. Konečný automat to vyřeší tak, že to vysvětlíte tabulkou.

Jeden BSP, mnoho rodin STM32: proč Git větve a kolik stojí

· 9 minut čtení

STM32 není jeden mikrokontrolér, je to tucet rodin: G4, H5, U5, F4 a tak dále. Mají stejné jádro Cortex-M, ale jiné periferie, jiné názvy registrů a jiný balík ovladačů od výrobce. Pokud chcete, aby jedna architektura firmwaru běžela na všech, musíte se rozhodnout, kde budou rozdíly žít. Žádná varianta není zadarmo. Tento článek popisuje tu, kterou jsem zvolil pro BSP Embedbits, co o ní říkají čísla ze skutečných repozitářů a kolik stojí.

Co se děje před main(): reset, startup kód a linker script

· 10 minut čtení

Každý tutoriál jazyka C začíná int main(void). Nikdo ale nevysvětluje, kdo ji volá. A přitom když napíšete uint32_t counter = 5; jako globální proměnnou a první řádek main() přečte 5, už se odvedlo hodně práce. Když se ta práce neodvede, projeví se to proměnnou s náhodnou hodnotou, která „včera fungovala".

V tomto článku budeme sledovat mikrokontrolér od resetu až po první řádek main(): co udělá hardware sám, co říká linker script a co musí udělat startup kód. Jde o obsah dvou modulů Embedbits BSP (Linker a Startup), ale princip je stejný na každém Cortex-M. Veškerý kód v článku byl přeložen pomocí arm-none-eabi-gcc 13.2.1 a spuštěn v QEMU na modelu desky se STM32F405, takže adresy i výstupy jsou skutečné.