<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>EmbedBits Blog</title>
        <link>https://embedbits.cz/sk/blog</link>
        <description>EmbedBits Blog</description>
        <lastBuildDate>Wed, 07 Oct 2026 20:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>sk</language>
        <item>
            <title><![CDATA[Ladenie HardFaultu na Cortex-M: od záhady k riadku kódu]]></title>
            <link>https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m</link>
            <guid>https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m</guid>
            <pubDate>Wed, 07 Oct 2026 20:00:00 GMT</pubDate>
            <description><![CDATA[Každý vývojár embedded systémov pozná ten okamih do ôsmich registrov na zásobníku a do štyroch stavových registrov. Stačí ich len prečítať.]]></description>
            <content:encoded><![CDATA[<p>Každý vývojár embedded systémov pozná ten okamih: firmvér bežal a zrazu už nebeží. Debugger ukazuje, že program sedí v nekonečnej slučke s názvom ako <code>HardFault_Handler</code> alebo <code>Default_Handler</code>, a zásobník volaní tvorí niekoľko nezmyselných rámcov. Tá slučka je <strong>predvolený</strong> handler zo startup kódu a o tom, čo sa stalo, nehovorí vôbec nič. Porucha má príčinu a procesor si ju už zapísal: do ôsmich registrov na zásobníku a do štyroch stavových registrov. Stačí ich len prečítať.</p>
<p>Tento článok ukazuje, ako z tej slučky získať riadok zdrojového kódu, na dvoch reálnych príkladoch, ktoré som spustil v QEMU (model dosky s STM32F4) a preskúmal pomocou GDB: volanie <code>NULL</code> ukazovateľa na funkciu a zápis na adresu, kde nie je nič. Všetky výstupy sú skutočné.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-robí-jadro-keď-nastane-porucha">Čo robí jadro, keď nastane porucha<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#%C4%8Do-rob%C3%AD-jadro-ke%C4%8F-nastane-porucha" class="hash-link" aria-label="Priamy odkaz na Čo robí jadro, keď nastane porucha" title="Priamy odkaz na Čo robí jadro, keď nastane porucha" translate="no">​</a></h2>
<p>Procesor Cortex-M sa nezrúti potichu. Keď nemôže pokračovať (neplatná inštrukcia, chyba zbernice, nepovolený prístup), spracuje <strong>výnimku</strong> a urobí dve veci, ktoré sú pre ladenie dôležité:</p>
<ol>
<li class=""><strong>Uloží osem registrov na zásobník</strong>: <code>R0</code>, <code>R1</code>, <code>R2</code>, <code>R3</code>, <code>R12</code>, <code>LR</code>, <code>PC</code> a <code>xPSR</code>. Uložený <code>PC</code> je inštrukcia, ktorá spôsobila poruchu, a uložený <code>LR</code> hovorí, kto zavolal funkciu, v ktorej porucha nastala.</li>
<li class="">Nastaví <strong>bity v stavových registroch porúch</strong>, ktoré hovoria, o aký druh poruchy išlo: <code>CFSR</code> (konfigurovateľný stav porúch, zložený z troch častí pre poruchy pamäte, zbernice a použitia), <code>HFSR</code> (stav hard fault) a adresové registre <code>MMFAR</code> a <code>BFAR</code> s adresou, ku ktorej sa pristupovalo.</li>
</ol>
<p>Poruchy pamäte, zbernice a použitia (usage fault) majú vlastné handlery, ale po resete sú <strong>vypnuté</strong>, takže každá porucha je <em>eskalovaná</em> na HardFault. Preto jeden handler vidí všetko a bit <code>FORCED</code> v <code>HFSR</code> hovorí, že sa tak stalo.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="handler-ktorý-číta-registre">Handler, ktorý číta registre<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#handler-ktor%C3%BD-%C4%8D%C3%ADta-registre" class="hash-link" aria-label="Priamy odkaz na Handler, ktorý číta registre" title="Priamy odkaz na Handler, ktorý číta registre" translate="no">​</a></h2>
<p>Jediná ťažkosť je dostať sa k zásobníku, kde registre sú. Jadro má dva ukazovatele zásobníka (<code>MSP</code> pre výnimky a hlavný kód, <code>PSP</code> pre úlohy operačného systému) a bit 2 hodnoty v <code>LR</code> pri vstupe do výnimky hovorí, ktorý z nich bol použitý. Musí sa to urobiť <em>predtým</em>, než kompilátor použije zásobník na vlastné účely, takže handler je krátka funkcia v assembleri (<code>naked</code>: bez prológu), ktorá odovzdá ukazovateľ funkcii v C:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">fault.c (the report)</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- the fault report ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">SCB_CFSR</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0xE000ED28u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">   </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* configurable fault status */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">SCB_HFSR</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0xE000ED2Cu</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">   </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* hard fault status */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">SCB_MMFAR</span><span class="token macro property"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0xE000ED34u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">SCB_BFAR</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0xE000ED38u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The registers that the core pushed on the stack when the fault happened. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> r0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> r1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> r2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> r3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> r12</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> lr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* where the faulting code was called from */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> pc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* the instruction that caused the fault   */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> xpsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">stackFrame_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">volatile</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">stackFrame_t</span><span class="token plain"> frame</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain">     cfsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> hfsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> mmfar</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bfar</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">HardFault_Report</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">stackFrame_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">frame</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">used</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">HardFault_Report</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">stackFrame_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">frame</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">frame </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">frame</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">cfsr  </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> SCB_CFSR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hfsr  </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> SCB_HFSR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">mmfar </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> SCB_MMFAR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">bfar  </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> SCB_BFAR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"*** HardFault ***\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"PC   "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> frame</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">pc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"LR   "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> frame</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">lr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"xPSR "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> frame</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">xpsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"CFSR "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">cfsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"HFSR "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> faultInfo</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">hfsr</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* stay here, so that a debugger can look at the state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The core uses the main or the process stack, depending on bit 2 of EXC_RETURN (in LR). */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">naked</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">HardFault_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    __asm__ </span><span class="token keyword" style="font-style:italic">volatile</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"tst   lr, #4        \n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"ite   eq            \n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"mrseq r0, msp       \n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"mrsne r0, psp       \n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"b     HardFault_Report \n"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Pozrite sa na tri časti. Štruktúra <code>stackFrame_t</code> je rozloženie ôsmich registrov v poradí, v akom ich jadro ukladá. Funkcia <code>HardFault_Report()</code> ich (spolu so stavovými registrami) skopíruje do globálnej premennej <code>faultInfo</code>, vypíše krátku správu a potom <strong>zámerne zostane v slučke</strong>, aby sa mohol pripojiť debugger a pozrieť sa na túto premennú. Assemblerový stub vyberie správny zásobník a skočí na ňu. V produkte by sa správa zapísala do pamäte, ktorá prežije reset, a firmvér by sa sám resetoval, ale princíp je rovnaký.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="príklad-1-volanie-null-ukazovateľa">Príklad 1: volanie <code>NULL</code> ukazovateľa<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#pr%C3%ADklad-1-volanie-null-ukazovate%C4%BEa" class="hash-link" aria-label="Priamy odkaz na príklad-1-volanie-null-ukazovateľa" title="Priamy odkaz na príklad-1-volanie-null-ukazovateľa" translate="no">​</a></h2>
<p>Toto je aplikácia s chybou. Callback sa zaregistruje neskôr, ale kód, ktorý ho volá, sa spustí skôr:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">fault.c (the application)</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- the application with a bug ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token class-name" style="color:rgb(255, 203, 107)">callback_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">callback_t</span><span class="token plain"> onButtonPressed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">      </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* will be registered later: it is NULL at the start */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">onButtonPressed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* the bug: the callback is called before it is set */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"start\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"never printed\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Program vypíše <code>start</code> a potom správu:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">start</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">*** HardFault ***</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PC    0x00000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">LR    0x08000115</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">xPSR  0x60000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">CFSR  0x00020000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">HFSR  0x40000000</span><br></div></code></pre></div></div>
<p>A teraz jej čítanie, hodnotu po hodnote:</p>
<ul>
<li class=""><strong><code>PC = 0x00000000</code></strong>: procesor sa pokúsil vykonať inštrukciu na adrese nula. Takmer vždy to znamená skok cez <code>NULL</code> ukazovateľ na funkciu alebo návrat na poškodenú adresu.</li>
<li class=""><strong><code>CFSR = 0x00020000</code></strong>: bit 17 je <code>INVSTATE</code>, „neplatný stav". Procesor sa pokúsil vykonávať kód v stave ARM, ktorý Cortex-M nemá. Dôvod je v <strong><code>xPSR</code></strong>: jeho bit 24 je bit <code>T</code> (Thumb) a tu je nulový (<code>0x60000000</code>). Adresa funkcie v Thumb móde má najnižší bit nastavený, <code>NULL</code> nie, takže skok cez ukazovateľ vynuloval bit <code>T</code>. Nulový bit <code>T</code> je typický odtlačok skoku na <code>NULL</code>.</li>
<li class=""><strong><code>HFSR = 0x40000000</code></strong>: bit 30 je <code>FORCED</code>, porucha bola eskalovaná na HardFault z usage fault, ktorý nie je povolený.</li>
<li class=""><strong><code>LR = 0x08000115</code></strong>: návratová adresa s nastaveným najnižším bitom (Thumb). Je to adresa <strong>volajúceho</strong>, <code>0x08000114</code>, a práve tam je chyba.</li>
</ul>
<p>S debuggerom trvá posledný krok pár sekúnd. QEMU čaká na GDB (<code>-S -gdb tcp::1234</code>) a session vyzerá takto:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) break fault.c:64</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) continue</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Breakpoint 1, HardFault_Report (frame=0x2001ffc0) at fault.c:64</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) print/x faultInfo.frame</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">$1 = {r0 = 0xdeadbeef, r1 = 0x80001f4, r2 = 0x8000220, r3 = 0x0, r12 = 0x0,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      lr = 0x8000115, pc = 0x0, xpsr = 0x60000000}</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) print/x faultInfo.cfsr</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">$2 = 0x20000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) info symbol faultInfo.frame.lr</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Button_Pressed + 7 in section .text</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) list *(faultInfo.frame.lr &amp; ~1u)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">0x8000114 is in Button_Pressed (fault.c:87).</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">82	static callback_t onButtonPressed;      /* will be registered later: it is NULL at the start */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">84	void Button_Pressed(void)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">85	{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">86	    onButtonPressed();                  /* the bug: the callback is called before it is set */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">87	}</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) x/2i (faultInfo.frame.lr &amp; ~1u) - 4</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   0x8000110 &lt;Button_Pressed+2&gt;:	movs	r3, #0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   0x8000112 &lt;Button_Pressed+4&gt;:	blx	r3</span><br></div></code></pre></div></div>
<p><code>info symbol</code> dá funkciu, <code>list *</code> dá riadok (ten <em>za</em> volaním, pretože to je návratová adresa) a disassembler ukáže dvojicu inštrukcií, ktorá je samotnou chybou: načítanie nuly do <code>r3</code> a <code>blx r3</code>, volanie cez register, ktorý obsahuje <code>NULL</code>. Všimnite si <code>r3 = 0x0</code> v uložených registroch. Bez debuggera je rovnaká odpoveď jedným príkazom toolchainu, ktorý potrebuje len adresu zo správy a súbor s ladiacimi informáciami (<code>-g</code>):</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">$ arm-none-eabi-addr2line -e fault.elf -f 0x08000114</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Button_Pressed</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">fault.c:87</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="príklad-2-zápis-na-adresu-kde-nie-je-nič">Príklad 2: zápis na adresu, kde nie je nič<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#pr%C3%ADklad-2-z%C3%A1pis-na-adresu-kde-nie-je-ni%C4%8D" class="hash-link" aria-label="Priamy odkaz na Príklad 2: zápis na adresu, kde nie je nič" title="Priamy odkaz na Príklad 2: zápis na adresu, kde nie je nič" translate="no">​</a></h2>
<p>Zmenil som jeden riadok aplikácie: namiesto callbacku funkcia zapisuje na adresu <code>0xA0000000</code>, kde v modeli čipu nie je namapované nič. Správa:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">*** HardFault ***</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PC    0x08000124</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">LR    0x08000199</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">xPSR  0x21000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">CFSR  0x00008200</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">HFSR  0x40000000</span><br></div></code></pre></div></div>
<p>Tentoraz je <code>PC</code> <strong>platná adresa vo flash</strong>, bit <code>T</code> je nastavený (<code>0x21000000</code>) a <code>CFSR</code> je iný: <code>0x8200</code> sú dva bity, 9 (<code>PRECISERR</code>, presná chyba dátovej zbernice) a 15 (<code>BFARVALID</code>, register <code>BFAR</code> obsahuje adresu). V GDB:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) print/x faultInfo.cfsr</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">$1 = 0x8200</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) print/x faultInfo.bfar</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">$2 = 0xa0000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(gdb) info symbol faultInfo.frame.pc</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">main + 12 in section .text</span><br></div></code></pre></div></div>
<p><code>BFAR</code> je adresa, na ktorú sa program pokúsil zapisovať, <code>PC</code> je inštrukcia, ktorá to skúsila. Spolu hovoria „táto inštrukcia zapisovala na túto adresu", čo je úplný popis problému. Ak je adresa malá (<code>0x00000008</code>), ide o <code>NULL</code> ukazovateľ na štruktúru a pristupujete k jej členu. Ak vyzerá ako dáta (<code>0x20000000</code> a o niečo viac), ide o zásobník alebo buffer, ktorý ste pretiahli.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bity-cfsr-s-ktorými-sa-stretnete">Bity CFSR, s ktorými sa stretnete<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#bity-cfsr-s-ktor%C3%BDmi-sa-stretnete" class="hash-link" aria-label="Priamy odkaz na Bity CFSR, s ktorými sa stretnete" title="Priamy odkaz na Bity CFSR, s ktorými sa stretnete" translate="no">​</a></h2>
<p>Register je kombináciou troch registrov (každý z nich má vlastný bajt alebo dva bajty). Toto sú tie, ktoré uvidíte najčastejšie (dva, ktoré som pozoroval v príkladoch, sú zvýraznené):</p>
















































































<table><thead><tr><th>Bit</th><th>Názov</th><th>Význam</th></tr></thead><tbody><tr><td>0</td><td><code>IACCVIOL</code></td><td>načítanie inštrukcie z oblasti, ktorá nie je povolená (MPU)</td></tr><tr><td>1</td><td><code>DACCVIOL</code></td><td>dátový prístup do oblasti, ktorá nie je povolená (MPU)</td></tr><tr><td>7</td><td><code>MMARVALID</code></td><td>register <code>MMFAR</code> obsahuje adresu</td></tr><tr><td>8</td><td><code>IBUSERR</code></td><td>chyba zbernice pri načítaní inštrukcie</td></tr><tr><td><strong>9</strong></td><td><strong><code>PRECISERR</code></strong></td><td><strong>presná chyba zbernice pri dátovom prístupe: <code>PC</code> je inštrukcia, ktorá ju spôsobila</strong></td></tr><tr><td>10</td><td><code>IMPRECISERR</code></td><td>nepresná chyba zbernice: inštrukcia je už preč, <code>PC</code> nie je spoľahlivý</td></tr><tr><td>11, 12</td><td><code>UNSTKERR</code>, <code>STKERR</code></td><td>chyba zbernice pri vyberaní alebo ukladaní registrov (často poškodený zásobník)</td></tr><tr><td><strong>15</strong></td><td><strong><code>BFARVALID</code></strong></td><td><strong>register <code>BFAR</code> obsahuje adresu</strong></td></tr><tr><td>16</td><td><code>UNDEFINSTR</code></td><td>nedefinovaná inštrukcia (vykonávanie dát, poškodený kód)</td></tr><tr><td><strong>17</strong></td><td><strong><code>INVSTATE</code></strong></td><td><strong>pokus o vykonávanie v stave ARM: skok na adresu s vynulovaným bitom 0</strong></td></tr><tr><td>18</td><td><code>INVPC</code></td><td>neplatný <code>EXC_RETURN</code> (poškodený zásobník výnimky)</td></tr><tr><td>19</td><td><code>NOCP</code></td><td>prístup ku koprocesoru, ktorý nie je povolený (typicky FPU, ktorá nebola zapnutá)</td></tr><tr><td>24</td><td><code>UNALIGNED</code></td><td>nezarovnaný prístup, keď je povolená pasca</td></tr><tr><td>25</td><td><code>DIVBYZERO</code></td><td>delenie nulou, keď je povolená pasca</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-zvyčajne-stojí-za-hardfaultom">Čo zvyčajne stojí za HardFaultom<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#%C4%8Do-zvy%C4%8Dajne-stoj%C3%AD-za-hardfaultom" class="hash-link" aria-label="Priamy odkaz na Čo zvyčajne stojí za HardFaultom" title="Priamy odkaz na Čo zvyčajne stojí za HardFaultom" translate="no">​</a></h2>

































<table><thead><tr><th>Čo vidíte</th><th>Čo to zvyčajne je</th></tr></thead><tbody><tr><td><code>PC = 0</code>, <code>INVSTATE</code></td><td>volanie cez <code>NULL</code> ukazovateľ na funkciu alebo návrat na poškodenú adresu</td></tr><tr><td><code>PRECISERR</code> a malé <code>BFAR</code></td><td><code>NULL</code> ukazovateľ na štruktúru</td></tr><tr><td><code>PRECISERR</code> a <code>BFAR</code> v rozsahu adries periférií</td><td>prístup k periférii, ktorá nie je dostupná, napríklad takej, ktorej hodiny neboli zapnuté (na niektorých rodinách je takýto prístup chybou zbernice, na iných sa potichu ignoruje)</td></tr><tr><td><code>STKERR</code> / <code>UNSTKERR</code> alebo <code>PC</code>, ktorý nedáva zmysel</td><td>pretečenie zásobníka alebo bufferu, ktoré poškodilo návratovú adresu</td></tr><tr><td><code>NOCP</code> pri prvej inštrukcii s pohyblivou desatinnou čiarkou</td><td>FPU nebola povolená v startup kóde</td></tr><tr><td><code>IMPRECISERR</code></td><td>zápis, ktorý prešiel cez write buffer: správa o poruche prichádza neskôr než inštrukcia. Na ladenie možno buffering vypnúť (bit <code>DISABLEDEFWRITEBUF</code> v <code>ACTLR</code>), takže porucha bude presná</td></tr></tbody></table>
<p>Prvý riadok tabuľky a princíp druhého (chyba zbernice s adresou v <code>BFAR</code>) som predviedol. Zvyšné riadky sú zhrnutím obvyklých príčin, vyplývajú z významu bitov v referenčnej príručke jadra.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-praxi">V praxi<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#v-praxi" class="hash-link" aria-label="Priamy odkaz na V praxi" title="Priamy odkaz na V praxi" translate="no">​</a></h2>
<ol>
<li class=""><strong>Nikdy nenechávajte predvolený handler ako prázdnu slučku.</strong> Handler vyššie má asi tridsať riadkov a mení poruchu na správu s miestom v kóde. Vložte ho raz do startup kódu projektu.</li>
<li class=""><strong>Uchovávajte ladiace informácie</strong> v súbore, ktorý archivujete s vydaním (<code>-g</code> a <code>.elf</code>), aby sa adresa zo správy z terénu dala premeniť na riadok, aj keď sa firmvér dodáva stripnutý. Je to ďalší dôvod pre <a class="" href="https://embedbits.cz/sk/blog/reproducible-builds-embedded">reprodukovateľný build</a>: adresa niečo znamená len pre presný binárny súbor, ktorý ju vytvoril.</li>
<li class=""><strong>Povoľte jemnejšie poruchy</strong> (bity v <code>SHCSR</code>), keď chcete samostatné handlery <code>UsageFault</code>, <code>BusFault</code> a <code>MemManage</code>. Správa je bohatšia, pretože stavové registre sa nezdieľajú.</li>
<li class=""><strong>Uložte správu do pamäte, ktorá prežije reset</strong> (sekcia, ktorú startup kód nemaže, pozrite článok o tom, <a class="" href="https://embedbits.cz/sk/blog/before-main-startup-linker">čo sa stane pred <code>main()</code></a>), resetujte a odošlite ju po reštarte. Správa zo zariadenia v teréne má väčšiu hodnotu než sto dohadov.</li>
<li class=""><strong>Predchádzajte tomu, čomu sa dá.</strong> Volanie <code>NULL</code> v príklade je chyba, ktorú by zachytili <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">pravidlá MISRA</a> a unit test modulu (ukazovateľ musí byť nastavený pred prvým volaním), a pretečenie zásobníka je vec, pri ktorej treba poznať využitie zásobníka (pravidlo proti rekurzii).</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rovnaká-session-na-doske">Rovnaká session na doske<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#rovnak%C3%A1-session-na-doske" class="hash-link" aria-label="Priamy odkaz na Rovnaká session na doske" title="Priamy odkaz na Rovnaká session na doske" translate="no">​</a></h2>
<p>Použil som QEMU, pretože nepotrebuje dosku, a jeho server GDB (<code>-S -gdb tcp::1234</code>) sa správa rovnako ako ten, ktorý poskytuje debug probe: príkazy v príkladoch sú príkazy, ktoré zadáte s probe. Platforma má artefakt pre sadu nástrojov <strong>probe-rs</strong> (ladiaca sada pre ARM ciele cez debug probe, so serverom DAP), čo je spôsob, ako pripojiť GDB alebo IDE ku skutočnej doske. Pre tento článok som ho nespúšťal, keďže vo svojom prostredí nemám probe.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="zhrnutie">Zhrnutie<a href="https://embedbits.cz/sk/blog/debugging-hardfault-cortex-m#zhrnutie" class="hash-link" aria-label="Priamy odkaz na Zhrnutie" title="Priamy odkaz na Zhrnutie" translate="no">​</a></h2>
<ol>
<li class="">HardFault nie je záhada: jadro uložilo registre a nastavilo stavové bity.</li>
<li class="">Handler musí nájsť správny zásobník (<code>EXC_RETURN</code>) a prečítať rámec, <code>CFSR</code>, <code>HFSR</code> a <code>BFAR</code>.</li>
<li class=""><code>PC</code> a <code>LR</code> dávajú miesto, <code>CFSR</code> dáva druh, <code>BFAR</code> dáva adresu.</li>
<li class=""><code>PC = 0</code> s <code>INVSTATE</code> je skok na <code>NULL</code> a bit <code>T</code> v <code>xPSR</code> to ukazuje.</li>
<li class="">Uchovajte si <code>.elf</code> a adresa z hlásenia z terénu sa zmení na riadok kódu.</li>
</ol>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>STM32</category>
        </item>
        <item>
            <title><![CDATA[Spustenie skutočného firmvéru bez hardvéru: simulátor v CI]]></title>
            <link>https://embedbits.cz/sk/blog/firmware-in-simulator-ci</link>
            <guid>https://embedbits.cz/sk/blog/firmware-in-simulator-ci</guid>
            <pubDate>Wed, 07 Oct 2026 18:00:00 GMT</pubDate>
            <description><![CDATA[V článku o unit testovaní s Unity a CMock som napísal, že testy na PC nenájdu „rozdiely medzi PC a MCU". Tento článok je o týchto rozdieloch a o nástroji, ktorý ich nájde: o simulátore, ktorý spúšťa skutočný binárny súbor. Nie logiku skompilovanú pre PC, ale ten istý .elf, ktorý vyrobil kompilátor ARM, so skutočným startup kódom a skutočným linker scriptom, na modeli procesora a jeho periférií.]]></description>
            <content:encoded><![CDATA[<p>V článku o <a class="" href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock">unit testovaní s Unity a CMock</a> som napísal, že testy na PC nenájdu „rozdiely medzi PC a MCU". Tento článok je o týchto rozdieloch a o nástroji, ktorý ich nájde: o <strong>simulátore, ktorý spúšťa skutočný binárny súbor</strong>. Nie logiku skompilovanú pre PC, ale ten istý <code>.elf</code>, ktorý vyrobil kompilátor ARM, so skutočným startup kódom a skutočným linker scriptom, na modeli procesora a jeho periférií.</p>
<p>Ukážem dva experimenty, ktoré som spustil: ten istý zdrojový kód testu, ktorý prejde na PC a zlyhá na Cortex-M4, a firmvér, ktorý zapisuje do registrov USART na skutočných adresách STM32F4 a ktorého text sa objaví v termináli. Na konci je úprimný zoznam toho, čo vám simulátor nepovie.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kde-to-zapadá">Kde to zapadá<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#kde-to-zapad%C3%A1" class="hash-link" aria-label="Priamy odkaz na Kde to zapadá" title="Priamy odkaz na Kde to zapadá" translate="no">​</a></h2>





























<table><thead><tr><th>Úroveň</th><th>Čo beží</th><th>Čo nájde</th><th>Rýchlosť</th></tr></thead><tbody><tr><td><strong>Unit test na PC</strong></td><td>logika skompilovaná pre PC, vrstvy pod ňou namockované</td><td>chyby v logike</td><td>milisekundy</td></tr><tr><td><strong>Simulátor</strong></td><td>skutočný binárny súbor firmvéru na modeli MCU</td><td>chyby špecifické pre cieľové zariadenie, startup, ovládače voči modelu registrov</td><td>sekundy</td></tr><tr><td><strong>Hardware in the loop</strong></td><td>skutočný firmvér na skutočnom MCU so skutočnými signálmi</td><td>časovanie, elektrické správanie, skutočné periférie</td><td>minúty, laboratórium</td></tr></tbody></table>
<p>Stredná úroveň je tá, ktorá sa vynecháva najčastejšie, a pritom je najlacnejšia na pridanie do CI, ktoré už firmvér zostavuje: simulátor je spustiteľný súbor, ktorému odovzdáte súbor, ktorý vyprodukoval váš build.</p>
<p>Nástrojom v mojich experimentoch je QEMU 8.2.2 so strojom <code>netduinoplus2</code>, modelom dosky s <strong>STM32F405</strong> (Cortex-M4 s pamäťovou mapou skutočného čipu: flash na <code>0x08000000</code>, RAM na <code>0x20000000</code>, periférie na ich skutočných adresách). Platforma má artefakt pre iný simulátor, <strong>Renode</strong>, a vrátim sa k nemu na konci.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="experiment-1-test-ktorý-prejde-na-pc-a-zlyhá-na-mcu">Experiment 1: test, ktorý prejde na PC a zlyhá na MCU<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#experiment-1-test-ktor%C3%BD-prejde-na-pc-a-zlyh%C3%A1-na-mcu" class="hash-link" aria-label="Priamy odkaz na Experiment 1: test, ktorý prejde na PC a zlyhá na MCU" title="Priamy odkaz na Experiment 1: test, ktorý prejde na PC a zlyhá na MCU" translate="no">​</a></h2>
<p>Malý modul s dvoma funkciami, ktoré má každý firmvér: prevod času a kontrola prijatého bajtu.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Conversions.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Conversions.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">long</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Get_Microseconds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> milliseconds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">long</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">milliseconds </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1000L</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Is_HighBitSet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> receivedByte</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">receivedByte </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Obe funkcie vyzerajú správne a obe sú otestované na PC. Zdrojový kód testu je pre oba ciele rovnaký: líši sa len výstup. Súbor <code>Platform.h</code> tlačí cez <code>printf</code> na PC a cez <em>semihosting</em> (požiadavku na simulátor alebo debugger) na cieľovom zariadení a návratový kód testu hovorí, či prešiel:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Platform.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">PLATFORM_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">PLATFORM_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The same test source runs on the PC and on the target: only the output differs. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">if</span><span class="token macro property"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">defined</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">__arm__</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Semihost_Call</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> operation</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">argument</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">register</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">int</span><span class="token plain">   r0 </span><span class="token function" style="color:rgb(130, 170, 255)">__asm__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"r0"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> operation</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">register</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">r1 </span><span class="token function" style="color:rgb(130, 170, 255)">__asm__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"r1"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> argument</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        __asm__ </span><span class="token keyword" style="font-style:italic">volatile</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"bkpt 0xAB"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"+r"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">r0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"r"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">r1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"memory"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> r0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Platform_Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">Semihost_Call</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0x04</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Platform_Exit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> failures</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 0x20026: the application exited normally, 0x20023: the application failed */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">Semihost_Call</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0x18</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> failures </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0x20026u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0x20023u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdio.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdlib.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Platform_Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">fputs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">stdout</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Platform_Exit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> failures</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">exit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> failures </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">tests.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Conversions.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Platform.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> failures</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name function" style="color:rgb(130, 170, 255)">CHECK</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">condition</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token macro property expression"> name</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">                                          </span><span class="token macro property punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token macro property"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token macro property">    </span><span class="token macro property expression keyword" style="font-style:italic">do</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token macro property expression">                                                                </span><span class="token macro property punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token macro property"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token macro property">        </span><span class="token macro property expression keyword" style="font-style:italic">if</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">condition</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token macro property expression"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">Platform_Print</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property string" style="color:rgb(195, 232, 141)">"PASS  "</span><span class="token macro property"> </span><span class="token macro property expression">name </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"\n"</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token macro property expression">          </span><span class="token macro property punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token macro property"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token macro property">        </span><span class="token macro property expression keyword" style="font-style:italic">else</span><span class="token macro property expression">           </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token macro property expression"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">Platform_Print</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property string" style="color:rgb(195, 232, 141)">"FAIL  "</span><span class="token macro property"> </span><span class="token macro property expression">name </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"\n"</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token macro property expression"> failures</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">++</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token macro property expression"> </span><span class="token macro property punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token macro property"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token macro property">    </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token macro property expression"> </span><span class="token macro property expression keyword" style="font-style:italic">while</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 3 000 000 ms = 50 minutes = 3 000 000 000 us */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">CHECK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">3000000000L</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Get_Microseconds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">3000000u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"50 minutes in microseconds"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">CHECK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">5000L</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Get_Microseconds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">5u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">             </span><span class="token string" style="color:rgb(195, 232, 141)">"5 ms in microseconds"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* the byte 0xFF is received from the UART */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">CHECK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Is_HighBitSet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">char</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token number" style="color:rgb(247, 140, 108)">0xFF</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">         </span><span class="token string" style="color:rgb(195, 232, 141)">"0xFF has the high bit set"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">CHECK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Is_HighBitSet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">char</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token number" style="color:rgb(247, 140, 108)">0x41</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"'A' has not the high bit set"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Platform_Exit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">failures</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> failures</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Na PC:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  50 minutes in microseconds</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  5 ms in microseconds</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  0xFF has the high bit set</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  'A' has not the high bit set</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">exit code: 0</span><br></div></code></pre></div></div>
<p>Ten istý zdrojový kód, skompilovaný pomocou <code>arm-none-eabi-gcc</code> pre Cortex-M4 a spustený v QEMU:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">FAIL  50 minutes in microseconds</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  5 ms in microseconds</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">FAIL  0xFF has the high bit set</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">PASS  'A' has not the high bit set</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">exit code: 1</span><br></div></code></pre></div></div>
<p>Dve chyby, obe na PC neviditeľné:</p>
<ul>
<li class=""><strong><code>long</code> má inú šírku.</strong> Na 64-bitovom Linuxe na PC má <code>long</code> 64 bitov, na Cortex-M má 32. <code>3 000 000 ms * 1000</code> je <code>3 000 000 000</code>, čo sa nezmestí do 32-bitového čísla so znamienkom (najväčšie je 2 147 483 647), takže výsledok je nesprávny a v C ide navyše o nedefinované správanie.</li>
<li class=""><strong><code>char</code> má iné znamienko.</strong> Norma C necháva otvorené, či je obyčajný <code>char</code> so znamienkom. Na x86 je, takže <code>(char)0xFF</code> je <code>-1</code> a kontrola <code>receivedByte &lt; 0</code> funguje. Na ARM je <em>bez znamienka</em>, takže <code>(char)0xFF</code> je <code>255</code> a porovnanie nikdy nie je pravdivé. Kompilátor ARM to dokonca povie, a len tam:</li>
</ul>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Conversions.c:10:26: warning: comparison is always false due to limited range of data type [-Wtype-limits]</span><br></div></code></pre></div></div>
<p>Obe sú otázkou prenosných typov, čo je téma pravidla 4.6 v článku o <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">MISRA</a>: používajte typy s veľkosťou a znamienkom. Opravená verzia používa <code>uint64_t</code> pre čas a <code>uint8_t</code> pre bajt:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint64_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Get_Microseconds_Fixed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> milliseconds</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint64_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">milliseconds </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1000u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Conversions_Is_HighBitSet_Fixed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> receivedByte</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">receivedByte </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0x80u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>a tie isté štyri kontroly teraz prejdú <strong>na oboch cieľoch</strong>, s návratovým kódom 0 na oboch. Prvá verzia nebola chybou testu a test na PC nebol nesprávny: jednoducho testoval iný program.</p>
<p>Návratový kód je celá integrácia s CI. Simulátor skončí s kódom, ktorý firmvér odovzdá volaniu semihostingu, takže <code>add_test</code> v CMake (pozrite článok o <a class="" href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware">CMake pre firmvér</a>) zlyhá, keď zlyhá test na cieľovom zariadení:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">add_test</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">NAME</span><span class="token plain"> conversions_on_target</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND qemu-system-arm -M netduinoplus2 -nographic</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            -semihosting-config enable=on,target=native -kernel conversions_test.elf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="experiment-2-registre-periférie">Experiment 2: registre periférie<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#experiment-2-registre-perif%C3%A9rie" class="hash-link" aria-label="Priamy odkaz na Experiment 2: registre periférie" title="Priamy odkaz na Experiment 2: registre periférie" translate="no">​</a></h2>
<p>Simulátor modeluje aj periférie, a tak môže bežať aj kód najbližší k hardvéru. Toto je firmvér, ktorý posiela text cez USART1 na STM32F4, napísaný na úrovni registrov so skutočnými adresami (žiadna knižnica, žiadny startup nad rámec kódu z článku o tom, <a class="" href="https://embedbits.cz/sk/blog/before-main-startup-linker">čo sa stane pred <code>main()</code></a>):</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">uart.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* STM32F4: RCC and USART1 registers, the same addresses as on the real chip */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">RCC_APB2ENR</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0x40023844u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART1_SR</span><span class="token macro property">    </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0x40011000u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART1_DR</span><span class="token macro property">    </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0x40011004u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART1_CR1</span><span class="token macro property">   </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression keyword" style="font-style:italic">volatile</span><span class="token macro property expression"> </span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0x4001100Cu</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">RCC_APB2ENR_USART1EN</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">1u</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">4</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART_CR1_UE</span><span class="token macro property">          </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">1u</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">13</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART_CR1_TE</span><span class="token macro property">          </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">1u</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">3</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">USART_SR_TXE</span><span class="token macro property">          </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">1u</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">7</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token char" style="color:rgb(130, 170, 255)">'\0'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">USART1_SR </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> USART_SR_TXE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* wait until the data register is empty */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        USART1_DR </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">unsigned</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    RCC_APB2ENR </span><span class="token operator" style="color:rgb(137, 221, 255)">|=</span><span class="token plain"> RCC_APB2ENR_USART1EN</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* clock of the peripheral */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    USART1_CR1  </span><span class="token operator" style="color:rgb(137, 221, 255)">|=</span><span class="token plain"> USART_CR1_UE </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> USART_CR1_TE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">           </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* enable the USART and its transmitter */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"hello from the register level\r\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">hello from the register level</span><br></div></code></pre></div></div>
<p>Text je v termináli simulátora: firmvér zapol hodiny periférie v RCC, povolil USART a jeho vysielač, počkal na príznak <code>TXE</code> a zapísal do dátového registra, presne tak, ako by to urobil na doske, a model USART odovzdal bajt sériovému portu. Je to test ovládača voči modelu registrového rozhrania. Ak ovládač čaká na príznak, ktorý nikdy nepríde, test to nájde pomocou timeoutu, a nie pri stole s osciloskopom.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-vám-simulátor-nepovie">Čo vám simulátor nepovie<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#%C4%8Do-v%C3%A1m-simul%C3%A1tor-nepovie" class="hash-link" aria-label="Priamy odkaz na Čo vám simulátor nepovie" title="Priamy odkaz na Čo vám simulátor nepovie" translate="no">​</a></h2>
<p>Simulátor je <em>model</em> a každý model má hranicu. Niekoľko, na ktoré som narazil v experimentoch tejto série:</p>
<ul>
<li class=""><strong>Časovanie nie je skutočné.</strong> QEMU vykonáva inštrukcie tak rýchlo, ako dovolí PC, a nepočíta cykly skutočného jadra. Test, ktorý má dokázať „prerušenie sa obslúži do 5 mikrosekúnd", sa v ňom urobiť nedá.</li>
<li class=""><strong>Prerušenia prichádzajú na iných miestach než na MCU.</strong> V článku o <a class="" href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data">prerušeniach</a> sa stratená aktualizácia zdieľaného počítadla v QEMU neobjavila ani v 200 000 pokusoch, pretože QEMU doručuje prerušenie medzi blokmi preloženého kódu. Skutočné MCU môže prerušiť po každej inštrukcii. Simulátor nedokazuje neprítomnosť race condition.</li>
<li class=""><strong>Existujú len namodelované periférie.</strong> Model STM32F405 má USART, ale iný čip môže mať perifériu, ktorú model nemá, alebo ju má v zjednodušenej podobe: registre tam sú, analógová časť nie.</li>
<li class=""><strong>Chýba elektrický svet:</strong> zákmity kontaktu, šum na vstupe ADC, pokles napätia. Všetko, čo prichádza zvonku, je to, čo do modelu vložíte.</li>
</ul>
<p>Simulátor teda nenahrádza ani unit testy (sú rýchlejšie a testujú logiku izolovane), ani hardvérové testy (testujú realitu). Nájde veci medzi nimi: kompilátor cieľového zariadenia, typy, startup, pamäťovú mapu, ovládač voči modelu registrov, a robí to za pár sekúnd pri každom commite.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="renode">Renode<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#renode" class="hash-link" aria-label="Priamy odkaz na Renode" title="Priamy odkaz na Renode" translate="no">​</a></h2>
<p>Platforma má artefakt pre <strong>Renode</strong>, open-source simulačný a virtuálny vývojový framework od Antmicro, dodávaný spolu s <code>renode-test</code>, jeho testovacím runnerom založeným na Robot Framework, ktorý sa používa na integračné testy simulovaného firmvéru. Pre tento článok som ho nespúšťal (vydanie sa v mojom prostredí nedalo stiahnuť), takže iba opakujem, čo hovorí jeho dokumentácia, a neporovnávam ho s QEMU. Štruktúra takéhoto testu je rovnaká ako vyššie: skutočný ELF, model hardvéru, verdikt a návratový kód pre CI.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kontrolný-zoznam">Kontrolný zoznam<a href="https://embedbits.cz/sk/blog/firmware-in-simulator-ci#kontroln%C3%BD-zoznam" class="hash-link" aria-label="Priamy odkaz na Kontrolný zoznam" title="Priamy odkaz na Kontrolný zoznam" translate="no">​</a></h2>
<ol>
<li class="">Zostavte test pre <strong>cieľové zariadenie</strong>, kompilátorom cieľového zariadenia, a spustite ho v simulátore, popri PC.</li>
<li class="">Použite jeden zdrojový kód testu pre oba, s tenkou vrstvou (<code>Platform.h</code>) pre výstup a ukončenie.</li>
<li class="">Návratový kód simulátora je výsledok testu, takže CI nepotrebuje nič viac.</li>
<li class="">Používajte typy s veľkosťou a znamienkom (<code>uint32_t</code>, <code>uint8_t</code>) a varovania kompilátora cieľového zariadenia: druhú chybu vyššie (<code>char</code>) by našlo <code>-Wtype-limits</code>, keby sa niekto pozrel na výstup buildu pre ARM.</li>
<li class="">Zapíšte si, čo simulátor nevie dokázať (časovanie, race condition, analógový svet), a nechajte to na hardvérové testy.</li>
</ol>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>Testovanie</category>
        </item>
        <item>
            <title><![CDATA[Reprodukovateľné buildy: pripnite nástroje, pripnite zdrojáky, odstráňte hodiny]]></title>
            <link>https://embedbits.cz/sk/blog/reproducible-builds-embedded</link>
            <guid>https://embedbits.cz/sk/blog/reproducible-builds-embedded</guid>
            <pubDate>Wed, 07 Oct 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[Zákazník volá kvôli firmvéru, ktorý ste dodali pred štrnástimi mesiacmi. Checkoutnete tag, zostavíte ho, nahráte a chyba tam nie je. Zmizla chyba, alebo je to iný firmvér? Ak váš build nie je reprodukovateľný, nemôžete to povedať. Nemôže to povedať nikto, pretože binárka, ktorú ste práve zostavili, sa líši od dodanej spôsobmi, ktoré nevidíte ani nedokážete vysvetliť: iná verzia kompilátora, knižnica aktualizovaná na PC, cesta k priečinku, denná doba.]]></description>
            <content:encoded><![CDATA[<p>Zákazník volá kvôli firmvéru, ktorý ste dodali pred štrnástimi mesiacmi. Checkoutnete tag, zostavíte ho, nahráte a chyba tam nie je. Zmizla chyba, alebo je to iný firmvér? Ak váš build nie je <strong>reprodukovateľný</strong>, nemôžete to povedať. Nemôže to povedať nikto, pretože binárka, ktorú ste práve zostavili, sa líši od dodanej spôsobmi, ktoré nevidíte ani nedokážete vysvetliť: iná verzia kompilátora, knižnica aktualizovaná na PC, cesta k priečinku, denná doba.</p>
<p>Reprodukovateľný build má jednoduchú definíciu: <strong>rovnaké vstupy dajú rovnaké bajty</strong>. Tento článok ukazuje, aké sú vstupy buildu firmvéru, ako ich platforma Embedbits pripína (Artifacts Handler) a experiment, ktorý som urobil: dva buildy toho istého zdrojáka v dvoch priečinkoch v dvoch rôznych časoch dajú dve rôzne binárky. Potom o tri zmeny neskôr dajú tú istú, až na posledný bit.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="vstupy-buildu">Vstupy buildu<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#vstupy-buildu" class="hash-link" aria-label="Priamy odkaz na Vstupy buildu" title="Priamy odkaz na Vstupy buildu" translate="no">​</a></h2>
<p>Build je funkcia. Čo do nej vstupuje?</p>



































<table><thead><tr><th>Vstup</th><th>Odkiaľ pochádza</th><th>Ako ho pripnúť</th></tr></thead><tbody><tr><td><strong>Zdroják</strong></td><td>Git</td><td>tag alebo commit, submoduly pripnuté svojimi commitmi</td></tr><tr><td><strong>Nástroje</strong> (kompilátor, linker, Ninja, Doxygen)</td><td>nainštalované na PC alebo stiahnuté</td><td>presné verzie z jedného zdroja</td></tr><tr><td><strong>Popis buildu</strong> (flagy, linker script)</td><td>súbory CMake</td><td>v repozitári, nič nenastavené ručne</td></tr><tr><td><strong>Skripty platformy</strong></td><td>submodul EmBi_Platform</td><td>commit submodulu, aktualizovaný nástrojom Updater, zámerne</td></tr><tr><td><strong>Prostredie</strong></td><td>PC</td><td>nič vo výstupe by na ňom nemalo závisieť: cesta, čas, meno používateľa</td></tr></tbody></table>
<p>Prvý, tretí a štvrtý sú v Gite, takže sú pripnuté už návrhom. Nástroje a prostredie sú miesta, kde sa build zvyčajne rozpadne, a každé z nich má vlastnú odpoveď.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="nástroje-artifacts-handler">Nástroje: Artifacts Handler<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#n%C3%A1stroje-artifacts-handler" class="hash-link" aria-label="Priamy odkaz na Nástroje: Artifacts Handler" title="Priamy odkaz na Nástroje: Artifacts Handler" translate="no">​</a></h2>
<p>„Nainštalujte GCC 13.2 a Ninja 1.12“ v README je veta, ktorú nikto nedodrží do písmena. Platforma to rieši tak, že z nástrojov urobí súčasť projektu. Artifacts Handler je skript CMake, ktorý zo súboru <code>ArtifactsConfig.txt</code> číta zoznam nástrojov a ich verzií a pripravuje ich. Jeho dokumentácia hovorí, že jediný softvér, ktorý používateľ potrebuje, je Git a CMake a každú ďalšiu súčasť buildu dodá handler. V krokoch:</p>
<ol>
<li class=""><strong>Naklonuje</strong> koreňový repozitár artefaktov (bez submodulov, aby sa ušetrila prevádzka).</li>
<li class=""><strong>Nájde</strong> v ňom artefakt (každý nástroj je submodul, názvy sa porovnávajú bez ohľadu na veľkosť písmen).</li>
<li class=""><strong>Checkoutne</strong> požadovanú verziu (plytký klon, <code>--depth=1</code>). Vydania sú označené verziou a operačným systémom (<code>Win</code>, <code>Unix</code>, <code>DarwinARM</code>).</li>
<li class=""><strong>Nainštaluje</strong> ho: rozbalí archív do priečinka cache.</li>
<li class=""><strong>Inicializuje</strong> ho: vo väčšine prípadov dá priečinok nástroja na <em>začiatok</em> <code>PATH</code>, takže projektový nástroj vyhrá nad akýmkoľvek nástrojom nainštalovaným v systéme.</li>
</ol>
<p>Konfigurácia má jeden riadok pre každý nástroj, <code>name;version;handler version</code>, napríklad riadky z dokumentácie platformy:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">ninja;1.12.1;1</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">gcc-arm-none-eabi;13.2.rel1;2</span><br></div></code></pre></div></div>
<p>Prvé číslo je verzia samotného nástroja (<em>binárky</em>), druhé je verzia handler skriptu daného artefaktu (môže sa meniť nezávisle, napríklad keď sa opraví spôsob nastavenia <code>PATH</code>). Cache má jeden priečinok na nástroj a verziu, takže viaceré verzie žijú vedľa seba a projekt, ktorý potrebuje staršiu, neruší projekt, ktorý potrebuje novšiu.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="prečo-nie-latest">Prečo nie <code>latest</code><a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#pre%C4%8Do-nie-latest" class="hash-link" aria-label="Priamy odkaz na prečo-nie-latest" title="Priamy odkaz na prečo-nie-latest" translate="no">​</a></h3>
<p>Handler akceptuje aj <code>latest</code> namiesto čísla. Je to pohodlné a rozbíja to celú myšlienku. Spustil som handler s riadkom <code>ninja;latest;latest</code> a vypísal, na čo to 5. októbra 2026 rozlíšil:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">-- Processing artifact ninja with Bin version latest and Core version latest.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">-- The version 1.0.0 of artifacts Core part will be used.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">-- The version 1.13.2 of artifacts Bin part will be used.</span><br></div></code></pre></div></div>
<p>(Beh sa zastavil pri sťahovaní vydania, pretože moje prostredie sa nedokáže dostať k GitHub API, ale rozlíšenie prebehlo.) <code>latest</code> je <strong>pohyblivý cieľ</strong>: podľa dokumentácie sa zoznam verzií sťahuje raz za deň, takže ten istý súbor dá dnes 1.13.2 a po ďalšom vydaní niečo iné. Build, ktorý je dnes správny, môže byť zajtra iný build a nič vo vašom repozitári to nepovie. Pravidlo je preto jednoduché: <strong><code>latest</code> je na vyskúšanie novej verzie a vydaný projekt pripína každé číslo.</strong></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ďalšie-nastavenia-ktoré-pomáhajú">Ďalšie nastavenia, ktoré pomáhajú<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#%C4%8Fal%C5%A1ie-nastavenia-ktor%C3%A9-pom%C3%A1haj%C3%BA" class="hash-link" aria-label="Priamy odkaz na Ďalšie nastavenia, ktoré pomáhajú" title="Priamy odkaz na Ďalšie nastavenia, ktoré pomáhajú" translate="no">​</a></h3>
<ul>
<li class=""><strong>Offline režim</strong> (<code>-DOFFLINE_MODE=true</code>): kontroluje sa len lokálna cache a nič sa nesťahuje. Je to spôsob, ako dokázať, že build nezávisí od siete, a spôsob, ako zostavovať na mieste, kde sieť nie je.</li>
<li class=""><strong>Umiestnenie cache</strong> (<code>ARTIFACTS_HANDLER_CACHE_PATH</code>) a <strong>koreňového repozitára</strong> (<code>ARTIFACTS_HANDLER_ROOT_REPO_URL</code>) sa dajú nastaviť v konfiguračnom súbore, v prostredí alebo na príkazovom riadku. Firma môže prevádzkovať vlastné zrkadlo artefaktov, takže build nezávisí ani od verejného servera.</li>
<li class=""><strong>Kontrolný súčet.</strong> Každé vydanie artefaktu sa publikuje so súborom SHA-256 vedľa archívu, takže poškodený alebo vymenený súbor sa neprijme potichu.</li>
</ul>
<p>Nástroje sú prvá polovica odpovede. Druhá polovica je niečo, čo si môžete overiť sami, príkazom nižšie.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prostredie-experiment">Prostredie: experiment<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#prostredie-experiment" class="hash-link" aria-label="Priamy odkaz na Prostredie: experiment" title="Priamy odkaz na Prostredie: experiment" translate="no">​</a></h2>
<p>Vzal som príkladový projekt z článku o <a class="" href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware">CMake</a> a pridal súbor, ktorý má väčšina firmvérov v nejakej podobe: <strong>informácie o builde</strong>. Ukladá čas buildu a cestu zdrojového súboru, pretože niekto kedysi chcel v debuggeri vidieť „kedy sa to zostavilo“:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> buildFile</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">__FILE__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> buildTime</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">__DATE__</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">" "</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">__TIME__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Potom som ten istý zdroják zostavil dvakrát: v dvoch rôznych priečinkoch (<code>a</code> a <code>b</code>), druhý o tri sekundy neskôr. Príkaz <code>strings</code> aplikovaný na obe binárky ukazuje, čo je vnútri:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Oct  5 2026 15:46:02</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">/tmp/.../repro/a/Application/BuildInfo.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">---</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Oct  5 2026 15:46:05</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">/tmp/.../repro/b/Application/BuildInfo.c</span><br></div></code></pre></div></div>
<p>a SHA-256 oboch súborov <code>firmware.bin</code> sa líši:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">f2366319462b6fee...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">d634c24c3c431799...</span><br></div></code></pre></div></div>
<p>Dva buildy jedného zdrojáka, dve rôzne binárky. Čas je zrejmý, ale <strong>cesta</strong> je tá, na ktorú ľudia zabúdajú: <code>__FILE__</code> (a tiež <code>assert()</code> a ladiace informácie) zapisuje do programu plnú cestu k súboru a cesta je iná na PC každého vývojára a v každej úlohe CI. Binárka zostavená v <code>/home/anna/project</code> a tá istá zostavená v <code>/builds/job-4711/project</code> sú dva rôzne súbory.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="tri-zmeny">Tri zmeny<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#tri-zmeny" class="hash-link" aria-label="Priamy odkaz na Tri zmeny" title="Priamy odkaz na Tri zmeny" translate="no">​</a></h3>
<p><strong>1. Odstráňte hodiny.</strong> Makrá <code>__DATE__</code> a <code>__TIME__</code> nemajú miesto vo firmvéri, ktorý má byť reprodukovateľný. Kompilátor to dokáže vynútiť, takže ich nikto omylom nepridá späť:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">BuildInfo.c:5:26: error: macro "__DATE__" might prevent reproducible builds [-Werror=date-time]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">BuildInfo.c:5:39: error: macro "__TIME__" might prevent reproducible builds [-Werror=date-time]</span><br></div></code></pre></div></div>
<p><strong>2. Verzia je vstup.</strong> Ak chcete vedieť „čo je tento firmvér“, build dostane odpoveď zvonka: verziu, tag alebo hash commitu, ktoré build systém odovzdá ako definíciu. Ten istý zdroják má rovnakú verziu, teda rovnaké bajty:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">BUILD_VERSION</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">BUILD_VERSION</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"unknown"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> buildVersion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUILD_VERSION</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>3. Odstráňte cesty.</strong> Voľba <code>-ffile-prefix-map=OLD=NEW</code> nahradí prefix každej cesty, ktorú GCC vkladá do výstupu (<code>__FILE__</code>, ladiace informácie, aserty). Zdrojový priečinok projektu sa nahradí bodkou:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">CMakeLists.txt (a part)</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The version of the firmware is an input of the build, not the time of the build.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">FIRMWARE_VERSION</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"1.2.3"</span><span class="token plain"> </span><span class="token variable" style="color:rgb(191, 199, 213)">CACHE</span><span class="token plain"> STRING </span><span class="token string" style="color:rgb(195, 232, 141)">"Version of the firmware"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_compile_definitions</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">BUILD_VERSION</span><span class="token plain">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string interpolation punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token string interpolation variable" style="color:rgb(191, 199, 213)">FIRMWARE_VERSION</span><span class="token string interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># No clock in the binary, and no path of this PC in it.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MCU_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">WARNING_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">BUILD_OPTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                    -Wdate-time -Werror=date-time</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                    -ffile-prefix-map=</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">=.</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>S týmito tromi zmenami dá rovnaká kontrola:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">first : 1bedc9d2b1d78452a77fa3440851d5ed3d9f6568d96edd4c4a18be3b828dc313</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">second: 1bedc9d2b1d78452a77fa3440851d5ed3d9f6568d96edd4c4a18be3b828dc313</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">REPRODUCIBLE</span><br></div></code></pre></div></div>
<p><code>.bin</code> je identický a rovnako aj <code>.elf</code>, vo vydaní (<code>-Os -g0</code>) aj v debug builde (<code>-Og -g3</code>), ktorého ladiace informácie sú plné ciest. S <code>-ffile-prefix-map</code> ukáže <code>strings</code> binárky <code>./Application/BuildInfo.c</code> a verziu <code>1.2.3</code> a nič o PC, ktoré ju zostavilo.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="test-ktorý-nikdy-nezostarne">Test, ktorý nikdy nezostarne<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#test-ktor%C3%BD-nikdy-nezostarne" class="hash-link" aria-label="Priamy odkaz na Test, ktorý nikdy nezostarne" title="Priamy odkaz na Test, ktorý nikdy nezostarne" translate="no">​</a></h2>
<p>Nestačí urobiť build reprodukovateľným raz, pretože prvé <code>__TIME__</code>, ktoré niekto pridá, ho zničí. Urobte z toho preto <strong>test</strong>: zostavte zdroják dvakrát a porovnajte. Toto je skript, ktorý som použil na čísla vyššie; skopíruje projekt do dvoch priečinkov, oba zostaví s pauzou medzi nimi a porovná SHA-256:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">check-reproducible.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token shebang important">#!/usr/bin/env bash</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Builds the same source twice, in two different folders, and compares the firmware.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">set</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-euo</span><span class="token plain"> pipefail</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">source_dir</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable builtin class-name" style="color:rgb(255, 203, 107)">cd</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$1</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable builtin class-name" style="color:rgb(255, 203, 107)">pwd</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">config</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">${2</span><span class="token string variable operator" style="color:rgb(137, 221, 255)">:-</span><span class="token string variable" style="color:rgb(191, 199, 213)">Release}</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">work</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable" style="color:rgb(191, 199, 213)">mktemp </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-d</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token for-or-select variable" style="color:rgb(191, 199, 213)">copy</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> first second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">do</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">cp</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-r</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$source_dir</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$copy</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">rm</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-rf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$copy</span><span class="token string" style="color:rgb(195, 232, 141)">/build"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-S</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$copy</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-B</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$copy</span><span class="token string" style="color:rgb(195, 232, 141)">/build"</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-G</span><span class="token plain"> Ninja </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">          </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DCMAKE_TOOLCHAIN_FILE</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">cmake/arm-none-eabi.cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DCMAKE_BUILD_TYPE</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$config</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> /dev/null</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--build</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$copy</span><span class="token string" style="color:rgb(195, 232, 141)">/build"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> /dev/null</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">sleep</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token plain">                                    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># the second build is later and is in another folder</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">done</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">first</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable" style="color:rgb(191, 199, 213)">sha256sum </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string variable string" style="color:rgb(195, 232, 141)">/first/build/firmware.bin"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">|</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable function" style="color:rgb(130, 170, 255)">cut</span><span class="token string variable" style="color:rgb(191, 199, 213)"> -d</span><span class="token string variable string" style="color:rgb(195, 232, 141)">' '</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-f1</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">second</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable" style="color:rgb(191, 199, 213)">sha256sum </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string variable string" style="color:rgb(195, 232, 141)">/second/build/firmware.bin"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">|</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable function" style="color:rgb(130, 170, 255)">cut</span><span class="token string variable" style="color:rgb(191, 199, 213)"> -d</span><span class="token string variable string" style="color:rgb(195, 232, 141)">' '</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-f1</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"first : </span><span class="token string variable" style="color:rgb(191, 199, 213)">$first</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"second: </span><span class="token string variable" style="color:rgb(191, 199, 213)">$second</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$first</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$second</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">then</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"REPRODUCIBLE"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"NOT REPRODUCIBLE"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">fi</span><br></div></code></pre></div></div>
<p>Spúšťaný v CI pri každom merge je strážcom. Použil som ho aj na pokazenú verziu informácií o builde, aby som si bol istý, že dokáže zlyhať, a zlyhal (<code>NOT REPRODUCIBLE</code>, návratový kód 1, dva rôzne hashe). Test, ktorý nikdy nezlyhal, je test, ktorý nepoznáte.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-ešte-rozbíja-reprodukovateľný-build">Čo ešte rozbíja reprodukovateľný build<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#%C4%8Do-e%C5%A1te-rozb%C3%ADja-reprodukovate%C4%BEn%C3%BD-build" class="hash-link" aria-label="Priamy odkaz na Čo ešte rozbíja reprodukovateľný build" title="Priamy odkaz na Čo ešte rozbíja reprodukovateľný build" translate="no">​</a></h2>
<p>Otestoval som tri veci vyššie. Nasledujúce sú ďalšie známe zdroje problémov, na ktoré treba pamätať (v príklade som ich nepotreboval, takže ich len pomenúvam):</p>
<ul>
<li class=""><strong>Poradie súborov</strong>, ktoré pochádza z <code>file(GLOB ...)</code> alebo z výpisu adresára. Zdroje by sa mali uvádzať explicitne, ako v súboroch CMake modulov platformy.</li>
<li class=""><strong>Časová pečiatka v archíve</strong> (statická knižnica vytvorená cez <code>ar</code>). Moderné verzie nástrojov majú deterministický režim, ale starý toolchain ho mať nemusí.</li>
<li class=""><strong>Generovaný kód.</strong> Mocky a runnery unit testov alebo linker script generovaný pre MCU sa musia generovať rovnako z rovnakých vstupov. Pravidlami sú triedenie a žiadne časové pečiatky vo výstupe.</li>
<li class=""><strong>Samotný kompilátor.</strong> Tá istá verzia toho istého kompilátora z dvoch zdrojov (balík distribúcie a archív od výrobcu) sa môže líšiť v knižniciach, ktoré linkuje. To je dôvod, prečo brať kompilátor z jedného miesta, čo je celý zmysel artefaktov.</li>
<li class=""><strong>Build s iným počtom vlákien.</strong> Správny build systém dá rovnaký výsledok s <code>-j1</code> aj <code>-j16</code> a test na to je lacným doplnkom k tomu vyššie.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kontrolný-zoznam">Kontrolný zoznam<a href="https://embedbits.cz/sk/blog/reproducible-builds-embedded#kontroln%C3%BD-zoznam" class="hash-link" aria-label="Priamy odkaz na Kontrolný zoznam" title="Priamy odkaz na Kontrolný zoznam" translate="no">​</a></h2>
<ol>
<li class="">Každý nástroj je v <code>ArtifactsConfig.txt</code> pripnutý na presnú verziu. Žiadne <code>latest</code> vo vydaní.</li>
<li class="">Submoduly (BSP, platforma) sú pripnuté commitmi a aktualizácia je viditeľný commit.</li>
<li class="">Nič vo firmvéri nezávisí od času ani cesty: <code>-Werror=date-time</code>, <code>-ffile-prefix-map</code>.</li>
<li class="">Verzia je parametrom buildu, odvodená z tagu, a je uložená vo firmvéri.</li>
<li class="">CI zostavuje dvakrát a porovnáva. Občas tiež zostavuje offline, z cache.</li>
<li class="">Dodaná binárka sa ukladá spolu so svojím SHA-256 a tagom, takže „je to ten istý súbor“ má odpoveď bez nového buildu.</li>
</ol>
<p>Odmenou je veta, ktorú použijete do telefónu so zákazníkom: <em>„Zostavil som presne váš firmvér a chyba v ňom (nie) je.“</em></p>]]></content:encoded>
            <category>Embedded</category>
            <category>CMake</category>
            <category>Architektúra</category>
        </item>
        <item>
            <title><![CDATA[Návrh API periférie: osem rozhodnutí za modulom Gpio]]></title>
            <link>https://embedbits.cz/sk/blog/designing-peripheral-api-gpio</link>
            <guid>https://embedbits.cz/sk/blog/designing-peripheral-api-gpio</guid>
            <pubDate>Wed, 07 Oct 2026 10:00:00 GMT</pubDate>
            <description><![CDATA[GPIO je najjednoduchšia periféria mikrokontroléra ako sa pomenuje pin, čo funkcia vracia, kde žije polarita LED. MCAL modul Gpio z Embedbits BSP je skutočný príklad so skutočnými odpoveďami a prejdem ich jednu po druhej, aj s alternatívami a cenou.]]></description>
            <content:encoded><![CDATA[<p>GPIO je najjednoduchšia periféria mikrokontroléra: pin je high alebo low. Presne preto je dobrým námetom na článok o <strong>návrhu rozhrania</strong>. Nie je tu žiadna hardvérová zložitosť, za ktorou by sa dalo schovať, a každé rozhodnutie je voľbou návrhára: ako sa pomenuje pin, čo funkcia vracia, kde žije polarita LED. MCAL modul <code>Gpio</code> z Embedbits BSP je skutočný príklad so skutočnými odpoveďami a prejdem ich jednu po druhej, aj s alternatívami a cenou.</p>
<p>Kód z modulu je citovaný z vetvy STM32H5 repozitára <a href="https://github.com/Embedbits/Bsp-Mcal-Gpio" target="_blank" rel="noopener noreferrer" class="">Bsp-Mcal-Gpio</a>. Príklady, ktoré ho používajú, som skompiloval a spustil proti <strong>skutočným</strong> <code>Gpio_Port.h</code> a <code>Gpio_Types.h</code>, s malým fake implementácie, aby sa API dalo vyskúšať na PC.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="celé-rozhranie-na-jednej-obrazovke">Celé rozhranie na jednej obrazovke<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#cel%C3%A9-rozhranie-na-jednej-obrazovke" class="hash-link" aria-label="Priamy odkaz na Celé rozhranie na jednej obrazovke" title="Priamy odkaz na Celé rozhranie na jednej obrazovke" translate="no">​</a></h2>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_ModuleVersion_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_ModuleVersion</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Init</span><span class="token plain">               </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_Config_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">gpioConfig </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">                 </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Deinit</span><span class="token plain">             </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">                 </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Task</span><span class="token plain">               </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PortActive</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinMode</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinMode_t</span><span class="token plain"> pinType </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_PinMode</span><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinMode_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> pinType </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ... speed, output type, alternate function and pull in the same pairs ... */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Toggle_PinLevel</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinLevel</span><span class="token plain">       </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> pinLevel </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_PinLevel</span><span class="token plain">       </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> pinLevel </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinStateActive</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> pinActiveLevel </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_RequestState_t</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinStateInactive</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain"> pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> pinActiveLevel </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Každé rozhodnutie nižšie sa dá vyčítať z tohto zoznamu.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-pin-je-dvojica-identifikátorov-nie-makro-výrobcu">1. Pin je dvojica identifikátorov, nie makro výrobcu<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#1-pin-je-dvojica-identifik%C3%A1torov-nie-makro-v%C3%BDrobcu" class="hash-link" aria-label="Priamy odkaz na 1. Pin je dvojica identifikátorov, nie makro výrobcu" title="Priamy odkaz na 1. Pin je dvojica identifikátorov, nie makro výrobcu" translate="no">​</a></h2>
<p>Ovládače výrobcu adresujú pin ukazovateľom na blok registrov a bitovou maskou: <code>LL_GPIO_SetOutputPin(GPIOA, LL_GPIO_PIN_5)</code>. MCAL namiesto toho berie dve enumerácie, <code>gpio_PortId_t</code> a <code>gpio_PinId_t</code>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> GPIO_PORT_A</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_ID_5</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_LEVEL_HIGH </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>Prečo:</strong> kód nad MCAL nepotrebuje žiadnu hlavičku výrobcu, nevie, čo je <code>GPIOA</code> (adresa bloku registrov výrobcu) a identifikátor sa dá kontrolovať na rozsah, čo pri ľubovoľnom ukazovateli nejde. Každá enumerácia končí počítadlom (<code>GPIO_PORT_CNT</code>, <code>GPIO_PIN_ID_CNT</code>), ktoré je hornou hranicou pre kontrolu na začiatku funkcie.</p>
<p><strong>Cena:</strong> tabuľka, ktorá prekladá identifikátor na blok registrov (v <code>Gpio.c</code>, jeden riadok na port) a jedna nepriama úroveň navyše. Tabuľka zároveň rieši vlastný problém: MCU jednej rodiny majú rôzny počet portov, takže záznamy sú obalené v <code>#if defined(GPIOK)</code> (pozri článok o <a class="" href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches">rodinách</a>).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-každá-funkcia-ktorá-môže-zlyhať-vracia-stav-a-výsledky-idú-von-cez-ukazovateľ">2. Každá funkcia, ktorá môže zlyhať, vracia stav a výsledky idú von cez ukazovateľ<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#2-ka%C5%BEd%C3%A1-funkcia-ktor%C3%A1-m%C3%B4%C5%BEe-zlyha%C5%A5-vracia-stav-a-v%C3%BDsledky-id%C3%BA-von-cez-ukazovate%C4%BE" class="hash-link" aria-label="Priamy odkaz na 2. Každá funkcia, ktorá môže zlyhať, vracia stav a výsledky idú von cez ukazovateľ" title="Priamy odkaz na 2. Každá funkcia, ktorá môže zlyhať, vracia stav a výsledky idú von cez ukazovateľ" translate="no">​</a></h2>
<p>Všetky funkcie okrem <code>Deinit</code>, <code>Task</code> a getteru verzie vracajú <code>gpio_RequestState_t</code> a gettery odovzdávajú hodnotu cez parameter-ukazovateľ:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> level </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_LEVEL_LOW</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_OK </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_PORT_C</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_ID_13</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">level</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* level is valid here */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Prečo:</strong> návratová hodnota getteru nemôže niesť hodnotu <em>aj</em> informáciu, že hodnota nie je platná (<code>GPIO_PIN_LEVEL_LOW</code> je platná úroveň, takže vrátená <code>0</code> je nejednoznačná). So stavom v návratovej hodnote a dátami v parametri je neplatný port, neplatný pin alebo <code>NULL</code> ukazovateľ viditeľná chyba a nie potichu zlá úroveň. <code>* const</code> v signatúre hovorí, že funkcia nemení ukazovateľ, iba dáta za ním.</p>
<p><strong>Cena:</strong> dva riadky namiesto jedného pri každom použití. A stav má dve hodnoty (<code>GPIO_REQUEST_OK</code>, <code>GPIO_REQUEST_ERROR</code>), takže volajúci vie, <em>že</em> zlyhalo, a nie <em>prečo</em>. Pre GPIO to stačí, lebo dôvodov je len niekoľko (neplatný identifikátor, <code>NULL</code>) a všetky sú programátorské chyby. Pri periférii so skutočným zlyhaním (timeout I2C, chyba zbernice) volajúci potrebuje viac a obvyklou odpoveďou je bohatšia enumerácia.</p>
<p>Pravidlo z článku o <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">MISRA</a>, ktoré sa tu uplatňuje, je 17.7 (vrátená hodnota sa používa): rozhranie tu uľahčuje jeho dodržanie, pretože každá funkcia, ktorá môže zlyhať, to oznamuje hodnotou, na ktorú sa musíte pozrieť.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-pin-sa-konfiguruje-dátami-nie-sledom-volaní">3. Pin sa konfiguruje dátami, nie sledom volaní<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#3-pin-sa-konfiguruje-d%C3%A1tami-nie-sledom-volan%C3%AD" class="hash-link" aria-label="Priamy odkaz na 3. Pin sa konfiguruje dátami, nie sledom volaní" title="Priamy odkaz na 3. Pin sa konfiguruje dátami, nie sledom volaní" translate="no">​</a></h2>
<p>Existuje konfiguračná štruktúra so všetkým, čo pin popisuje, a jedna funkcia, ktorá ju aplikuje:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain">        PortId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">         </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO port identification       */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain">         PinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO pin identification        */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinMode_t</span><span class="token plain">       PinMode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO pin type                  */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinPullCfg_t</span><span class="token plain">    PinPull</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO pin pull configuration    */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinSpeed_t</span><span class="token plain">      PinSpeed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO output speed              */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinOutputType_t</span><span class="token plain"> PinOutType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; GPIO output style              */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_AltFunction_t</span><span class="token plain">   PinAltFunction</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Alternate function used by pin */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain">      PinActiveLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Pin level in active state      */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_Config_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>Prečo:</strong> znalosť o doske potom žije v <strong>tabuľke</strong> a kód, ktorý ju aplikuje, je pre každú dosku rovnaký. Pozrite sa na príklad, ktorý som skompiloval a spustil: doska sú dva záznamy a inicializácia je slučka.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">board.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Gpio_Port.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The board is data: which pin is what, and what "active" means for it. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> BOARD_IO_LED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> BOARD_IO_BUTTON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> BOARD_IO_CNT </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">boardIo_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_Config_t</span><span class="token plain"> boardPins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BOARD_IO_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BOARD_IO_LED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PortId </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PORT_A</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinId </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_ID_5</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinMode </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_MODE_OUTPUT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinPull </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_PULL_NONE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinSpeed </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_SPEED_LOW</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinOutType </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_OUTPUT_PUSHPULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinAltFunction </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_ALT_FUNC_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinActiveLevel </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_LEVEL_LOW        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* this LED is connected to the supply: low = on */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BOARD_IO_BUTTON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PortId </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PORT_C</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinId </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_ID_13</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinMode </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_MODE_INPUT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinPull </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_PULL_NONE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinSpeed </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_SPEED_LOW</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinOutType </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_OUTPUT_PUSHPULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinAltFunction </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_ALT_FUNC_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">PinActiveLevel </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_LEVEL_HIGH</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Board_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    bool isOk </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">BOARD_IO_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_OK </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">boardPins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            isOk </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> isOk</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Board_Set_Led</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool isOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_Config_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">led </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">boardPins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BOARD_IO_LED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_OK </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">isOn</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinStateActive</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PortId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PinActiveLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinStateInactive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PortId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> led</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">PinActiveLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Keďže tabuľka sú dáta, nová revízia DPS zmení riadok v tabuľke a nič v kóde. V architektúre Embedbits je to úloha vrstvy HAL: drží tabuľky a pomocou MCAL ich aplikuje.</p>
<p><strong>Cena:</strong> štruktúra má osem polí a každý záznam musí vyplniť všetky (designated initializers to robia čitateľným a vynechané pole je nula, čo nie je vždy rozumná hodnota). Preto je užitočným spoločníkom funkcia <code>Get_DefaultConfig</code>, ktorú majú niektoré iné moduly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-polarita-signálu-je-vlastnosťou-pinu-nie-kódu">4. Polarita signálu je vlastnosťou pinu, nie kódu<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#4-polarita-sign%C3%A1lu-je-vlastnos%C5%A5ou-pinu-nie-k%C3%B3du" class="hash-link" aria-label="Priamy odkaz na 4. Polarita signálu je vlastnosťou pinu, nie kódu" title="Priamy odkaz na 4. Polarita signálu je vlastnosťou pinu, nie kódu" translate="no">​</a></h2>
<p>Štruktúra má pole <code>PinActiveLevel</code> a existujú funkcie <code>Gpio_Set_PinStateActive()</code> a <code>Gpio_Set_PinStateInactive()</code>, ktoré berú polaritu ako parameter. Dôvodom je obyčajný fakt z elektroniky: LED môže byť pripojená k zemi (svieti s úrovňou <strong>high</strong>) alebo k napájaniu (svieti s úrovňou <strong>low</strong>) a signál chip-select je zvyčajne <em>active low</em>. Ak kód hovorí <code>Gpio_Set_PinLevel(..., HIGH)</code> pre „LED zapnutá“, je to správne pre jednu dosku a zlé pre ďalšiu.</p>
<p>S polaritou v tabuľke aplikácia povie „zapni“ a tabuľka povie, čo to znamená. V príklade vyššie je LED pripojená k napájaniu, takže <code>PinActiveLevel</code> je <code>GPIO_PIN_LEVEL_LOW</code> a test potvrdzuje, čo pin robí:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">after Board_Init():      the pin is high (the LED is off)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">after Board_Set_Led(1):  the pin is low  (the LED is on)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-enumerácie-sú-konštanty-výrobcu">5. Enumerácie sú konštanty výrobcu<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#5-enumer%C3%A1cie-s%C3%BA-kon%C5%A1tanty-v%C3%BDrobcu" class="hash-link" aria-label="Priamy odkaz na 5. Enumerácie sú konštanty výrobcu" title="Priamy odkaz na 5. Enumerácie sú konštanty výrobcu" translate="no">​</a></h2>
<p>Typy si nevymýšľajú vlastné čísla, sú to čísla ovládača výrobcu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    GPIO_PIN_MODE_INPUT     </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> LL_GPIO_MODE_INPUT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Select input mode              */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    GPIO_PIN_MODE_OUTPUT    </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> LL_GPIO_MODE_OUTPUT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Select output mode             */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    GPIO_PIN_MODE_ALTERNATE </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> LL_GPIO_MODE_ALTERNATE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Select alternate function mode */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    GPIO_PIN_MODE_ANALOG    </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> LL_GPIO_MODE_ANALOG     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Select analog mode             */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinMode_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><strong>Prečo:</strong> konverzia z typu MCAL na hodnotu, ktorú chce funkcia LL, je <strong>zadarmo</strong>: žiadny <code>switch</code>, žiadna tabuľka a žiadna možnosť urobiť v preklade preklep. Hodnoty konštánt sa líšia rodinu od rodiny a to je skryté v jedinom <code>#include</code> portu RAL (<code>Stm32_gpio.h</code> špecifický pre rodinu).</p>
<p><strong>Cena:</strong> <code>Gpio_Types.h</code>, verejná hlavička, includuje hlavičku RAL, takže konštanty výrobcu presakujú do hlavičiek, ktoré vidia používatelia modulu. Alternatívou je typ s vlastnými hodnotami a prekladová tabuľka v súbore <code>.c</code>, čo stojí kód a miesto pre chybu, ale drží výrobcu mimo verejných hlavičiek. Rozhodnutie je kompromis a je dobré vedieť, že ním je.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-rovnaký-životný-cyklus-ako-v-každom-inom-module">6. Rovnaký životný cyklus ako v každom inom module<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#6-rovnak%C3%BD-%C5%BEivotn%C3%BD-cyklus-ako-v-ka%C5%BEdom-inom-module" class="hash-link" aria-label="Priamy odkaz na 6. Rovnaký životný cyklus ako v každom inom module" title="Priamy odkaz na 6. Rovnaký životný cyklus ako v každom inom module" translate="no">​</a></h2>
<p><code>Gpio_Get_ModuleVersion()</code>, <code>Gpio_Init()</code>, <code>Gpio_Deinit()</code> a <code>Gpio_Task()</code> pochádzajú zo šablóny, s ktorou začína každý modul (pozri článok o <a class="" href="https://embedbits.cz/sk/blog/file-organization-embedded-c">organizácii súborov</a>). Rozdiel je na jedinom mieste, kde to dáva zmysel: <code>Gpio_Init()</code> nie je <code>void</code>, berie <strong>konfiguráciu pinu</strong>. Modul GPIO nepozná dosku, takže „inicializuj modul“ nemá zmysel bez otázky „ktorý pin?“. Jednotný životný cyklus, ktorý sa ohne tam, kde to povaha modulu vyžaduje, je lepší než životný cyklus vnútený modulu, kam nepasuje.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-poradie-krokov-je-súčasťou-rozhrania">7. Poradie krokov je súčasťou rozhrania<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#7-poradie-krokov-je-s%C3%BA%C4%8Das%C5%A5ou-rozhrania" class="hash-link" aria-label="Priamy odkaz na 7. Poradie krokov je súčasťou rozhrania" title="Priamy odkaz na 7. Poradie krokov je súčasťou rozhrania" translate="no">​</a></h2>
<p>Pozrite sa na komentár k <code>Gpio_Init()</code>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Activates the port clock and configures the pin. Output level (inactive state),</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * output type, speed, pull and alternate function are configured before the pin</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * mode, so an output pin starts directly with its inactive level (no glitch).</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Configuration stops at the first failed step.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><br></div></code></pre></div></div>
<p>Režim pinu, čo je krok, ktorý skutočne <strong>pripája výstupný budič na pad</strong>, je posledný. Keby bol režim prvý, pin by na okamih budil úroveň, akú mal výstupný register po resete (zvyčajne low), a potom by preskočil na správnu: impulz na vedení, ktoré môže byť chip-select, reset iného čipu alebo gate tranzistora. Takýto glitch je v debuggeri neviditeľný a na osciloskope viditeľný. Je to dobrý príklad pravidla pre návrh API: <strong>keď na poradí krokov záleží hardvéru, funkcia, ktorá ich vykonáva, by mala poradie vlastniť</strong>, aby ho používateľ nemohol pokaziť.</p>
<p>Druhá veta komentára, „stops at the first failed step“, je tiež dizajnové rozhodnutie: funkcia sa nepokúša pokračovať po chybe a vráti stav zlyhaného kroku.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="8-zlý-argument-je-chyba-ktorú-volajúci-vidí-nie-pád">8. Zlý argument je chyba, ktorú volajúci vidí, nie pád<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#8-zl%C3%BD-argument-je-chyba-ktor%C3%BA-volaj%C3%BAci-vid%C3%AD-nie-p%C3%A1d" class="hash-link" aria-label="Priamy odkaz na 8. Zlý argument je chyba, ktorú volajúci vidí, nie pád" title="Priamy odkaz na 8. Zlý argument je chyba, ktorú volajúci vidí, nie pád" translate="no">​</a></h2>
<p>Funkcie kontrolujú svoje argumenty a odpoveďou je stav:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_ERROR </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_NULL_PTR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_ERROR </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_PORT_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_ID_0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">level</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_REQUEST_ERROR </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_PORT_A</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_ID_CNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_LEVEL_HIGH</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>(Toto je test môjho fake, ale skutočný <code>Gpio_Init()</code> robí to isté pre <code>NULL</code>: celé telo je vo vnútri <code>if( GPIO_NULL_PTR != gpioConfig )</code>.) Konštanty <code>_CNT</code> tu majú druhú úlohu: <code>GPIO_PORT_CNT</code> je prvá hodnota, ktorá <strong>nie je</strong> platným portom, takže kontrola je jediné porovnanie. Vo firmvéri nie je komu ukázať správu a <code>assert</code>, ktorý zastaví program, je pre produkčný build zvyčajne zlá odpoveď. Lepšia je chyba, ktorá ide hore k volajúcemu, ktorý vie, čo robiť (a k modulu nad MCAL, ktorý vie, čo je kritické).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="na-čo-by-som-sa-pozrel-znova">Na čo by som sa pozrel znova<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#na-%C4%8Do-by-som-sa-pozrel-znova" class="hash-link" aria-label="Priamy odkaz na Na čo by som sa pozrel znova" title="Priamy odkaz na Na čo by som sa pozrel znova" translate="no">​</a></h2>
<p>Úprimná revízia návrhu má vždy zoznam a tento má dve položky, ktoré pochádzajú z článku o MISRA:</p>
<ul>
<li class=""><code>Gpio_Init( gpio_Config_t *gpioConfig )</code> štruktúru iba <strong>číta</strong>, takže parameter by mohol byť <code>const gpio_Config_t *</code> (Rule 8.13). Signatúra by hovorila, že funkcia konfiguráciu nemení, a tabuľka dosky by mohla byť <code>const</code> a žiť vo flash namiesto v RAM.</li>
<li class="">Dvojhodnotový <code>gpio_RequestState_t</code> je v každom module rovnaký (generuje ho šablóna). Je to jednoduché a jednotné rozhodnutie, ktoré je pre GPIO správne, a moduly so skutočnými zlyhaniami budú skôr či neskôr potrebovať viac.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="princípy-stručne">Princípy stručne<a href="https://embedbits.cz/sk/blog/designing-peripheral-api-gpio#princ%C3%ADpy-stru%C4%8Dne" class="hash-link" aria-label="Priamy odkaz na Princípy stručne" title="Priamy odkaz na Princípy stručne" translate="no">​</a></h2>
<ol>
<li class=""><strong>Skrývajte hardvér, nie zámer.</strong> Používateľ povie <em>ktorý pin</em> a <em>akú polaritu</em>, nie <em>ktorý register</em>.</li>
<li class=""><strong>Urobte neplatný stav viditeľným.</strong> Stav pre všetko, čo môže zlyhať, a výstup len pri úspechu.</li>
<li class=""><strong>Dajte znalosť do dát.</strong> Doska je tabuľka, ktorú číta slučka.</li>
<li class=""><strong>Nechajte funkciu vlastniť poradie,</strong> keď na ňom hardvéru záleží.</li>
<li class=""><strong>Držte rozhranie rovnaké a povedzte úprimne, kde je ohnuté</strong> (<code>Init</code> s parametrom) a kde abstrakcia presakuje (konštanty výrobcu v typoch).</li>
</ol>
<p>Rozhranie má dvoch čitateľov: používateľa dneška a správcu budúceho roka. Rozhodnutia vyššie sú napísané pre oboch a komentáre v hlavičkách sú dôkazom, že niekto myslel na toho druhého.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>Architektúra</category>
        </item>
        <item>
            <title><![CDATA[Doxygen pre embedded C: dokumentácia, na ktorú sa nedá zabudnúť]]></title>
            <link>https://embedbits.cz/sk/blog/doxygen-embedded-c</link>
            <guid>https://embedbits.cz/sk/blog/doxygen-embedded-c</guid>
            <pubDate>Tue, 06 Oct 2026 20:00:00 GMT</pubDate>
            <description><![CDATA[Každý projekt má dokumentáciu a každý projekt má dokumentáciu, ktorá klame. Súbor Wordu s popisom rozhrania bol správny v týždni, keď vznikol. Komentár nad funkciou je čestnejší, pretože je len pár riadkov od kódu, ktorý opisuje, ale píšu ho tí istí ľudia, ktorí zabúdajú. Cesta von nie je viac disciplíny, ale nástroj, ktorý číta komentáre, zostaví z nich dokumentáciu a pri chýbajúcom popise zlyhá build. Tým nástrojom je Doxygen.]]></description>
            <content:encoded><![CDATA[<p>Každý projekt má dokumentáciu a každý projekt má dokumentáciu, ktorá klame. Súbor Wordu s popisom rozhrania bol správny v týždni, keď vznikol. Komentár nad funkciou je čestnejší, pretože je len pár riadkov od kódu, ktorý opisuje, ale píšu ho tí istí ľudia, ktorí zabúdajú. Cesta von nie je viac disciplíny, ale <strong>nástroj, ktorý číta komentáre, zostaví z nich dokumentáciu a pri chýbajúcom popise zlyhá build</strong>. Tým nástrojom je Doxygen.</p>
<p>Tento článok ukazuje, ako vyzerá zdokumentovaný modul v mojich projektoch, ako sa generuje a ako z dokumentácie urobiť súčasť CI, ktorú nemožno preskočiť. Príklady boli zostavené s Doxygen 1.9.8 a Graphviz a výstupy sú skutočné.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-dokumentovať-a-čo-nie">Čo dokumentovať a čo nie<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#%C4%8Do-dokumentova%C5%A5-a-%C4%8Do-nie" class="hash-link" aria-label="Priamy odkaz na Čo dokumentovať a čo nie" title="Priamy odkaz na Čo dokumentovať a čo nie" translate="no">​</a></h2>
<p>Môj <a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/coding-style">coding style</a> má o tom jeden odsek: komentáre v štýle Doxygen pre všetky <strong>verejné</strong> funkcie, typy a makrá, v angličtine, krátke a presné, <em>prečo</em> a nie <em>čo</em>. Pár príkladov rozdielu:</p>





















<table><thead><tr><th>Komentár, ktorý nič nestojí</th><th>Komentár, ktorý pomáha</th></tr></thead><tbody><tr><td><code>/* initializes the module */</code></td><td><code>Clears the filter and marks the value as not valid. The module does not report a value until Temperature_Task() has run at least once.</code></td></tr><tr><td><code>/* returns the value */</code></td><td><code>Returns TEMPERATURE_REQUEST_OK if a valid value is available, TEMPERATURE_REQUEST_ERROR if the task has not run yet.</code></td></tr><tr><td><code>/* value */</code> (pre parameter)</td><td><code>Filtered temperature in tenths of a degree Celsius. Must not be NULL. Written only if the function returns TEMPERATURE_REQUEST_OK.</code></td></tr></tbody></table>
<p>Prvý stĺpec opakuje názov funkcie, ktorý čitateľ už vidí. Druhý stĺpec hovorí to, čo čitateľ <strong>vidieť nemôže</strong>: jednotku, platný rozsah, kto vlastní pamäť, či sa výstup zapíše v prípade chyby, odkiaľ sa funkcia môže volať, čo treba urobiť predtým. Pre embedded rozhranie je to aj miesto pre informácie, ktoré je nebezpečné hádať: <em>je bezpečné volať ju z prerušenia</em>, <em>ako dlho môže blokovať</em>, <em>smie byť ukazovateľ NULL</em>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="modul-v-súboroch-platformy">Modul v súboroch platformy<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#modul-v-s%C3%BAboroch-platformy" class="hash-link" aria-label="Priamy odkaz na Modul v súboroch platformy" title="Priamy odkaz na Modul v súboroch platformy" translate="no">​</a></h2>
<p>Šablóny EmBi_Platform, z ktorých každý modul vychádza, majú rovnakú kostru dokumentácie: hlavičku súboru s <code>\author</code>, <code>\file</code>, <code>\ingroup</code> a <code>\brief</code> a nad každou funkciou blok s <code>\brief</code>, popisom a <code>\return</code>. Šablóna konečného automatu pridáva <code>\pre</code> pre predpoklady a blok <code>\par Used global variables</code> so zoznamom premenných, ktoré funkcia číta (<code>in</code>), zapisuje (<code>out</code>) alebo oboje (<code>in,out</code>), čo je prekvapivo užitočný druh dokumentácie: tok dát funkcie v troch riadkoch.</p>
<p>Celý modul je v Doxygene jedna <strong>skupina</strong>. <code>\ingroup Temperature</code> v každom súbore hovorí, že súbor patrí do modulu, a samotná skupina je definovaná raz, v súbore port:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature_Port.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \author Mr.Nobody</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature_Port.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Temperature module public functionality</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * The only header that other modules include.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \defgroup Temperature Temperature module</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Measures the temperature and provides a filtered value.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * The module has to be initialized by Temperature_Init() and its</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Temperature_Task() has to be called periodically. The latest filtered value</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * is read by Temperature_Get_Value().</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TEMPERATURE_TEMPERATURE_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TEMPERATURE_TEMPERATURE_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">__cplusplus</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"C"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature_Types.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================= EXPORTED FUNCTIONS ============================= */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Initializes the module.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Clears the filter and marks the value as not valid. The module does not</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * report a value until Temperature_Task() has run at least once.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \pre Called once, before the first Temperature_Task().</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Reads the sensor and updates the filtered value.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Shall be called periodically from the main loop or from a scheduler, it</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * takes about the same time on every call.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \note Not safe to be called from an interrupt: the function is not reentrant.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Provides the latest filtered temperature.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \param[out] value Filtered temperature in tenths of a degree Celsius. Must</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *                   not be NULL. It is written only if the function returns</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *                   \ref TEMPERATURE_REQUEST_OK.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \return \ref TEMPERATURE_REQUEST_OK if a valid value is available,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *         \ref TEMPERATURE_REQUEST_ERROR if the task has not run yet.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Get_Value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> value </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">__cplusplus</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token macro property"> </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* TEMPERATURE_TEMPERATURE_PORT_H */</span><br></div></code></pre></div></div>
<p>Typy majú krátky popis typu a každej hodnoty (komentár <code>/**&lt; ... */</code> za členom dokumentuje člen na tom istom riadku):</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature_Types.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \author Mr.Nobody</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature_Types.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Temperature module global types definition</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * This file contains the types that are used across the module and are</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * available for other modules through the port file.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TEMPERATURE_TEMPERATURE_TYPES_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TEMPERATURE_TEMPERATURE_TYPES_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== TYPEDEFS ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/** Temperature in tenths of a degree Celsius, e.g. 253 means 25.3 degC. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">int16_t</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/** Enumeration used to signal the result of a request. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    TEMPERATURE_REQUEST_ERROR </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; The request failed, the output is not valid */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    TEMPERATURE_REQUEST_OK          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; The request succeeded                       */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token macro property"> </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* TEMPERATURE_TEMPERATURE_TYPES_H */</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="generovanie">Generovanie<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#generovanie" class="hash-link" aria-label="Priamy odkaz na Generovanie" title="Priamy odkaz na Generovanie" translate="no">​</a></h2>
<p>Doxygen sa konfiguruje súborom s pár stovkami volieb. Písať ho ručne je chyba, ktorej sa dá ľahko vyhnúť: platforma má súbor ako šablónu (<code>Doxyfile.in</code> v artefakte Doxygen) a napĺňa ho z premenných CMake a projekty nastavujú len tie, ktoré sa líšia od predvolených. To isté umožňuje aj samotný modul CMake a toto je celá konfigurácia príkladu:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">CMakeLists.txt</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">cmake_minimum_required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">VERSION</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.19</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">project</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DoxDemo C</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">find_package</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Doxygen REQUIRED dot</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_PROJECT_NAME        </span><span class="token string" style="color:rgb(195, 232, 141)">"Temperature module"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_OUTPUT_DIRECTORY    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/docs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_FULL_PATH_NAMES     NO</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_GENERATE_LATEX      NO</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_QUIET               YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The documentation is a contract: a missing description is an error.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_IF_UNDOCUMENTED     YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_IF_DOC_ERROR        YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_NO_PARAMDOC         YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_AS_ERROR            FAIL_ON_WARNINGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Graphs (the Graphviz artifact in the platform)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_HAVE_DOT                 YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_CALL_GRAPH               YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_CALLER_GRAPH             YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_DOT_IMAGE_FORMAT         svg</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">doxygen_add_docs</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">docs Temperature COMMENT </span><span class="token string" style="color:rgb(195, 232, 141)">"Generating the documentation"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>a build je jeden cieľ:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-S</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">.</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-B</span><span class="token plain"> build </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-G</span><span class="token plain"> Ninja</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--build</span><span class="token plain"> build </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--target</span><span class="token plain"> docs</span><br></div></code></pre></div></div>
<p>Výsledkom je priečinok so stránkami HTML. Skupina modulu so súbormi, ktoré do nej patria, a s popisom zo súboru port vyzerá takto:</p>
<p><img decoding="async" loading="lazy" alt="Stránka skupiny Temperature vo vygenerovanej HTML dokumentácii" src="https://embedbits.cz/sk/assets/images/doxygen-module-group-7e9b023f433e65035665cd32e2f490ba.png" width="1000" height="900" class="img_ev3q"></p>
<p>Doxygen tiež kreslí <strong>include graf</strong> každého súboru a <strong>call graf</strong> a <strong>caller graf</strong> každej zdokumentovanej funkcie (<code>HAVE_DOT</code>, Graphviz: preto má platforma na to artefakt). Include grafy stojí za to občas pozrieť: šípka z aplikačného súboru do internej hlavičky modulu je ten istý problém, ktorý opisuje <a class="" href="https://embedbits.cz/sk/blog/file-organization-embedded-c">článok o organizácii súborov</a>, len videný zhora.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dokumentácia-ako-test">Dokumentácia ako test<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#dokument%C3%A1cia-ako-test" class="hash-link" aria-label="Priamy odkaz na Dokumentácia ako test" title="Priamy odkaz na Dokumentácia ako test" translate="no">​</a></h2>
<p>Toto je časť, ktorá mení disciplínu. Štyri voľby menia chýbajúcu dokumentáciu z „mali by sme“ na „build je červený“:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_IF_UNDOCUMENTED   YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># a public member without a description</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_IF_DOC_ERROR      YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># a wrong tag, a parameter that does not exist</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_NO_PARAMDOC       YES</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># a function whose parameters are not described</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DOXYGEN_WARN_AS_ERROR          FAIL_ON_WARNINGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>S <code>FAIL_ON_WARNINGS</code> Doxygen prejde všetko, vypíše <strong>všetky</strong> varovania a až potom zlyhá (obyčajné <code>YES</code> sa zastaví pri prvom). Vyskúšal som to: zo súboru port som zmazal popis <code>Temperature_Task()</code> a <code>\param</code> funkcie <code>Temperature_Get_Value()</code> a build vypísal:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Temperature/Temperature_Port.h:40: error: Member Temperature_Task(void) (function) of file Temperature_Port.h is not documented.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Temperature/Temperature_Port.h:45: error: parameters of member Temperature_Get_Value are not documented</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ninja: build stopped: subcommand failed.</span><br></div></code></pre></div></div>
<p>(Návratový kód príkazu je 1, takže CI je červené.) Keď sa popisy vrátia, ten istý build skončí bez akéhokoľvek výstupu a s návratovým kódom 0. Nová funkcia bez komentára sa teraz nemôže omylom dostať do hlavnej vetvy a nikto nemusí byť ten, kto si to pri review pamätá.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-obsahuje-dobrá-dokumentácia-rozhrania">Čo obsahuje dobrá dokumentácia rozhrania<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#%C4%8Do-obsahuje-dobr%C3%A1-dokument%C3%A1cia-rozhrania" class="hash-link" aria-label="Priamy odkaz na Čo obsahuje dobrá dokumentácia rozhrania" title="Priamy odkaz na Čo obsahuje dobrá dokumentácia rozhrania" translate="no">​</a></h2>
<p>Pri každej funkcii verejného rozhrania skontrolujte zoznam:</p>
<ol>
<li class=""><strong>Čo robí</strong>, v jednej vete, so slovesom (<code>\brief</code>).</li>
<li class=""><strong>Parametre</strong>: smer (<code>[in]</code>, <code>[out]</code>, <code>[in,out]</code>), jednotku, rozsah, či je <code>NULL</code> povolené.</li>
<li class=""><strong>Návratová hodnota</strong>: každá hodnota, ktorá sa môže vrátiť, a čo znamená.</li>
<li class=""><strong>Predpoklady</strong> (<code>\pre</code>): čo sa musí urobiť predtým, napríklad inicializácia.</li>
<li class=""><strong>Kontext</strong>: dá sa volať z prerušenia, blokuje, ako dlho trvá.</li>
<li class=""><strong>Vedľajšie účinky</strong>: čo ešte mení (globálny stav, periféria).</li>
</ol>
<p>Ak funkcia nemá odpoveď na jednu z týchto otázok, odpoveď je v kóde a čitateľ si ju musí prečítať. To je znamenie, že rozhranie nie je dokončené, a písanie komentára je často moment, keď to zistíte.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kde-to-zapadá-v-platforme">Kde to zapadá v platforme<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#kde-to-zapad%C3%A1-v-platforme" class="hash-link" aria-label="Priamy odkaz na Kde to zapadá v platforme" title="Priamy odkaz na Kde to zapadá v platforme" translate="no">​</a></h2>
<p>Každý modul platformy má vo svojom <code>CMakeLists.txt</code> volanie, ktoré zaregistruje jeho priečinok pre dokumentáciu (keď je artefakt Doxygen v projekte dostupný), a koreňový build má voľbu <code>DOXYGEN_ENABLED</code>. Dokumentácia celého firmvéru sa teda generuje tým istým buildom ako firmvér: <code>-DDOXYGEN_ENABLED=ON</code>. Artefakty (Doxygen a Graphviz) sa sťahujú vo verzii, ktorú má projekt pripnutú, takže stránky dnes a o rok vyzerajú rovnako.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="checklist">Checklist<a href="https://embedbits.cz/sk/blog/doxygen-embedded-c#checklist" class="hash-link" aria-label="Priamy odkaz na Checklist" title="Priamy odkaz na Checklist" translate="no">​</a></h2>
<ol>
<li class="">Každá verejná funkcia, typ a makro má popis. Interné len tam, kde to nie je zrejmé.</li>
<li class="">Popis hovorí to, čo čitateľ nevidí v signatúre: jednotky, rozsahy, kontext, chyby.</li>
<li class="">Jedna skupina na modul (<code>\defgroup</code> v súbore port, <code>\ingroup</code> v ostatných).</li>
<li class=""><code>WARN_IF_UNDOCUMENTED</code>, <code>WARN_NO_PARAMDOC</code> a <code>FAIL_ON_WARNINGS</code> v CI.</li>
<li class="">Grafy sú zapnuté a niekto sa občas pozrie na include graf aplikácie.</li>
<li class="">Dokumentácia sa generuje z toho istého buildu ako firmvér, s pripnutými nástrojmi.</li>
</ol>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>CMake</category>
        </item>
        <item>
            <title><![CDATA[CMake pre embedded firmware: build, ktorý si môžete prečítať]]></title>
            <link>https://embedbits.cz/sk/blog/cmake-for-embedded-firmware</link>
            <guid>https://embedbits.cz/sk/blog/cmake-for-embedded-firmware</guid>
            <pubDate>Tue, 06 Oct 2026 18:00:00 GMT</pubDate>
            <description><![CDATA[Projekt z IDE je súbor, ktorý nikto nečíta build je text, ktorý čítate, kontrolujete, verzujete a spúšťate v CI presne tak isto ako na svojom stole.]]></description>
            <content:encoded><![CDATA[<p>Projekt z IDE je súbor, ktorý nikto nečíta: niekoľko tisíc riadkov XML, ktoré IDE zapisuje a IDE číta a ktoré sa nedajú skontrolovať v pull requeste. Build potom existuje len na počítači, kde ho niekto naklikal. CMake to rieši inou filozofiou: <strong>build je text, ktorý čítate, kontrolujete, verzujete a spúšťate v CI</strong> presne tak isto ako na svojom stole.</p>
<p>Build systém platformy Embedbits (EmBi_Platform) je postavený na CMake a tento článok vysvetľuje súčasti, ktoré potrebuje každý embedded build v CMake, na malom projekte, ktorý som zostavil a spustil: toolchain file, flagy s menami, typy buildu, moduly ako knižnice, linker script, súbory po linkovaní a test, ktorý spustí firmware v simulátore. Všetky čísla a výstupy sú skutočné.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dve-vrstvy-projekt-a-platforma">Dve vrstvy: projekt a platforma<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#dve-vrstvy-projekt-a-platforma" class="hash-link" aria-label="Priamy odkaz na Dve vrstvy: projekt a platforma" title="Priamy odkaz na Dve vrstvy: projekt a platforma" translate="no">​</a></h2>
<p>Platforma delí build na dve časti a túto myšlienku stojí za to ukradnúť aj pre malý projekt. Koreňový <code>CMakeLists.txt</code> produktu je minimálny vstupný bod a všetko komplikované žije v samostatnom skripte, ktorý je <strong>verzovaný a zdieľaný</strong> (submodul Gitu) a ktorý koreň includuje:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">include</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_CURRENT_LIST_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/CMake/Build.cmake</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Skript platformy pozná typy buildu (<code>Debug</code>, <code>Release</code>, <code>UnitTest</code>, <code>IntegrationTest</code>), kontroly parametrov, toolchain, include cesty a registráciu modulov. Produkt dopĺňa iba to, čo je preň špecifické. Oprava buildu je potom nová verzia submodulu, nie úprava desiatich produktov. Príklad nižšie má obe časti v jednom projekte, aby bol krátky, ale zachováva rovnaké oddelenie: <code>cmake/</code> je „platforma“ a <code>CMakeLists.txt</code> je „produkt“.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ukážkový-projekt">Ukážkový projekt<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#uk%C3%A1%C5%BEkov%C3%BD-projekt" class="hash-link" aria-label="Priamy odkaz na Ukážkový projekt" title="Priamy odkaz na Ukážkový projekt" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  arm-none-eabi.cmake       toolchain file</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  Flags.cmake               flags with names</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Bsp/Startup/                startup code and the linker script (see the article about main())</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Middlewares/Temperature/    a module as a library (see the article about file organization)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Application/                main.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">CMakeLists.txt</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="toolchain-file-kompilátor-nie-je-pc">Toolchain file: kompilátor nie je PC<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#toolchain-file-kompil%C3%A1tor-nie-je-pc" class="hash-link" aria-label="Priamy odkaz na Toolchain file: kompilátor nie je PC" title="Priamy odkaz na Toolchain file: kompilátor nie je PC" translate="no">​</a></h2>
<p>CMake predpokladá, že zostavujete pre počítač, pri ktorom sedíte. Toolchain file hovorí niečo iné:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">cmake/arm-none-eabi.cmake</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Toolchain file: tells CMake that the target is a bare-metal ARM and not the PC.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SYSTEM_NAME</span><span class="token plain">      Generic</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SYSTEM_PROCESSOR</span><span class="token plain"> arm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_C_COMPILER</span><span class="token plain">   arm-none-eabi-gcc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_ASM_COMPILER</span><span class="token plain"> arm-none-eabi-gcc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_OBJCOPY</span><span class="token plain">      arm-none-eabi-objcopy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SIZE</span><span class="token plain">         arm-none-eabi-size</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The compiler cannot link a PC executable: the check of the compiler builds a static library only.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_TRY_COMPILE_TARGET_TYPE</span><span class="token plain"> STATIC_LIBRARY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Search for programs on the PC, for libraries and headers only in the toolchain.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_FIND_ROOT_PATH_MODE_PROGRAM</span><span class="token plain"> NEVER</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_FIND_ROOT_PATH_MODE_LIBRARY</span><span class="token plain"> ONLY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_FIND_ROOT_PATH_MODE_INCLUDE</span><span class="token plain"> ONLY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Riadok, na ktorý ľudia zabúdajú, je <code>CMAKE_TRY_COMPILE_TARGET_TYPE</code>. Na začiatku CMake zostaví testovací program, aby overil, že kompilátor funguje, a bare-metal kompilátor nevie zlinkovať program pre PC (nie je operačný systém, nie je <code>main</code>, ktorý by niekto volal). Ak je cieľom kontroly statická knižnica, test prejde. Toolchain sa zadáva na príkazovom riadku, raz, pri vytvorení build priečinka:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-S</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">.</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-B</span><span class="token plain"> build-debug </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-G</span><span class="token plain"> Ninja </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DCMAKE_TOOLCHAIN_FILE</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">cmake/arm-none-eabi.cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DCMAKE_BUILD_TYPE</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">Debug</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--build</span><span class="token plain"> build-debug</span><br></div></code></pre></div></div>
<p>Rovnaký zdrojový priečinok s iným <code>-B</code> je iný build: <code>build-release</code> vedľa neho alebo build pre unit testy na PC, bez toolchain file.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="flagy-s-menami">Flagy s menami<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#flagy-s-menami" class="hash-link" aria-label="Priamy odkaz na Flagy s menami" title="Priamy odkaz na Flagy s menami" translate="no">​</a></h2>
<p>Riadok ako <code>-mcpu=cortex-m4 -mthumb -mfloat-abi=soft -ffunction-sections ...</code> sa ťažko kontroluje, pretože nikto nevie, ktorá jeho časť je dôležitá. Platforma má súbor <code>Flags.cmake</code> s premennou pre každý flag a s komentárom (<code>THUMB_MODE</code>, <code>ENABLE_ALL_WARNINGS</code>, <code>REMOVE_UNUSED_FUNCTIONS</code>, <code>ENABLE_GC_SECTIONS</code>, <code>PRINT_MEMORY_USAGE</code> a tak ďalej, plus varianty CPU a FPU od Cortex-M0 po M85). Projekt sa potom číta ako veta. Môj obsahuje len to, čo príklad potrebuje:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">cmake/Flags.cmake</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Flags with names, so the CMakeLists.txt reads like a sentence.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">MCU_FLAGS             -mcpu=cortex-m4 -mthumb -mfloat-abi=soft</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">WARNING_FLAGS         -Wall -Wextra -Wshadow -Wconversion</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">SECTION_FLAGS         -ffunction-sections -fdata-sections</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># one section per function and variable...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GC_FLAGS              -Wl,--gc-sections</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">                          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ...so the linker can drop the unused ones</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">STARTUP_LINK_FLAGS    -nostartfiles</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">DEBUG_OPTIONS         -Og -g3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">RELEASE_OPTIONS       -Os -g0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cmakeliststxt">CMakeLists.txt<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#cmakeliststxt" class="hash-link" aria-label="Priamy odkaz na CMakeLists.txt" title="Priamy odkaz na CMakeLists.txt" translate="no">​</a></h2>
<p>Celý koreňový súbor príkladu, 80 riadkov:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">CMakeLists.txt</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">cmake_minimum_required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">VERSION</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.19</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The toolchain file has to be given before project(), see the command line.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">project</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CmakeDemo C</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">enable_testing</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">option</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GC_SECTIONS </span><span class="token string" style="color:rgb(195, 232, 141)">"Let the linker remove the unused functions and data"</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">ON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">include</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">cmake/Flags.cmake</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># CMake adds its own flags to every configuration (-O3 -DNDEBUG for Release, -g for Debug).</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The flags of the project are in Flags.cmake, so the defaults are cleared.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_C_FLAGS_DEBUG</span><span class="token plain">   </span><span class="token string" style="color:rgb(195, 232, 141)">""</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_C_FLAGS_RELEASE</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">""</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- build type: flags of the configuration ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">NOT</span><span class="token plain"> </span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BUILD_TYPE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BUILD_TYPE</span><span class="token plain"> Debug</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BUILD_TYPE</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">STREQUAL</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"Debug"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUILD_OPTIONS </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">DEBUG_OPTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">elseif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BUILD_TYPE</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">STREQUAL</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"Release"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUILD_OPTIONS </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">RELEASE_OPTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">else</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">message</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">FATAL_ERROR </span><span class="token string" style="color:rgb(195, 232, 141)">"Unknown build type '</span><span class="token string interpolation punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token string interpolation variable" style="color:rgb(191, 199, 213)">CMAKE_BUILD_TYPE</span><span class="token string interpolation punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token string" style="color:rgb(195, 232, 141)">', use Debug or Release"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_C_STANDARD</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">11</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_C_STANDARD_REQUIRED</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">ON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_EXPORT_COMPILE_COMMANDS</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">ON</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- flags for everything that is built here ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MCU_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">WARNING_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">BUILD_OPTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GC_SECTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">add_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">SECTION_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_link_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MCU_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- modules ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_subdirectory</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Middlewares/Temperature</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># The startup code is an OBJECT library: its objects always end up in the executable,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># without relying on the linker to pull them out of an archive.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_library</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Startup OBJECT Bsp/Startup/startup.c</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># GCC may turn the copy and zero loops of the startup code into calls of memcpy() and memset()</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Startup </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> -fno-tree-loop-distribute-patterns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- the firmware ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">LINKER_SCRIPT </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/Bsp/Startup/link.ld</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_executable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware.elf Application/main.c Application/Unused.c </span><span class="token punctuation" style="color:rgb(199, 146, 234)">$&lt;</span><span class="token namespace" style="color:rgb(178, 204, 214)">TARGET_OBJECTS</span><span class="token plain">:Startup</span><span class="token punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_link_libraries</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware.elf </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> Temperature_Lib</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_link_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware.elf </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">STARTUP_LINK_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    -T </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">LINKER_SCRIPT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    -Wl,-Map=firmware.map</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    -Wl,--print-memory-usage</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    -Wl,--no-warn-rwx-segments</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GC_SECTIONS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">target_link_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware.elf </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">GC_FLAGS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set_target_properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware.elf </span><span class="token namespace" style="color:rgb(178, 204, 214)">PROPERTIES</span><span class="token plain"> </span><span class="token property">LINK_DEPENDS</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">LINKER_SCRIPT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- after the link: the files that you flash and a size report ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_custom_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">TARGET firmware.elf POST_BUILD</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_OBJCOPY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> -O binary firmware.elf firmware.bin</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_OBJCOPY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> -O ihex   firmware.elf firmware.hex</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> firmware.elf</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMENT </span><span class="token string" style="color:rgb(195, 232, 141)">"Creating firmware.bin, firmware.hex and the size report"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># ---- run it in the simulator as a test ----</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">find_program</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">QEMU qemu-system-arm</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">QEMU</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">add_test</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">NAME</span><span class="token plain"> firmware_runs_in_qemu</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">QEMU</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> -M netduinoplus2 -nographic -semihosting-config enable=on,target=native -kernel firmware.elf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">set_tests_properties</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">firmware_runs_in_qemu </span><span class="token namespace" style="color:rgb(178, 204, 214)">PROPERTIES</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token property">PASS_REGULAR_EXPRESSION</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"temperature module works"</span><span class="token plain"> </span><span class="token property">TIMEOUT</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">10</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endif</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Vysvetlím niekoľko riadkov, od ktorých závisí, či bude firmware správny.</p>
<p><strong>Typy buildu s explicitnými flagmi.</strong> Sú len dva, <code>Debug</code> (<code>-Og -g3</code>: dosť rýchly a laditeľný) a <code>Release</code> (<code>-Os -g0</code>: malý a bez ladiacich informácií) a čokoľvek iné zastaví konfiguráciu s chybovou hláškou. Platforma má ďalšie dva, <code>UnitTest</code> a <code>IntegrationTest</code>: v prvom z nich sa <code>TARGET_MCU</code> ani nevyžaduje, pretože sa zostavuje pre PC.</p>
<p><strong>Predvolené flagy CMake.</strong> Toto je pasca. CMake pridáva do každej konfigurácie vlastné flagy, <code>-O3 -DNDEBUG</code> pre <code>Release</code> a <code>-g</code> pre <code>Debug</code>, pred vaše vlastné. V prvej verzii príkladu vyzeral kompilačný príkaz release takto:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">-O3 -DNDEBUG -std=gnu11 -mcpu=cortex-m4 ... -Os -g0 -ffunction-sections ...</span><br></div></code></pre></div></div>
<p>Posledné <code>-O</code> vyhráva, takže to bolo <code>-Os</code>, ale <code>-DNDEBUG</code> (ktoré vypína <code>assert()</code>) tam bolo, hoci som oň nikdy nepožiadal. Ak chcete vedieť, čo zostavujete, vymažte predvolené hodnoty (<code>set(CMAKE_C_FLAGS_RELEASE "")</code>) a všetko napíšte do vlastného súboru. Spôsob, ako vidieť, čo skutočne ide do kompilátora, je <code>compile_commands.json</code>, ktorý vytvorí voľba <code>CMAKE_EXPORT_COMPILE_COMMANDS</code>: je to aj súbor, ktorý čítajú editory a <code>clang-tidy</code>.</p>
<p><strong>Startup kód je knižnica <code>OBJECT</code>.</strong> Objekty takej knižnice sa dostanú do spustiteľného súboru priamo, bez spoliehania sa na to, že ich linker vytiahne z archívu.</p>
<p><strong>Linker script je závislosť</strong> (<code>LINK_DEPENDS</code>): keď sa zmení, firmware sa zlinkuje znova.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="moduly-sú-knižnice">Moduly sú knižnice<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#moduly-s%C3%BA-kni%C5%BEnice" class="hash-link" aria-label="Priamy odkaz na Moduly sú knižnice" title="Priamy odkaz na Moduly sú knižnice" translate="no">​</a></h2>
<p>Každý modul je statická knižnica so zoznamom svojich <strong>vlastných</strong> zdrojákov a verejných hlavičiek (<a class="" href="https://embedbits.cz/sk/blog/file-organization-embedded-c">článok o organizácii súborov</a> vysvetľuje prečo). Aplikácia knižnicu zlinkuje a dostane s ňou include cestu k verejným hlavičkám a nič iné. V súbore CMake modulu nie je <code>file(GLOB ...)</code>: zdrojáky sú vymenované jeden po druhom, takže nový súbor je viditeľná zmena v pull requeste a súbor, ktorý v priečinku zostal omylom, sa do firmvéru nedostane.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="target_mcu-jeden-názov-viac-definícií"><code>TARGET_MCU</code>: jeden názov, viac definícií<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#target_mcu-jeden-n%C3%A1zov-viac-defin%C3%ADci%C3%AD" class="hash-link" aria-label="Priamy odkaz na target_mcu-jeden-názov-viac-definícií" title="Priamy odkaz na target_mcu-jeden-názov-viac-definícií" translate="no">​</a></h2>
<p>Buildy platformy sa spúšťajú s <code>-DTARGET_MCU=STM32G474xE</code>. Skript rozloží názov regulárnym výrazom a z jedného parametra vytvorí definície pre kód (<code>STM32G474xx</code> a <code>STM32G4xx</code>), ktoré hlavičky výrobcu používajú na výber správneho zariadenia. Rovnaká logika spustená na štyroch názvoch:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">STM32G474xE  -&gt;  MCU_ID STM32G474xx, MCU_FAMILY_ID STM32G4xx</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">STM32U5A5xx  -&gt;  MCU_ID STM32U5A5xx, MCU_FAMILY_ID STM32U5xx</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">STM32F407VG  -&gt;  MCU_ID STM32F407xx, MCU_FAMILY_ID STM32F4xx</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">STM32H563ZI  -&gt;  MCU_ID STM32H563xx, MCU_FAMILY_ID STM32H5xx</span><br></div></code></pre></div></div>
<p>To je spojenie s článkom o <a class="" href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches">rodinách STM32 a vetvách</a>: rodina rozhoduje, ktorá vetva BSP je v strome, a názov MCU rozhoduje o definíciách a linker scripte.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-vám-povie-linker">Čo vám povie linker<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#%C4%8Do-v%C3%A1m-povie-linker" class="hash-link" aria-label="Priamy odkaz na Čo vám povie linker" title="Priamy odkaz na Čo vám povie linker" translate="no">​</a></h2>
<p><code>-Wl,--print-memory-usage</code> na konci každého linkovania vypíše, koľko z ktorej pamäte je využité, <code>-Wl,-Map=firmware.map</code> zapíše adresu všetkého a krok po builde vypíše veľkosť:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Memory region         Used Size  Region Size  %age Used</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">           FLASH:         276 B         1 MB      0.03%</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">             RAM:           8 B       128 KB      0.01%</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   text	   data	    bss	    dec	    hex	filename</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    276	      0	      8	    284	    11c	firmware.elf</span><br></div></code></pre></div></div>
<p>Dva experimenty, ktoré som s týmito číslami urobil, ukazujú, prečo sú flagy v builde a nie v niekoho hlave.</p>
<p><strong>Linker vie zahodiť to, čo nikto nevolá.</strong> S <code>-ffunction-sections -fdata-sections</code> je každá funkcia vo vlastnej sekcii a <code>-Wl,--gc-sections</code> dovolí linkeru odstrániť nereferencované. Príklad má funkciu <code>Unused_Checksum()</code>, ktorú nikto nevolá:</p>

















<table><thead><tr><th>Build</th><th>Veľkosť kódu</th></tr></thead><tbody><tr><td>Release, bez flagov sekcií a bez <code>--gc-sections</code></td><td>324 B</td></tr><tr><td>Release, s nimi (<code>-DGC_SECTIONS=ON</code>)</td><td><strong>276 B</strong></td></tr></tbody></table>
<p>Rozdiel 48 bajtov je presne funkcia kontrolného súčtu. V reálnom projekte s knižnicou od výrobcu, ktorá má stovky funkcií a vy volíte desať, je rozdiel v kilobajtoch.</p>
<p><strong>Kompilátor vie pridať pamäť za vaším chrbtom.</strong> Prvý release build príkladu mal <strong>772 B</strong>, takmer trikrát viac než debug build (288 B). Map súbor ukázal <code>memcpy</code> a <code>memset</code> zo štandardnej knižnice. Príčina: keď je optimalizácia zapnutá, GCC rozpozná cykly v startup kóde (kopírovanie <code>.data</code> a nulovanie <code>.bss</code>) ako kopírovanie a vyplnenie a nahradí ich volaniami týchto dvoch funkcií, ktoré potom prinesú svoj kód z knižnice. Opraví to jeden flag na startup objekte a výsledok je <strong>276 B</strong>:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">target_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Startup </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> -fno-tree-loop-distribute-patterns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Okrem veľkosti je tu druhý dôvod, prečo sa o to starať: startup kód beží <em>skôr</em>, než je pamäť inicializovaná, a čím menej knižničného kódu používa, tým menej sa môže pokaziť (pozrite si článok o tom, <a class="" href="https://embedbits.cz/sk/blog/before-main-startup-linker">čo sa deje pred <code>main()</code></a>).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="po-linkovaní-čo-flashujete-a-čo-testujete">Po linkovaní: čo flashujete a čo testujete<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#po-linkovan%C3%AD-%C4%8Do-flashujete-a-%C4%8Do-testujete" class="hash-link" aria-label="Priamy odkaz na Po linkovaní: čo flashujete a čo testujete" title="Priamy odkaz na Po linkovaní: čo flashujete a čo testujete" translate="no">​</a></h2>
<p>Príkaz <code>POST_BUILD</code> vytvorí z ELF súboru <code>firmware.bin</code> a <code>firmware.hex</code> (formáty, ktoré čítajú programátory) a vypíše veľkosť. Posledná časť príkladu je test: <code>add_test</code> spustí firmware v QEMU a <code>ctest</code> skontroluje, že vypísal očakávaný text:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">ctest --test-dir build-debug</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">1/1 Test #1: firmware_runs_in_qemu ............   Passed    0.05 sec</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">100% tests passed, 0 tests failed out of 1</span><br></div></code></pre></div></div>
<p>Je to <em>smoke test</em> (naštartuje firmware a dostane sa do svojho <code>main()</code>?) a beží zlomok sekundy pri každom commite. Nenahrádza test na hardvéri, ale build, ktorý nenaštartuje, sa nájde v CI a nie pri stole. Testy modulov na PC sú iný build toho istého projektu CMake (ukazuje ho <a class="" href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock">článok o Unity a CMock</a>).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="checklist">Checklist<a href="https://embedbits.cz/sk/blog/cmake-for-embedded-firmware#checklist" class="hash-link" aria-label="Priamy odkaz na Checklist" title="Priamy odkaz na Checklist" translate="no">​</a></h2>
<ol>
<li class="">Toolchain file a <code>CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY</code>.</li>
<li class="">Flagy v jednom súbore s menami, predvolené hodnoty konfigurácií CMake vymazané.</li>
<li class="">Každý modul je knižnica s explicitným zoznamom zdrojákov a verejných hlavičiek.</li>
<li class=""><code>-ffunction-sections -fdata-sections</code> a <code>--gc-sections</code>, vždy.</li>
<li class=""><code>--print-memory-usage</code> a map súbor pri každom linkovaní, po ňom <code>size</code>.</li>
<li class=""><code>compile_commands.json</code> pre editor a statickú analýzu.</li>
<li class="">Linker script je závislosť firmvéru.</li>
<li class="">Smoke test v simulátore v CI.</li>
<li class="">Občas sa pozrite na veľkosť <em>release</em> buildu. Ak rastie bez dôvodu, map súbor vie prečo.</li>
</ol>]]></content:encoded>
            <category>Embedded</category>
            <category>CMake</category>
            <category>STM32</category>
        </item>
        <item>
            <title><![CDATA[Prerušenia a main(): ako bezpečne zdieľať dáta]]></title>
            <link>https://embedbits.cz/sk/blog/interrupts-and-main-shared-data</link>
            <guid>https://embedbits.cz/sk/blog/interrupts-and-main-shared-data</guid>
            <pubDate>Tue, 06 Oct 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[Obsluha prerušenia a hlavná slučka sú dva programy, ktoré bežia v tej istej pamäti a o sebe nevedia. Kompilátor C nevie, že prerušenie existuje, a CPU nevie, že dve premenné patria k sebe. Vie to jedine programátor a chyby, ktoré z toho vznikajú, sú najhoršieho druhu: objavia sa raz za tisíc behov, zmiznú, keď pripojíte debugger, a nikdy sa neobjavia pri code review, pretože kód vyzerá správne.]]></description>
            <content:encoded><![CDATA[<p>Obsluha prerušenia a hlavná slučka sú dva programy, ktoré bežia v tej istej pamäti a o sebe nevedia. Kompilátor C nevie, že prerušenie existuje, a CPU nevie, že dve premenné patria k sebe. Vie to jedine programátor a chyby, ktoré z toho vznikajú, sú najhoršieho druhu: objavia sa raz za tisíc behov, zmiznú, keď pripojíte debugger, a nikdy sa neobjavia pri code review, pretože kód vyzerá správne.</p>
<p>Tento článok prejde tri problémy zdieľaných dát jeden po druhom s kódom, ktorý <strong>zlyháva</strong>, a potom ukáže vzory, ktoré fungujú. Experimenty bežia na Cortex-M4 (v QEMU, na modeli dosky STM32F4) alebo na PC a výstupy sú skutočné.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="problém-1-kompilátor-nevidí-prerušenie">Problém 1: kompilátor nevidí prerušenie<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#probl%C3%A9m-1-kompil%C3%A1tor-nevid%C3%AD-preru%C5%A1enie" class="hash-link" aria-label="Priamy odkaz na Problém 1: kompilátor nevidí prerušenie" title="Priamy odkaz na Problém 1: kompilátor nevidí prerušenie" translate="no">​</a></h2>
<p>Najjednoduchšia komunikácia medzi prerušením a hlavnou slučkou je flag. Prerušenie ho nastaví, hlavná slučka naň čaká:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">main.c (a part)</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">USE_VOLATILE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">volatile</span><span class="token plain"> bool dataReady</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> bool dataReady</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">SysTick_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    dataReady </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">SysTick_Start</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">1000u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token plain">dataReady</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* waiting for the interrupt */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"the interrupt was seen\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Quit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Toto je celý program a s optimalizáciou <code>-O2</code> sa <strong>nikdy neskončí</strong>. Spustil som ho v QEMU so SysTick ako zdrojom prerušenia (prerušenie sa spustí a nastaví flag) a porovnal verziu s <code>volatile</code> a bez neho:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">--- without volatile</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">(no output, the program was killed by the timeout after 5 s)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">--- with volatile</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">the interrupt was seen</span><br></div></code></pre></div></div>
<p>Prečo? Pozrite sa, čo kompilátor vygeneroval pre slučku v prvej verzii:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000062:  ldrb  r3, [r1, #0]       @ read the flag once</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000064:  cbnz  r3, 8000068        @ non-zero: leave the loop</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000066:  b.n   8000066            @ zero: jump to itself, forever</span><br></div></code></pre></div></div>
<p>Kompilátor uvažuje iba o kóde <code>main()</code> a v tom kóde do <code>dataReady</code> nikto nezapisuje. Hodnota sa teda nemôže zmeniť, stačí ju prečítať raz a slučka sa zmení na nekonečnú. Presne to, o čo ste z jeho pohľadu požiadali. S <code>volatile</code> musí kompilátor premennú čítať z pamäte pri každom prechode:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000062:  ldrb  r3, [r2, #0]       @ read the flag in every pass</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000064:  cmp   r3, #0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000066:  beq.n 8000062</span><br></div></code></pre></div></div>
<p>Poučenie: <strong>každá premenná zdieľaná medzi prerušením a hlavným kódom musí byť <code>volatile</code>.</strong> To isté platí pre každý register periférie, a preto sú definície registrov v hlavičkách CMSIS <code>volatile</code>. Pamätajte, že v debug builde (<code>-O0</code>) to bez neho funguje a v release builde zlyhá, a preto sa chyba nájde neskoro.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="problém-2-volatile-neznamená-atomické">Problém 2: <code>volatile</code> neznamená atomické<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#probl%C3%A9m-2-volatile-neznamen%C3%A1-atomick%C3%A9" class="hash-link" aria-label="Priamy odkaz na problém-2-volatile-neznamená-atomické" title="Priamy odkaz na problém-2-volatile-neznamená-atomické" translate="no">​</a></h2>
<p><code>volatile</code> hovorí „čítaj a zapisuj pamäť zakaždým“. Nehovorí „naraz“. Nevinný riadok <code>counter++</code> sú tri inštrukcie:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Increment_Plain:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   ldr   r2, [pc, #8]       @ address of the counter</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   ldr   r3, [r2, #0]       @ 1. load the value</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   adds  r3, #1             @ 2. add one</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   str   r3, [r2, #0]       @ 3. store it back</span><br></div></code></pre></div></div>
<p>Ak prerušenie príde medzi načítaním a uložením a prerušenie tiež inkrementuje čítač, jedna z dvoch inkrementácií sa <strong>stratí</strong>: hlavný kód uloží starú hodnotu plus jedna cez hodnotu, ktorú práve uložilo prerušenie. Časová os:</p>



































<table><thead><tr><th>Krok</th><th>Hlavný kód</th><th>Prerušenie</th><th>Čítač</th></tr></thead><tbody><tr><td>1</td><td>načíta 5</td><td></td><td>5</td></tr><tr><td>2</td><td></td><td>načíta 5, pripočíta 1, uloží 6</td><td>6</td></tr><tr><td>3</td><td>pripočíta 1 (v registri má 5)</td><td></td><td>6</td></tr><tr><td>4</td><td>uloží 6</td><td></td><td><strong>6, malo byť 7</strong></td></tr></tbody></table>
<p>Chcel som to ukázať aj na Cortex-M4 a nevyšlo to: pri 200 000 inkrementáciách s prerušením každých pár inštrukcií QEMU nestratilo nič. Pravdepodobne preto, že QEMU kontroluje prerušenia medzi blokmi preloženého kódu, takže žiadne nepristane medzi <code>ldr</code> a <code>str</code>. Je to užitočná pripomienka, že <strong>simulátor nedokazuje neprítomnosť race condition</strong>: skutočné MCU môže prerušiť po každej inštrukcii. Ten istý race na mieste, kde sa dá ľahko reprodukovať, sú dve vlákna na PC:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">host_race.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;pthread.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdio.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">INCREMENTS</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">2000000u</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">volatile</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> plainCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">_Atomic</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain">  atomicCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token function" style="color:rgb(130, 170, 255)">Worker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">argument</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">argument</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> INCREMENTS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        plainCounter</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* load, add, store: not atomic */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_fetch_add</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">atomicCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* one indivisible operation    */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">pthread_t</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">pthread_create</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Worker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">pthread_create</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Worker</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">pthread_join</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">pthread_join</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">printf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"expected        %u\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> INCREMENTS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">printf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"plain counter   %u (lost %u)\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> plainCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> INCREMENTS </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> plainCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">printf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"atomic counter  %u (lost %u)\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> atomicCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> INCREMENTS </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> atomicCounter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">expected        4000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">plain counter   2652421 (lost 1347579)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">atomic counter  4000000 (lost 0)</span><br></div></code></pre></div></div>
<p>Tretina všetkých inkrementácií sa stratí a výsledky sa líšia beh od behu. Vlákno na PC a prerušenie na MCU sú v tomto ohľade to isté: druhý tok riadenia, ktorý môže udrieť medzi dve inštrukcie. To isté platí pre všetko, čo je väčšie ako slovo CPU: 64-bitová časová pečiatka alebo štruktúra s dvoma poľami sa môže prečítať napoly stará a napoly nová (<em>torn read</em>).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tri-spôsoby-riešenia">Tri spôsoby riešenia<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#tri-sp%C3%B4soby-rie%C5%A1enia" class="hash-link" aria-label="Priamy odkaz na Tri spôsoby riešenia" title="Priamy odkaz na Tri spôsoby riešenia" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-jeden-zapisovateľ-pre-každú-premennú-najlepší">1. Jeden zapisovateľ pre každú premennú (najlepší)<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#1-jeden-zapisovate%C4%BE-pre-ka%C5%BEd%C3%BA-premenn%C3%BA-najlep%C5%A1%C3%AD" class="hash-link" aria-label="Priamy odkaz na 1. Jeden zapisovateľ pre každú premennú (najlepší)" title="Priamy odkaz na 1. Jeden zapisovateľ pre každú premennú (najlepší)" translate="no">​</a></h3>
<p>Najrobustnejšie riešenie je navrhnúť dáta tak, aby <strong>každú premennú zapisovala len jedna strana</strong>. Prerušenie zapíše flag, hlavný kód ho iba číta a nemaže (alebo naopak). Bez dvoch zapisovateľov niet čo stratiť. Ak obe strany potrebujú meniť to isté, nemali by to zdieľať: každá má vlastnú premennú (čítač prerušení je <code>isrCalls</code>, čítač hlavného kódu je iný) a súčet urobí čitateľ.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-kritická-sekcia">2. Kritická sekcia<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#2-kritick%C3%A1-sekcia" class="hash-link" aria-label="Priamy odkaz na 2. Kritická sekcia" title="Priamy odkaz na 2. Kritická sekcia" translate="no">​</a></h3>
<p>Keď sa dvom zapisovateľom nedá vyhnúť, prerušenia sa na čas operácie zakážu. Správny spôsob je <strong>uložiť stav a obnoviť ho</strong>, a nie na konci slepo povoliť prerušenia, pretože funkcia mohla byť zavolaná s už zakázanými prerušeniami:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Increment_CriticalSection:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   mrs   r1, PRIMASK        @ save the state of the mask</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   cpsid i                  @ disable the interrupts</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   ldr   r3, [r2, #0]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   adds  r3, #1</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   str   r3, [r2, #0]</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   msr   PRIMASK, r1        @ restore the state, as it was</span><br></div></code></pre></div></div>
<p>Cenou je latencia: počas sekcie nemôže bežať žiadne prerušenie. Sekcia teda musí byť krátka, na pár inštrukcií, a bez volania funkcie, cyklu alebo čakania vo vnútri.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-atomická-operácia">3. Atomická operácia<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#3-atomick%C3%A1-oper%C3%A1cia" class="hash-link" aria-label="Priamy odkaz na 3. Atomická operácia" title="Priamy odkaz na 3. Atomická operácia" translate="no">​</a></h3>
<p>Pre jedno slovo (čítač, flag s počtom) má procesor inštrukcie <code>LDREX</code> a <code>STREX</code>: uloženie uspeje len vtedy, ak sa adresy od načítania nikto nedotkol, a ak sa dotkol, cyklus sa zopakuje. Kompilátor ich za vás vygeneruje zo štandardnej operácie:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Increment_Atomic:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   ldrex r1, [r3]           @ load and mark the address</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   adds  r1, #1</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   strex r2, r1, [r3]       @ store only if nobody has touched it, r2 = 0 on success</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   cmp   r2, #0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">   bne.n Increment_Atomic   @ somebody did: try again</span><br></div></code></pre></div></div>
<p>v C je to jeden riadok, <code>__atomic_fetch_add(&amp;counter, 1u, __ATOMIC_RELAXED)</code> (alebo <code>atomic_fetch_add()</code> z <code>&lt;stdatomic.h&gt;</code>). Neblokuje prerušenia, takže nepridáva latenciu. Funguje pre jednu premennú; pre dve premenné, ktoré patria k sebe, nepomôže.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="najpoužívanejší-vzor-kruhový-buffer">Najpoužívanejší vzor: kruhový buffer<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#najpou%C5%BE%C3%ADvanej%C5%A1%C3%AD-vzor-kruhov%C3%BD-buffer" class="hash-link" aria-label="Priamy odkaz na Najpoužívanejší vzor: kruhový buffer" title="Priamy odkaz na Najpoužívanejší vzor: kruhový buffer" translate="no">​</a></h2>
<p>Najčastejšia vec, ktorú prerušenie odovzdáva hlavnému kódu, je tok dát: bajty prijaté cez UART, vzorky z ADC. Prerušenie ich nemôže spracovať (musí byť krátke), a tak ich vloží do <strong>fronty</strong> a hlavný kód ich vyberie v pokojnej chvíli. Je to problém producent-konzument s <em>jedným producentom</em> (prerušenie) a <em>jedným konzumentom</em> (hlavný kód) a pre tento konkrétny prípad kruhový buffer <strong>nepotrebuje žiadny zámok</strong>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Ring.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">RING_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">RING_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdatomic.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">RING_SIZE</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">16u</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">                       </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* has to be a power of two */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">RING_MASK</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> RING_SIZE </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">-</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">1u</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/*</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Single producer, single consumer ring buffer without any lock.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * head: written only by the producer, tail: written only by the consumer.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Both are free-running counters, the difference is the number of items.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain">         items</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">RING_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">atomic_uint_fast32_t</span><span class="token plain"> head</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">atomic_uint_fast32_t</span><span class="token plain"> tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">ring_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> bool </span><span class="token function" style="color:rgb(130, 170, 255)">Ring_Push</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">ring_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ring</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> item</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint_fast32_t</span><span class="token plain"> head </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_load_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">head</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_relaxed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint_fast32_t</span><span class="token plain"> tail </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_load_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_acquire</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">RING_SIZE </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">head </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                            </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* full, the producer decides what to do */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">items</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">head </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> RING_MASK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> item</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_store_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">head</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> head </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_release</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* publish the item */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> bool </span><span class="token function" style="color:rgb(130, 170, 255)">Ring_Pop</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">ring_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ring</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">item</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint_fast32_t</span><span class="token plain"> tail </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_load_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_relaxed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint_fast32_t</span><span class="token plain"> head </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_load_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">head</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_acquire</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">head </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                            </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* empty */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">item </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">items</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">tail </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> RING_MASK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">atomic_store_explicit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">ring</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">tail</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> tail </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> memory_order_release</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* free the slot */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<p>Prečo je to správne?</p>
<ul>
<li class=""><code>head</code> zapisuje <strong>iba producent</strong> a <code>tail</code> <strong>iba konzument</strong>. Nie je tu premenná s dvoma zapisovateľmi, takže sa nemôže stratiť žiadna aktualizácia: je to prvé riešenie vyššie, zabudované do štruktúry.</li>
<li class="">Čítače sú voľne bežiace (nikdy sa neresetujú). Počet položiek je <code>head - tail</code> a vďaka aritmetike bez znamienka je správny aj po pretečení čítačov. Pri veľkosti, ktorá je mocninou dvojky, je pozícia jednoduchá maska namiesto delenia.</li>
<li class="">Záleží na <strong>poradí</strong>: producent zapíše položku a <strong>potom</strong> ju zverejní posunutím <code>head</code> (<code>memory_order_release</code>) a konzument číta najprv <code>head</code> (<code>memory_order_acquire</code>) a až potom položku. Na jedinom jadre Cortex-M je jediné, na čom záleží, poradie, v akom kompilátor zapisuje, a atomiky ho zachovávajú. Na MCU s dvoma jadrami (niektoré STM32H7 majú dve) alebo s cache je ten istý kód stále správny, čo je dôvod písať ho v tejto forme a nie s <code>volatile</code>, ktoré náhodou funguje.</li>
<li class="">Producent nečaká. Plný buffer znamená „zahoď položku a spočítaj ju“, pretože prerušenie nemôže na nikoho čakať. Počítadlo zahodených vám v teste povie, že buffer je primalý.</li>
</ul>
<p>Otestoval som to dvoma spôsobmi. Na PC s dvoma vláknami, producentom a konzumentom, prejde bufferom s 16 slotmi 20 miliónov položiek:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">items 20000000, order errors 0</span><br></div></code></pre></div></div>
<p>a na Cortex-M4 v QEMU: prerušenie SysTick je producent a <code>main()</code> konzument, s 5000 položkami:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">items received  5000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">order errors    0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">full buffer hits 0</span><br></div></code></pre></div></div>
<p>Prvý test je ťažší (dve vlákna naozaj bežia paralelne na dvoch jadrách), druhý je skutočná situácia MCU. Je to tiež perfektný kandidát na unit test na PC, ako v článku o <a class="" href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock">unit testovaní s Unity a CMock</a>: modul je nezávislý od hardvéru.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-pre-obsluhy-prerušení">Pravidlá pre obsluhy prerušení<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#pravidl%C3%A1-pre-obsluhy-preru%C5%A1en%C3%AD" class="hash-link" aria-label="Priamy odkaz na Pravidlá pre obsluhy prerušení" title="Priamy odkaz na Pravidlá pre obsluhy prerušení" translate="no">​</a></h2>
<ol>
<li class=""><strong>Krátke.</strong> Prečítajte register, uložte dáta, nastavte flag, zrušte pending flag, vráťte sa. Spracovanie sa robí v hlavnom kóde.</li>
<li class=""><strong>Žiadne čakanie, žiadna alokácia, žiadny <code>printf</code>.</strong> Nič, čo blokuje, trvá dlho alebo volá funkciu, ktorú nie je bezpečné volať z prerušenia (je <em>non-reentrant</em>, ak vo vnútri používa statický buffer).</li>
<li class=""><strong>Všetko zdieľané je <code>volatile</code> alebo atomické</strong> a každá premenná má definovaného zapisovateľa.</li>
<li class=""><strong>Nezdieľajte viac, než musíte.</strong> Flag alebo fronta medzi stranami, nie štruktúra s desiatimi poliami.</li>
<li class=""><strong>Myslite na prioritu.</strong> Prerušenie vyššej priority môže prerušiť iné prerušenie. Premenná zdieľaná medzi dvoma prerušeniami má rovnaký problém ako zdieľaná s hlavným kódom.</li>
</ol>
<p>V Embedbits BSP majú periférne moduly (napr. USART) variant spracovania dát s pollingom, s prerušením a s DMA a variant s prerušením je presne toto: obsluha na úrovni MCAL, ktorá berie dáta z periférie a odovzdáva ich aplikácii cez buffer, kým <code>Task</code> modulu beží v hlavnej slučke a robí spracovanie.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="zhrnutie">Zhrnutie<a href="https://embedbits.cz/sk/blog/interrupts-and-main-shared-data#zhrnutie" class="hash-link" aria-label="Priamy odkaz na Zhrnutie" title="Priamy odkaz na Zhrnutie" translate="no">​</a></h2>



































<table><thead><tr><th>Problém</th><th>Príznak</th><th>Liek</th></tr></thead><tbody><tr><td>Kompilátor nevidí prerušenie</td><td>Funguje s <code>-O0</code>, nekonečná slučka s <code>-O2</code></td><td><code>volatile</code> na každej zdieľanej premennej</td></tr><tr><td><code>counter++</code> nie je atomické</td><td>Počet, ktorý je občas primalý</td><td>Jeden zapisovateľ na premennú, kritická sekcia alebo <code>atomic_fetch_add</code></td></tr><tr><td>Viac než slovo</td><td>Napoly stará, napoly nová hodnota</td><td>Kritická sekcia, alebo poradové číslo, alebo fronta</td></tr><tr><td>Tok dát</td><td>Stratené alebo pomiešané bajty</td><td>Kruhový buffer s jedným producentom a jedným konzumentom</td></tr><tr><td>Test prejde v simulátore</td><td>Chyba v teréne</td><td>Pamätajte, že simulátor prerušuje na iných miestach než MCU</td></tr></tbody></table>
<p>Tri druhy kódu v tomto článku mali jedno spoločné: všetky <em>vyzerali</em> správne.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>STM32</category>
        </item>
        <item>
            <title><![CDATA[Konečné automaty v praxi: tlačidlo s debounce a dlhým stlačením]]></title>
            <link>https://embedbits.cz/sk/blog/fsm-in-practice-button</link>
            <guid>https://embedbits.cz/sk/blog/fsm-in-practice-button</guid>
            <pubDate>Tue, 06 Oct 2026 10:00:00 GMT</pubDate>
            <description><![CDATA[V prvom článku o konečných automatoch som vám dal šablónu a skončil som slovami „pokračovanie nabudúce“. Toto je to pokračovanie a najlepší spôsob, ako pokračovať v teórii, je problém. Vybral som taký, ktorý má každý embedded projekt a ktorý nikto nespraví správne na prvý pokus: tlačidlo.]]></description>
            <content:encoded><![CDATA[<p>V <a class="" href="https://embedbits.cz/sk/blog/finite-state-machines">prvom článku o konečných automatoch</a> som vám dal šablónu a skončil som slovami „pokračovanie nabudúce“. Toto je to pokračovanie a najlepší spôsob, ako pokračovať v teórii, je problém. Vybral som taký, ktorý má každý embedded projekt a ktorý nikto nespraví správne na prvý pokus: <strong>tlačidlo</strong>.</p>
<p>Tlačidlo vyzerá triviálne: pin, high alebo low. Lenže mechanický kontakt <em>poskakuje</em>, takže pin robí 1 0 1 1 0 1, kým sa ustáli, a produkt od jedného tlačidla zvyčajne chce dve rôzne veci: krátke a dlhé stlačenie. Napísané s príznakmi a počítadlami v hlavnej slučke to skončí ako zopár <code>if</code>ov, ktoré od seba závisia spôsobom, ktorý po mesiaci nikto nevie vysvetliť. Konečný automat to rieši spôsobom, ktorý viete vysvetliť tabuľkou.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="šablóna-v-jednom-odseku">Šablóna v jednom odseku<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#%C5%A1abl%C3%B3na-v-jednom-odseku" class="hash-link" aria-label="Priamy odkaz na Šablóna v jednom odseku" title="Priamy odkaz na Šablóna v jednom odseku" translate="no">​</a></h2>
<p>Každý stav má štyri rutiny a každá z nich má presne jednu úlohu:</p>






























<table><thead><tr><th>Rutina</th><th>Volá sa</th><th>Úloha</th></tr></thead><tbody><tr><td><code>Entry</code></td><td>raz, pri vstupe do stavu</td><td>pripraviť stav (vynulovať počítadlo, vytvoriť udalosť)</td></tr><tr><td><code>Execute</code></td><td>pri každom behu automatu, kým je v stave</td><td>vykonať prácu stavu (počítať, vzorkovať)</td></tr><tr><td><code>CheckLeave</code></td><td>pri každom behu, po <code>Execute</code></td><td>rozhodnúť, či stav opustiť a kam: <strong>jediné miesto, kde sa žiada prechod</strong></td></tr><tr><td><code>Leave</code></td><td>raz, pri opustení stavu</td><td>upratať</td></tr></tbody></table>
<p>Jadro automatu spúšťa <code>Execute</code> a <code>CheckLeave</code> aktuálneho stavu a keď sa stav zmenil, spustí <code>Leave</code> starého a <code>Entry</code> nového. Rutiny sa navzájom nikdy nevolajú a kód automatu neobsahuje nič iné než automat. Ak chcete vedieť, prečo je zariadenie v nejakom stave, prečítate <code>CheckLeave</code> predchádzajúceho.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="najprv-návrh-stavy-a-prechody">Najprv návrh: stavy a prechody<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#najprv-n%C3%A1vrh-stavy-a-prechody" class="hash-link" aria-label="Priamy odkaz na Najprv návrh: stavy a prechody" title="Priamy odkaz na Najprv návrh: stavy a prechody" translate="no">​</a></h2>
<p>Úloha beží každých 10 ms a číta surový kontakt. Čas debounce je 50 ms a hranica dlhého stlačenia je 1 sekunda. Stačí päť stavov:</p>





















































<table><thead><tr><th>Stav</th><th>Execute</th><th>Opúšťa sa, keď</th><th>Kam</th></tr></thead><tbody><tr><td><code>RELEASED</code></td><td>nič</td><td>kontakt je zatvorený</td><td><code>DEBOUNCE_PRESS</code></td></tr><tr><td><code>DEBOUNCE_PRESS</code></td><td>počíta tiky</td><td>kontakt sa znova otvorí (bol to glitch)</td><td><code>RELEASED</code></td></tr><tr><td></td><td></td><td>kontakt bol zatvorený 50 ms</td><td><code>PRESSED</code></td></tr><tr><td><code>PRESSED</code></td><td>počíta tiky</td><td>kontakt sa otvorí: udalosť <strong>krátke stlačenie</strong></td><td><code>DEBOUNCE_RELEASE</code></td></tr><tr><td></td><td></td><td>kontakt je zatvorený 1 s</td><td><code>LONG_PRESS</code></td></tr><tr><td><code>LONG_PRESS</code></td><td>nič, udalosť <strong>dlhé stlačenie</strong> sa vytvorila pri vstupe</td><td>kontakt sa otvorí</td><td><code>DEBOUNCE_RELEASE</code></td></tr><tr><td><code>DEBOUNCE_RELEASE</code></td><td>počíta tiky otvoreného kontaktu, poskočenie vynuluje počítadlo</td><td>kontakt bol otvorený 50 ms</td><td><code>RELEASED</code></td></tr></tbody></table>
<p>Písanie tabuľky je skutočná práca. Keď je kompletná, kód je len písanie na stroji. Keď nie je (čo sa stane v <code>LONG_PRESS</code>, keď kontakt poskakuje pri uvoľnení?), tabuľka ukáže dieru ešte predtým, než napíšete riadok v C.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kód">Kód<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#k%C3%B3d" class="hash-link" aria-label="Priamy odkaz na Kód" title="Priamy odkaz na Kód" translate="no">​</a></h2>
<p>Vstup prichádza z BSP, takže modul nemá závislosť na hardvéri a dá sa testovať na PC (rovnaký <em>seam</em> ako v článku o <a class="" href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock">unit testovaní</a>). Port modulu tvorí <code>Init</code>, <code>Task</code> a funkcia, ktorá vráti udalosť jednorazovo:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Button_Port.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">BUTTON_BUTTON_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">BUTTON_BUTTON_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_EVENT_NONE </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_EVENT_SHORT_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_EVENT_LONG_PRESS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_Event_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">           </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">           </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* call it every 10 ms */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">button_Event_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Get_Event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* returns the event once and clears it */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<p>Typy sledujú šablónu. Je tu jedna zmena, ktorú som urobil zámerne: tabuľka rutín je <strong>indexovaná stavom</strong> a nehľadá sa v nej a enumerácia končí <code>BUTTON_STATE_COUNT</code>, ktorá má dve použitia.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Button.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_RELEASED </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Contact open, waiting for a press      */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_DEBOUNCE_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Contact closed, is it stable?          */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_PRESSED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Stable press, short or long?           */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_LONG_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Held longer than the limit             */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_DEBOUNCE_RELEASE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Contact open again, is it stable?      */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    BUTTON_STATE_COUNT             </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Number of the states, keep it the last */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_States_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_PtrToRoutine_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_PtrToRoutine_t</span><span class="token plain"> entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_PtrToRoutine_t</span><span class="token plain"> execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_PtrToRoutine_t</span><span class="token plain"> checkLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_PtrToRoutine_t</span><span class="token plain"> leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_Routines_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Prvým použitím je samotná tabuľka. S designated initializers nezáleží na polohe riadku, takže stav sa nedá prepojiť so zlými rutinami, keď niekto pridá riadok do stredu (šablóna potrebuje komentár „toto pole musí mať rovnaké poradie ako enum stavov“):</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Button.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The table is indexed by the state, so the order of the lines does not matter. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_SM_Routines_t</span><span class="token plain"> stateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_COUNT</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_RELEASED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain">         </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Button_Released_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">        Button_Released_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                        Button_Released_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   Button_Released_Leave        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_DEBOUNCE_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain">   </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Button_DebouncePress_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   Button_DebouncePress_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                        Button_DebouncePress_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Button_DebouncePress_Leave </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_PRESSED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain">          </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Button_Pressed_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">         Button_Pressed_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                        Button_Pressed_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">    Button_Pressed_Leave         </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_LONG_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain">       </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Button_LongPress_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">       Button_LongPress_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                        Button_LongPress_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">  Button_LongPress_Leave       </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">BUTTON_STATE_DEBOUNCE_RELEASE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Button_DebounceRelease_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Button_DebounceRelease_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                        Button_DebounceRelease_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Button_DebounceRelease_Leave </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Druhým použitím je jadro automatu, v ktorom tá istá konštanta nahrádza natvrdo zapísaný „posledný stav“ pri kontrole rozsahu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Button.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_HandleStateTransition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_STATE_COUNT </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> newState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_RELEASED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">      </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* invalid request: go to the safe state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    stateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">actualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    stateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">actualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">checkLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">actualState </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> newState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        stateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">actualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        actualState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> newState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        stateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">actualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Všimnite si, čo jadro <em>nevie</em>: tlačidlá, čas, udalosti. Teraz stavy. Väčšina rutín sú jednoriadkovky:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Button.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- RELEASED ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Released_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Released_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Released_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">isContactClosed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_DEBOUNCE_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Released_Leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- DEBOUNCE_PRESS: closed, but is it only a bounce? ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebouncePress_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebouncePress_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebouncePress_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token plain">isContactClosed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_RELEASED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">               </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* a glitch, nothing happened */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_DEBOUNCE_TICKS </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> stateTicks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_PRESSED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebouncePress_Leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- PRESSED: a short press if released early, a long one if held ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token plain">isContactClosed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        pendingEvent </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_EVENT_SHORT_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        newState     </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_DEBOUNCE_RELEASE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_LONG_PRESS_TICKS </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> stateTicks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_LONG_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Pressed_Leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- LONG_PRESS: the event is created once, on the entry ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_LongPress_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> pendingEvent </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_EVENT_LONG_PRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_LongPress_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_LongPress_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token plain">isContactClosed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_DEBOUNCE_RELEASE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_LongPress_Leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ---- DEBOUNCE_RELEASE: open, has to stay open for the debounce time ---- */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebounceRelease_Entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebounceRelease_Execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> isContactClosed </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">stateTicks </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebounceRelease_CheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_DEBOUNCE_TICKS </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> stateTicks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> newState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> BUTTON_STATE_RELEASED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_DebounceRelease_Leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Niekoľko detailov, ktoré stoja za pozornosť:</p>
<ul>
<li class=""><code>Button_Task()</code> číta vstup <strong>raz</strong> za beh a drží ho v <code>isContactClosed</code>. Všetky rutiny jedného behu vidia tú istú hodnotu, aj keď sa pin zmení uprostred behu.</li>
<li class="">Udalosť krátkeho stlačenia sa vytvára v <code>Button_Pressed_CheckLeave()</code>, na tom istom mieste, kde sa robí rozhodnutie. Udalosť dlhého stlačenia sa vytvára v <code>Button_LongPress_Entry()</code>: entry sa volá presne raz za prechod, takže udalosť sa nedá vytvoriť dvakrát, nech kontakt robí počas držania tlačidla čokoľvek.</li>
<li class="">Debounce uvoľnenia (<code>DEBOUNCE_RELEASE</code>) vynuluje svoje počítadlo vždy, keď sa kontakt opäť zatvorí. To je odpoveď na poskakovanie pri uvoľnení: automat čaká, kým je kontakt 50 ms pokojný.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="test">Test<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#test" class="hash-link" aria-label="Priamy odkaz na Test" title="Priamy odkaz na Test" translate="no">​</a></h2>
<p>Test nahradí <code>Bsp_Get_ButtonRaw()</code> funkciou, ktorá číta reťazec: jeden znak na 10 ms tik, <code>1</code> je zatvorený kontakt. Vzory sú príbehom tlačidla a výsledkom je reťazec udalostí, <code>S</code> pre krátke stlačenie a <code>L</code> pre dlhé:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">test_Button.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The fake input: one character per 10 ms tick, '1' = contact closed. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">inputPattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain">      inputIndex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_ButtonRaw</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> symbol </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> inputPattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">inputIndex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token char" style="color:rgb(130, 170, 255)">'\0'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> symbol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> inputIndex</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token char" style="color:rgb(130, 170, 255)">'1'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> symbol</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Runs the machine over the whole pattern and returns the events as a string, S = short, L = long. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token function" style="color:rgb(130, 170, 255)">Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">pattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">16</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> count </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    inputPattern </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> pattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    inputIndex   </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">memset</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> tick </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> tick </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">strlen</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">pattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">20u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> tick</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 20 extra ticks of an open contact */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">button_Event_t</span><span class="token plain"> event </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Button_Get_Event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_EVENT_SHORT_PRESS </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">count</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'S'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">BUTTON_EVENT_LONG_PRESS  </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">count</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'L'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> events</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">pattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">expected</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">pattern</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">printf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"%-34s -&gt; %s\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> name</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token char" style="color:rgb(130, 170, 255)">'\0'</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"(no event)"</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">strcmp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">expected</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">220</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"nothing happens"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                 </span><span class="token string" style="color:rgb(195, 232, 141)">"0000000000"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                              </span><span class="token string" style="color:rgb(195, 232, 141)">""</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a 20 ms glitch"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                  </span><span class="token string" style="color:rgb(195, 232, 141)">"0011000000"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                              </span><span class="token string" style="color:rgb(195, 232, 141)">""</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a clean 200 ms press"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">            </span><span class="token string" style="color:rgb(195, 232, 141)">"00111111111111111111110000000000"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">        </span><span class="token string" style="color:rgb(195, 232, 141)">"S"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a press with a bouncing contact"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"0101101111111111111111011010000000000"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   </span><span class="token string" style="color:rgb(195, 232, 141)">"S"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a bounce on the release"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">         </span><span class="token string" style="color:rgb(195, 232, 141)">"001111111111111111111101001000000000"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">    </span><span class="token string" style="color:rgb(195, 232, 141)">"S"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">memset</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">150u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">150</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'\0'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 1.5 s */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a 1.5 s hold"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                    longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                                  </span><span class="token string" style="color:rgb(195, 232, 141)">"L"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">memset</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'1'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">99u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">99</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token char" style="color:rgb(130, 170, 255)">'\0'</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* just under the limit (+ debounce) */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"a 0.99 s hold"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                   longHold</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">                                  </span><span class="token string" style="color:rgb(195, 232, 141)">"S"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">puts</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"all state machine tests passed"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Výstup behu je skutočný:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">nothing happens                    -&gt; (no event)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a 20 ms glitch                     -&gt; (no event)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a clean 200 ms press               -&gt; S</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a press with a bouncing contact    -&gt; S</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a bounce on the release            -&gt; S</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a 1.5 s hold                       -&gt; L</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">a 0.99 s hold                      -&gt; S</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">all state machine tests passed</span><br></div></code></pre></div></div>
<p>Posledné dva riadky sú prípad, ktorý príznaky vždy pokazia. Podržanie na 1,5 sekundy vyprodukuje <strong>jedno</strong> dlhé stlačenie a žiadne krátke stlačenie po uvoľnení a podržanie tesne pod hranicou je krátke stlačenie. Oboje je dôsledkom tabuľky a nie opatrného programovania.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-získate-a-čo-to-stojí">Čo získate a čo to stojí<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#%C4%8Do-z%C3%ADskate-a-%C4%8Do-to-stoj%C3%AD" class="hash-link" aria-label="Priamy odkaz na Čo získate a čo to stojí" title="Priamy odkaz na Čo získate a čo to stojí" translate="no">​</a></h2>
<p><strong>Získate:</strong></p>
<ul>
<li class=""><strong>čitateľnú špecifikáciu</strong>: tabuľka vyššie a kód sú tá istá vec,</li>
<li class=""><strong>záruku jedného razu</strong>: <code>Entry</code> a <code>Leave</code> bežia raz za prechod, udalosti sa neduplikujú,</li>
<li class=""><strong>miesto pre všetko</strong>: nová požiadavka (dvojklik) je nový stav alebo nový riadok v tabuľke, a nie úprava troch vnorených podmienok,</li>
<li class=""><strong>automat, ktorý sa dá testovať na PC</strong> s reťazcom ako vstupom, ako ste práve videli.</li>
</ul>
<p><strong>Stojí to:</strong></p>
<ul>
<li class=""><strong>boilerplate</strong>: štyri funkcie na stav, väčšina z nich prázdna. Je to cena za jednotnosť a vyplatí sa od 5. stavu. Pre automat s dvoma stavmi je lepší <code>switch</code>,</li>
<li class=""><strong>tabuľku prechodov treba premyslieť</strong> skôr, než napíšete kód. To nie je náklad, ale na začiatku sa tak cíti.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="úskalia">Úskalia<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#%C3%BAskalia" class="hash-link" aria-label="Priamy odkaz na Úskalia" title="Priamy odkaz na Úskalia" translate="no">​</a></h2>
<ol>
<li class=""><strong>Čas patrí perióde úlohy, nie delayu.</strong> Automat počíta behy, takže limity (50 ms, 1 s) sú počty tikov. Nikdy nevolajte delay v stave, blokuje všetky ostatné automaty.</li>
<li class=""><strong>Vzorkujte v úlohe, nie v prerušení.</strong> Prerušenie od pinu by videlo každé poskočenie. Úloha, ktorá beží každých 10 ms, je dolnopriepustný filter zadarmo.</li>
<li class=""><strong>Jediný slot pre udalosť stráca udalosti</strong>, ak ho aplikácia číta pomalšie, než ich automat produkuje. Pri tlačidle to nevadí, pri protokole áno: použite frontu.</li>
<li class=""><strong>Neplatný stav je stav.</strong> Kontrola rozsahu v jadre pošle poškodenú premennú do bezpečného stavu namiesto čítania tabuľky mimo jej hraníc (platia tu pravidlá MISRA o <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">nedefinovanom správaní</a>).</li>
<li class=""><strong>Automat s 30 stavmi je znakom chýbajúcej hierarchie.</strong> Rozdeľte ho na niekoľko automatov, kde jeden je <em>stavom</em> druhého, a každý nechajte dosť malý, aby sa zmestil do tabuľky na jednej obrazovke.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="opravy-v-šablóne">Opravy v šablóne<a href="https://embedbits.cz/sk/blog/fsm-in-practice-button#opravy-v-%C5%A1abl%C3%B3ne" class="hash-link" aria-label="Priamy odkaz na Opravy v šablóne" title="Priamy odkaz na Opravy v šablóne" translate="no">​</a></h2>
<p>Keď som porovnal príklad so šablónou z prvého článku, našiel som v šablóne dve chyby a opravil som ich tam (neskoršia revízia šablóny našla ďalšie, pozri <a class="" href="https://embedbits.cz/sk/blog/finite-state-machines#what-was-fixed">zoznam opráv</a>): počiatočná hodnota stavových premenných bola pozostatkom názvu z iného projektu (<code>APPCORE_HANDLER_STATE_1</code> namiesto <code>&lt;MODULE&gt;_STATE_1</code>) a posledný riadok tabuľky používal <code>State_2_Leave</code> namiesto <code>State_3_Leave</code>. Tá druhá je typ chyby, o ktorej tento článok je: kód sa skompiluje a automat pri opustení tretieho stavu zavolá zlú rutinu. Tabuľka s designated initializers to trochu sťažuje a test, ktorý prejde všetky stavy, to znemožňuje.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>Architektúra</category>
        </item>
        <item>
            <title><![CDATA[Jeden BSP, mnoho rodín STM32: prečo Git vetvy a čo stoja]]></title>
            <link>https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches</link>
            <guid>https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches</guid>
            <pubDate>Mon, 05 Oct 2026 18:00:00 GMT</pubDate>
            <description><![CDATA[STM32 nie je jeden mikrokontrolér, je to tucet rodín: G4, H5, U5, F4 a ďalšie. Majú rovnaké jadro Cortex-M, ale odlišnú periférnu výbavu, odlišné názvy registrov a iný balík ovládačov od výrobcu. Ak chcete, aby jedna architektúra firmvéru bežala na všetkých, musíte rozhodnúť, kde budú rozdiely žiť. Zadarmo sa to nedá a tento článok opisuje variant, ktorý som zvolil pre Embedbits BSP, čo o ňom hovoria čísla zo skutočných repozitárov a koľko stojí.]]></description>
            <content:encoded><![CDATA[<p>STM32 nie je jeden mikrokontrolér, je to tucet rodín: G4, H5, U5, F4 a ďalšie. Majú rovnaké jadro Cortex-M, ale odlišnú periférnu výbavu, odlišné názvy registrov a iný balík ovládačov od výrobcu. Ak chcete, aby jedna architektúra firmvéru bežala na všetkých, musíte rozhodnúť, kde budú rozdiely žiť. Zadarmo sa to nedá a tento článok opisuje variant, ktorý som zvolil pre Embedbits BSP, čo o ňom hovoria čísla zo skutočných repozitárov a koľko stojí.</p>
<!-- -->
<p>Všetky čísla nižšie pochádzajú z repozitárov k 5. októbru 2026 a boli zmerané malým skriptom, ktorý nájdete na konci časti o nákladoch. Poznámka k dátumu: v tom momente je <strong>STM32F4 jedinou rodinou s kompletným vydaním</strong> BSP a vydanie ostatných (ako prvé U5) sa práve robilo. Čísla teda ukazujú platformu uprostred migrácie, nie konečný stav, a práve to ich robí zaujímavými. Spustite skript znova po vydaní a porovnajte.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="štyri-spôsoby-ako-podporiť-viac-rodín">Štyri spôsoby, ako podporiť viac rodín<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#%C5%A1tyri-sp%C3%B4soby-ako-podpori%C5%A5-viac-rod%C3%ADn" class="hash-link" aria-label="Priamy odkaz na Štyri spôsoby, ako podporiť viac rodín" title="Priamy odkaz na Štyri spôsoby, ako podporiť viac rodín" translate="no">​</a></h2>






























<table><thead><tr><th>Prístup</th><th>Ako vyzerá</th><th>Problém</th></tr></thead><tbody><tr><td><strong>Jeden strom, <code>#ifdef</code></strong></td><td><code>#if defined(STM32G4) ... #elif defined(STM32U5) ...</code> v kóde</td><td>Kód sa zaplní podmienkami, väčšina z neho je pre konkrétny build mŕtva (pozrite si pravidlá o mŕtvom kóde v článku o <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">MISRA</a>) a nikto sa ho neodváži zmeniť</td></tr><tr><td><strong>Copy and paste</strong></td><td>Priečinok pre každú rodinu, kópia všetkého</td><td>Každá oprava sa musí urobiť N-krát ručne a jedna sa zabudne</td></tr><tr><td><strong>Jeden repozitár na rodinu</strong></td><td><code>Bsp-G4</code>, <code>Bsp-U5</code>, ...</td><td>To isté ako kópia, len s viacerými repozitármi</td></tr><tr><td><strong>Abstrakcia + vetva na rodinu</strong></td><td>Jedno rozhranie, rodina žije vo vetve</td><td>Vetva sa môže od ostatných vzďaľovať (pozri nižšie)</td></tr></tbody></table>
<p>Používam posledný variant. Myšlienka je, že používateľ vyberie rodinu <strong>raz</strong> a odvtedy strom obsahuje iba kód tej rodiny.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ako-to-funguje-v-bsp">Ako to funguje v BSP<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#ako-to-funguje-v-bsp" class="hash-link" aria-label="Priamy odkaz na Ako to funguje v BSP" title="Priamy odkaz na Ako to funguje v BSP" translate="no">​</a></h2>
<p>Každá rodina STM32 je <strong>vetva Gitu</strong> repozitára BSP (<code>STM32G4</code>, <code>STM32H5</code>, <code>STM32U5</code>, ...). To isté platí pre moduly BSP: moduly MCAL, linker a RAL. Zvyšok urobí platforma. Keď spustíte inštalačný skript EmBi_Platform a vyberiete <em>Configure BSP module</em>, zobrazí zoznam vetiev:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Available BSP Families:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[0]: STM32G4</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[1]: STM32G4_Dev</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[2]: STM32H5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[3]: STM32H5_Dev</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[4]: STM32U5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">[5]: master</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Enter branch ID (numerical):</span><br></div></code></pre></div></div>
<p>a po vašom výbere pridá moduly BSP ako submoduly Gitu, prepne vetvu a commity danej rodiny a aktualizuje súbory CMake. Projekt je pripnutý na presné commity, takže zajtra sa zostaví rovnako. Položky s <code>_Dev</code> sú vývojové vetvy rodiny a <code>master</code> obsahuje najnovšie nevydané zmeny všetkých rodín, takže je určený na prácu na platforme, nie na produkt. Prepnutie na inú rodinu znamená spustiť tú istú voľbu znova.</p>
<p>Balík ovládačov od výrobcu sleduje rovnakú schému. RAL má vetvy <code>STM32&lt;family&gt;</code> pre rodinu, <code>STM32&lt;family&gt;_&lt;major&gt;.x</code> pre hlavné vydanie ovládačov ST a <code>STM32&lt;family&gt;_&lt;major&gt;.&lt;minor&gt;</code> pre vedľajšie. Keď ST zverejní novú verziu, vznikne nová vetva a stará zostane dostupná pre projekty, ktoré ju používajú.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kde-sú-skutočné-rozdiely">Kde sú skutočné rozdiely<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#kde-s%C3%BA-skuto%C4%8Dn%C3%A9-rozdiely" class="hash-link" aria-label="Priamy odkaz na Kde sú skutočné rozdiely" title="Priamy odkaz na Kde sú skutočné rozdiely" translate="no">​</a></h2>
<p>Chcel som vedieť, koľko kódu sa medzi rodinami skutočne líši, a tak som porovnal vetvy. Tu je modul GPIO, <code>Bsp-Mcal-Gpio</code>, s vydaným STM32F4 ako referenciou. Čísla sú zmenené riadky (pridané plus odstránené) v každom súbore:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">file               STM32F4 vs STM32G4   STM32F4 vs STM32H5   STM32F4 vs STM32U5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Gpio.c             306                  142                  303</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Gpio.h             5                    0                    0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Gpio_Port.h        3                    0                    0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Gpio_Types.h       35                   5                    28</span><br></div></code></pre></div></div>
<p>Verejné rozhranie, <code>Gpio_Port.h</code>, je na F4 a H5 <strong>identické</strong> a na G4 a U5 sa líši v troch riadkoch komentára. G4 a U5 sú si blízke (ich <code>Gpio.c</code> sa líši v troch riadkoch, opäť len komentár): sú to staršia generácia modulu, ktorá čaká na vydanie. Prečo je <em>kód modulu</em> taký podobný naprieč dvoma rôznymi rodinami? Pretože rozdiel bol vytlačený z modulu do najnižšej vrstvy. RAL má priečinok <code>Port</code> s jednou hlavičkou pre každú periférnu jednotku a celý rozdiel medzi rodinami v <code>Stm32_gpio.h</code> je toto:</p>
<div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token deleted-sign deleted prefix deleted" style="color:rgb(255, 85, 114)">-</span><span class="token deleted-sign deleted line" style="color:rgb(255, 85, 114)">#include "stm32g4xx_ll_gpio.h"              /* GPIO peripheral access layer   */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token deleted-sign deleted line" style="color:rgb(255, 85, 114)"></span><span class="token inserted-sign inserted prefix inserted" style="color:rgb(195, 232, 141)">+</span><span class="token inserted-sign inserted line" style="color:rgb(195, 232, 141)">#include "stm32u5xx_ll_gpio.h"              /* GPIO peripheral access layer   */</span><br></div></code></pre></div></div>
<p>Jeden riadok. Modul MCAL includuje <code>Stm32_gpio.h</code> a nikdy nevie, ktorý ovládač výrobcu je za ním. To isté platí pre ostatné periférie, ktoré som porovnal medzi G4 a U5 (<code>Stm32_rcc.h</code>, <code>Stm32_usart.h</code>, <code>Stm32_tim.h</code>): dva odlišné riadky z 32. To je celá myšlienka vrstvenej architektúry, aplikovaná na otázku rodín.</p>
<p>Čo sa naozaj líši, sú <strong>sady periférií</strong>. Priečinok <code>Port</code> pre G4 má hlavičky pre HRTIM a DMAMUX, ktoré U5 nemá, a U5 má cache, PKA, SDMMC a low-power GPIO, ktoré G4 nemá. Modul pre periféria, ktoré rodina nemá, sa v jej vetve jednoducho nenachádza, a odtiaľ pochádza tabuľka <em>podpory rodín</em> na stránke o <a class="" href="https://embedbits.cz/sk/docs/bsp/mcal">MCAL</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="dve-úrovne-rodina-a-mcu">Dve úrovne: rodina a MCU<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#dve-%C3%BArovne-rodina-a-mcu" class="hash-link" aria-label="Priamy odkaz na Dve úrovne: rodina a MCU" title="Priamy odkaz na Dve úrovne: rodina a MCU" translate="no">​</a></h3>
<p>Vetva rieši rozdiel medzi <em>rodinami</em>. <em>Vnútri</em> rodiny je menší rozdiel: jednotlivé MCU majú rôzny počet portov (MCU v malom puzdre má menej portov GPIO než to vo veľkom puzdre). To sa rieši podmienkou na makrách, ktoré hlavičkový súbor zariadenia od výrobcu už definuje, nie vetvou:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortConfig_t</span><span class="token plain">      gpio_PeriphConf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain"> GPIO_PORT_CNT </span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">if</span><span class="token macro property"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">defined</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">GPIOA</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioReg </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIOA</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioRcc </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> RCC_PERIPH_GPIOA </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ... */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">if</span><span class="token macro property"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">defined</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">GPIOJ</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioReg </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIOJ</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioRcc </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> RCC_PERIPH_GPIOJ </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">if</span><span class="token macro property"> </span><span class="token macro property expression function" style="color:rgb(130, 170, 255)">defined</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">GPIOK</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioReg </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIOK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">GpioRcc </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> RCC_PERIPH_GPIOK </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>a v typoch sa port, ktorý neexistuje, mapuje na hodnotu <code>GPIO_PORT_CNT</code>, takže ostatné moduly sa stále skompilujú a použitie takého portu sa dá rozpoznať ako neplatné. Pravidlo: <strong>vetva pre inú rodinu, <code>#if defined</code> makra výrobcu pre iné MCU v tej istej rodine.</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-získate">Čo získate<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#%C4%8Do-z%C3%ADskate" class="hash-link" aria-label="Priamy odkaz na Čo získate" title="Priamy odkaz na Čo získate" translate="no">​</a></h2>
<ul>
<li class=""><strong>Iba kód danej rodiny.</strong> Žiadne lesy <code>#ifdef</code>, nič nie je mŕtve a diff zmeny ukazuje iba kód, ktorý sa zostavuje.</li>
<li class=""><strong>Čisté oddelenie kódu výrobcu.</strong> Ovládače ST pre každú rodinu sú zrkadlené vo vlastných vetvách RAL a nie sú upravované. Váš kód ich neobsahuje.</li>
<li class=""><strong>Stabilné rozhranie pre aplikáciu.</strong> Aplikácia volá <code>Gpio_Set_PinLevel()</code> a nepozná rodinu, takže zmena MCU je iná vetva, nie prepísanie aplikácie.</li>
<li class=""><strong>Pripnuté verzie.</strong> Projekt presne určuje, ktorý commit ktorej vetvy používa, takže aktualizácia je vedomé rozhodnutie.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-to-stojí-drift">Čo to stojí: drift<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#%C4%8Do-to-stoj%C3%AD-drift" class="hash-link" aria-label="Priamy odkaz na Čo to stojí: drift" title="Priamy odkaz na Čo to stojí: drift" translate="no">​</a></h2>
<p>Slabinou vetiev je, že žijú vlastným životom. Oprava urobená v jednej vetve nie je v ostatných, kým ju tam niekto neprenesie. Meranie vyššie ukazuje dve <em>generácie</em> toho istého modulu naraz. Vydané F4 (a H5, ktoré za ním nasleduje) má prepracovanú inicializáciu GPIO (výstupná úroveň sa nastaví <em>pred</em> prepnutím režimu pinu na výstup, aby pin negeneroval glitch), zdokumentované parametre a priečinok <code>Tests</code> s <strong>unit testami a integračnými testami</strong>. G4 a U5 nič z toho zatiaľ nemajú. Verejné rozhranie USART v <code>Usart_Port.h</code> to ukazuje ešte lepšie:</p>






























<table><thead><tr><th>Vetva</th><th>Verejné funkcie</th><th>V porovnaní s F4</th></tr></thead><tbody><tr><td>STM32F4 (vydaná)</td><td>79</td><td>referencia</td></tr><tr><td>STM32H5</td><td>79</td><td>rovnaká sada funkcií, hlavička sa líši v 2 riadkoch</td></tr><tr><td>STM32G4</td><td>82</td><td>12 funkcií, ktoré F4 nemá (<code>Usart_StartTransmit</code>, <code>Usart_Set_TransmitBytes</code>, ...) a 9, ktoré F4 má a G4 nie (<code>Usart_Set_TxStart</code>, <code>Usart_Set_DataConfig</code>, ...)</td></tr><tr><td>STM32U5</td><td>83</td><td>13 funkcií len na U5, 9 len na F4</td></tr></tbody></table>
<p>V tejto chvíli sa kód napísaný voči rozhraniu F4 skompiluje na H5 a neskompiluje na G4 a U5. Nie je to chyba prístupu, je to normálny stav platformy uprostred vydania. Ukazuje to však cenu: sľub „rovnaké rozhranie BSP pre všetky rodiny“ platí pre rodinu až <strong>po vydaní jej vetvy</strong> a čas medzi vydaním prvej a poslednej rodiny je obdobie, v ktorom sa vetvy od seba vzďaľujú. Počas neho by nikto nemal písať aplikáciu pre rodinu, ktorá nie je pripravená.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ako-držať-drift-pod-kontrolou">Ako držať drift pod kontrolou<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#ako-dr%C5%BEa%C5%A5-drift-pod-kontrolou" class="hash-link" aria-label="Priamy odkaz na Ako držať drift pod kontrolou" title="Priamy odkaz na Ako držať drift pod kontrolou" translate="no">​</a></h3>
<ol>
<li class=""><strong>Majte referenčnú vetvu a zoznam toho, čo je portované.</strong> Jedna rodina vedie (tu F4), ostatné ju nasledujú a stav je viditeľný: je to tabuľka podpory rodín na stránke MCAL, rozšírená o „rovnakú verziu rozhrania ako referencia“.</li>
<li class=""><strong>Urobte z vydania jednu operáciu.</strong> Skript vydania, ktorý prejde všetky moduly jednej rodiny (tak, ako sa robí vydanie U5), je lepší než ručný merge: rodina je buď pripravená celá, alebo nie je.</li>
<li class=""><strong>Merajte drift.</strong> Skript nižšie porovná jeden modul na viacerých vetvách a vypíše počet zmenených riadkov na súbor. Nula alebo komentár znamená „rovnaké“, veľké číslo je práca, ktorá čaká. Trvá to sekundu a zmestí sa to do jobu CI.</li>
<li class=""><strong>Nechajte jednu sadu testov kontrolovať všetky vetvy.</strong> Unit testy, ktoré existujú na F4 (a H5), sú špecifikáciou modulu. Ak musí ten istý <code>Test_Gpio.c</code> prejsť na každej vetve rodiny, rozhranie sa nemôže potichu rozísť. Článok o <a class="" href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock">unit testovaní</a> ukazuje, ako sa takýto test stavia.</li>
<li class=""><strong>Držte rozdiel naspodku.</strong> Všetko, čo sa dá presunúť do hlavičiek <code>Port</code> v RAL (jediný <code>#include</code>, ako je ukázané vyššie), je rozdiel, ktorý netreba udržiavať pre každú vetvu zvlášť. Čím viac kódu je <em>identického</em>, tým ľahšie je preniesť opravu z jednej vetvy do druhej (<code>git cherry-pick</code>).</li>
</ol>
<div class="language-sh codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">branch-drift.sh</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-sh codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token shebang important">#!/usr/bin/env bash</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Shows how much a module differs between its family branches.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Usage: branch-drift.sh &lt;repository-url&gt; &lt;branch&gt; &lt;branch&gt; [&lt;branch&gt;...]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">set</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-euo</span><span class="token plain"> pipefail</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">repo</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$1</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">shift</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">branches</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$@</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">work</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable" style="color:rgb(191, 199, 213)">mktemp </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-d</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> init </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-q</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-C</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> remote </span><span class="token function" style="color:rgb(130, 170, 255)">add</span><span class="token plain"> origin </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$repo</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token for-or-select variable" style="color:rgb(191, 199, 213)">branch</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable" style="color:rgb(191, 199, 213)">@</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">do</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">git</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-C</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"> fetch </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-q</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--depth</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token plain"> origin </span><span class="token string" style="color:rgb(195, 232, 141)">"refs/heads/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$branch</span><span class="token string" style="color:rgb(195, 232, 141)">:refs/remotes/origin/</span><span class="token string variable" style="color:rgb(191, 199, 213)">$branch</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">done</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">files</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable function" style="color:rgb(130, 170, 255)">git</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-C</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> ls-tree </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-r</span><span class="token string variable" style="color:rgb(191, 199, 213)"> --name-only </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"origin/</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">0</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">|</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable function" style="color:rgb(130, 170, 255)">grep</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-E</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">'\.(c|h)$'</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">||</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable boolean" style="color:rgb(255, 88, 116)">true</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'%-44s'</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"file"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">((</span><span class="token variable" style="color:rgb(191, 199, 213)">i </span><span class="token variable operator" style="color:rgb(137, 221, 255)">=</span><span class="token variable" style="color:rgb(191, 199, 213)"> </span><span class="token variable number" style="color:rgb(247, 140, 108)">1</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token variable" style="color:rgb(191, 199, 213)"> i </span><span class="token variable operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token variable" style="color:rgb(191, 199, 213)"> ${#branches[@]}</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token variable" style="color:rgb(191, 199, 213)"> i</span><span class="token variable operator" style="color:rgb(137, 221, 255)">++</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">))</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">do</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'%-24s'</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable" style="color:rgb(191, 199, 213)">0</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string" style="color:rgb(195, 232, 141)"> vs </span><span class="token string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable" style="color:rgb(191, 199, 213)">i</span><span class="token string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">done</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'\n'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token for-or-select variable" style="color:rgb(191, 199, 213)">file</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">in</span><span class="token plain"> </span><span class="token variable" style="color:rgb(191, 199, 213)">$files</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">do</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'%-44s'</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$file</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">((</span><span class="token variable" style="color:rgb(191, 199, 213)">i </span><span class="token variable operator" style="color:rgb(137, 221, 255)">=</span><span class="token variable" style="color:rgb(191, 199, 213)"> </span><span class="token variable number" style="color:rgb(247, 140, 108)">1</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token variable" style="color:rgb(191, 199, 213)"> i </span><span class="token variable operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token variable" style="color:rgb(191, 199, 213)"> ${#branches[@]}</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token variable" style="color:rgb(191, 199, 213)"> i</span><span class="token variable operator" style="color:rgb(137, 221, 255)">++</span><span class="token variable punctuation" style="color:rgb(199, 146, 234)">))</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">do</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">changed</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$(</span><span class="token string variable function" style="color:rgb(130, 170, 255)">git</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">-C</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable function" style="color:rgb(130, 170, 255)">diff</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable parameter variable" style="color:rgb(191, 199, 213)">--numstat</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"origin/</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">0</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"origin/</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">${branches</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">i</span><span class="token string variable string variable punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">}</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> -- </span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable string variable" style="color:rgb(191, 199, 213)">$file</span><span class="token string variable string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable operator" style="color:rgb(137, 221, 255)">|</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable function" style="color:rgb(130, 170, 255)">awk</span><span class="token string variable" style="color:rgb(191, 199, 213)"> </span><span class="token string variable string" style="color:rgb(195, 232, 141)">'{print $1 + $2}'</span><span class="token string variable" style="color:rgb(191, 199, 213)">)</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'%-24s'</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">${changed</span><span class="token string variable operator" style="color:rgb(137, 221, 255)">:-</span><span class="token string variable" style="color:rgb(191, 199, 213)">0}</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">done</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">printf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'\n'</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">done</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">rm</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-rf</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"</span><span class="token string variable" style="color:rgb(191, 199, 213)">$work</span><span class="token string" style="color:rgb(195, 232, 141)">"</span><br></div></code></pre></div></div>
<p>Použité na vetvách modulu GPIO (tabuľka vyššie je jeho výstup):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">./branch-drift.sh https://github.com/Embedbits/Bsp-Mcal-Gpio STM32F4 STM32G4 STM32H5 STM32U5</span><br></div></code></pre></div></div>
<p>Pri ostatných moduloch je obraz iný, a to je užitočné vedieť skôr, než si naplánujete prácu:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">file             F4 vs G4   F4 vs H5   F4 vs U5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Exti_Port.h      0          0          0</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Exti.c           586        538        682</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Usart_Port.h     55         2          28</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Usart.c          3734       2301       3927</span><br></div></code></pre></div></div>
<p>EXTI má nezmenenú verejnú hlavičku na všetkých vetvách a odlišnú implementáciu (periférie sa líšia, rozhranie nie). USART sa líši v rozhraní na G4 a U5 a vo veľkej časti implementácie, čo je miera toho, koľko práce zaberie vydanie týchto dvoch.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ktorý-prístup-zvoliť">Ktorý prístup zvoliť<a href="https://embedbits.cz/sk/blog/bsp-stm32-families-git-branches#ktor%C3%BD-pr%C3%ADstup-zvoli%C5%A5" class="hash-link" aria-label="Priamy odkaz na Ktorý prístup zvoliť" title="Priamy odkaz na Ktorý prístup zvoliť" translate="no">​</a></h2>
<ul>
<li class=""><strong>Vetvy na rodinu</strong> sa hodia, keď sa rodiny líšia v <em>sade</em> periférií a v ovládačoch výrobcu, keď sa produkt zostavuje pre viac rodín a keď si môžete dovoliť udržiavať rozhranie (drift je zvládnuteľný pri niekoľkých rodinách a s nástrojom).</li>
<li class=""><strong><code>#ifdef</code> v jednom strome</strong> je prijateľný, keď sú rozdiely malé: jedna rodina s niekoľkými variantmi MCU, jediný register, ktorý sa volá inak.</li>
<li class=""><strong>Ani jeden z nich</strong> nepomôže bez <strong>abstrakcie naspodku</strong>. Vetva len rozhoduje, ktorá implementácia rozhrania je v strome. Ak aplikácia includuje hlavičky výrobcu, vetva na rodinu vás pred ničím nezachráni.</li>
</ul>
<p>A nech zvolíte čokoľvek, zapíšte si, ktorá rodina je referenčná, a držte v jobe CI jedno číslo: ako ďaleko sú ostatné.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>Architektúra</category>
            <category>STM32</category>
        </item>
        <item>
            <title><![CDATA[Čo sa stane pred main(): reset, startup kód a linker script]]></title>
            <link>https://embedbits.cz/sk/blog/before-main-startup-linker</link>
            <guid>https://embedbits.cz/sk/blog/before-main-startup-linker</guid>
            <pubDate>Mon, 05 Oct 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[Každý tutoriál jazyka C začína int main(void). Nikto však nevysvetlí, kto túto funkciu volá. A pritom, keď napíšete uint32_t counter = 5; ako globálnu premennú a prvý riadok main() prečíta hodnotu 5, už sa vykonalo veľa práce. Ak sa táto práca nevykoná, prejaví sa to premennou s náhodnou hodnotou, ktorá „včera fungovala".]]></description>
            <content:encoded><![CDATA[<p>Každý tutoriál jazyka C začína <code>int main(void)</code>. Nikto však nevysvetlí, kto túto funkciu volá. A pritom, keď napíšete <code>uint32_t counter = 5;</code> ako globálnu premennú a prvý riadok <code>main()</code> prečíta hodnotu 5, už sa vykonalo veľa práce. Ak sa táto práca nevykoná, prejaví sa to premennou s náhodnou hodnotou, ktorá „včera fungovala".</p>
<p>V tomto článku budeme sledovať mikrokontrolér od resetu až po prvý riadok <code>main()</code>: čo robí hardvér sám od seba, čo hovorí linker script a čo musí urobiť startup kód. Je to obsah dvoch modulov Embedbits BSP (<a class="" href="https://embedbits.cz/sk/docs/bsp/linker">Linker</a> a <a class="" href="https://embedbits.cz/sk/docs/bsp/startup">Startup</a>), ale princíp je rovnaký na každom Cortex-M. Všetok kód v článku bol zostavený pomocou <code>arm-none-eabi-gcc</code> 13.2.1 a <strong>spustený</strong> v QEMU, na modeli dosky s STM32F405, takže adresy a výstupy sú skutočné.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-od-programu-očakáva-jazyk-c">Čo od programu očakáva jazyk C<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#%C4%8Do-od-programu-o%C4%8Dak%C3%A1va-jazyk-c" class="hash-link" aria-label="Priamy odkaz na Čo od programu očakáva jazyk C" title="Priamy odkaz na Čo od programu očakáva jazyk C" translate="no">​</a></h2>
<p>Norma jazyka C sľubuje o programe niekoľko vecí, o ktorých hardvér nevie:</p>
<ul>
<li class="">globálna premenná s inicializátorom (<code>uint32_t initializedValue = 0x12345678u;</code>) má na začiatku túto hodnotu,</li>
<li class="">globálna alebo <code>static</code> premenná bez inicializátora je <strong>nulová</strong>,</li>
<li class="">existuje zásobník (stack) a funkcia ho môže používať,</li>
<li class="">globálne objekty C++ sú skonštruované (a v jazyku C sa spustia funkcie označené <code>__attribute__((constructor))</code>) ešte pred <code>main()</code>.</li>
</ul>
<p>Hardvér ponúka veľmi málo. Jadro Cortex-M po resete robí len dve veci: z prvého slova vektorovej tabuľky načíta <strong>počiatočnú hodnotu ukazovateľa zásobníka</strong>, z druhého <strong>adresu reset handlera</strong> a skočí tam. Všetko ostatné je úloha startup kódu, ktorý je súčasťou <strong>vášho</strong> firmvéru.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="vektorová-tabuľka">Vektorová tabuľka<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#vektorov%C3%A1-tabu%C4%BEka" class="hash-link" aria-label="Priamy odkaz na Vektorová tabuľka" title="Priamy odkaz na Vektorová tabuľka" translate="no">​</a></h2>
<p>Vektorová tabuľka je pole adries umiestnené na začiatku flash pamäte (na STM32 je to <code>0x08000000</code>, čo je po štarte z flash viditeľné aj na adrese 0). V minimálnej podobe obsahuje ukazovateľ zásobníka, reset handler a handlery výnimiek:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">section</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">".isr_vector"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> used</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> vectorTable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_estack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* [0] initial stack pointer */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Reset_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">              </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* [1] where the core jumps after the reset */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    NMI_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    HardFault_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Toto obsahuje prvých 16 bajtov zostaveného firmvéru:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Contents of section .isr_vector:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"> 8000000 00000220 13000008 11000008 11000008</span><br></div></code></pre></div></div>
<p>Čísla sú v poradí little-endian. Prvé slovo je <code>0x20020000</code>, koniec 128 kB RAM, ktorá začína na <code>0x20000000</code>, a práve tu začína zásobník (rastie smerom nadol). Druhé je <code>0x08000013</code>: reset handler leží na adrese <code>0x08000012</code> a najnižší bit hovorí „Thumb kód", čo je na Cortex-M povinné. Zvyšok sú výnimky; všetky nepoužité som nasmeroval na ten istý handler.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="linker-script-mapa-pamäte">Linker script: mapa pamäte<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#linker-script-mapa-pam%C3%A4te" class="hash-link" aria-label="Priamy odkaz na Linker script: mapa pamäte" title="Priamy odkaz na Linker script: mapa pamäte" translate="no">​</a></h2>
<p>Kompilátor vytvára objektové súbory so sekciami (<code>.text</code> pre kód, <code>.data</code>, <code>.bss</code> a podobne) a netuší, kde v pamäti skončia. Rozhoduje o tom linker a potrebuje na to mapu. Toto je celý skript z príkladu, 59 riadkov:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">link.ld</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">/* Entry point: the first instruction that runs after the reset */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">ENTRY(Reset_Handler)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">MEMORY</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  FLASH (rx)  : ORIGIN = 0x08000000, LENGTH = 1024K</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  RAM   (xrw) : ORIGIN = 0x20000000, LENGTH = 128K</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">/* The stack grows down from the end of the RAM */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">_estack = ORIGIN(RAM) + LENGTH(RAM);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">SECTIONS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">{</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  /* The vector table has to be at the very beginning of the flash */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  .isr_vector :</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    KEEP(*(.isr_vector))</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  } &gt; FLASH</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  .text :</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    *(.text*)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    *(.rodata*)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  } &gt; FLASH</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  /* Constructors of the C++ objects and functions marked as constructor */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  .init_array :</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    __init_array_start = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    KEEP(*(.init_array*))</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    __init_array_end = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  } &gt; FLASH</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  /* Start of the initial values of .data: in the flash, right after the code */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  _sidata = LOADADDR(.data);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  /* .data lives in the RAM (VMA), its initial values are stored in the flash (LMA) */</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  .data :</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _sdata = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    *(.data*)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _edata = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  } &gt; RAM AT &gt; FLASH</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  .bss (NOLOAD) :</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  {</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _sbss = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    *(.bss*)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    *(COMMON)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    . = ALIGN(4);</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    _ebss = .;</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  } &gt; RAM</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Prejdime si dôležité časti.</p>
<p><strong><code>MEMORY</code></strong> popisuje fyzické pamäte: kde začínajú a aké sú veľké. Atribúty hovoria linkeru, čo tam je povolené (<code>rx</code>: čítanie a vykonávanie, <code>xrw</code>: všetko).</p>
<p><strong><code>.isr_vector</code> ide ako prvá</strong> do flash pamäte a <code>KEEP</code> bráni linkeru, aby ju zahodil: nič v kóde túto tabuľku <em>nevolá</em>, takže bez <code>KEEP</code> by vyzerala ako nepoužitá. Nasleduje <code>.text</code> s kódom a dátami len na čítanie (<code>.rodata</code>, čo znamená, že <code>const</code> premenné zostávajú vo flash a nezaberajú žiadnu RAM).</p>
<p><strong><code>.data</code> je tá zaujímavá.</strong> Pozrite sa na riadok <code>} &gt; RAM AT &gt; FLASH</code>. Každá sekcia má dve adresy:</p>
<ul>
<li class=""><strong>VMA</strong> (virtual memory address), kde sa sekcia nachádza, keď program <em>beží</em>: <code>.data</code> musí byť v RAM, pretože sa do nej zapisuje,</li>
<li class=""><strong>LMA</strong> (load address), kde je sekcia <em>uložená</em> v obraze firmvéru: RAM je po zapnutí prázdna, takže počiatočné hodnoty musia byť niekde, kde prežijú, teda vo flash.</li>
</ul>
<p><code>arm-none-eabi-objdump -h</code> ukáže obe:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Idx Name          Size      VMA       LMA       File off  Algn</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  0 .isr_vector   00000010  08000000  08000000  00001000  2**2</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  1 .text         000001b0  08000010  08000010  00001010  2**2</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  2 .init_array   00000004  080001c0  080001c0  000011c0  2**2</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  3 .data         00000004  20000000  080001c4  00002000  2**2</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  4 .bss          00000008  20000004  080001c8  00002004  2**2</span><br></div></code></pre></div></div>
<p><code>.data</code> sídli na <code>0x20000000</code>, ale jej počiatočné hodnoty sú vo flash na <code>0x080001C4</code>. Niekto ich musí skopírovať, a preto skript definuje symboly <code>_sidata</code> (zdroj vo flash), <code>_sdata</code> a <code>_edata</code> (začiatok a koniec cieľa v RAM). Za týmito symbolmi nie je žiadna pamäť, sú to len adresy, ktoré kód v C načíta cez <code>&amp;_sdata</code>:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">080001c4 A _sidata</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">20000000 D _sdata</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">20000004 D _edata</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">20000004 B _sbss</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">2000000c B _ebss</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">20020000 R _estack</span><br></div></code></pre></div></div>
<p><strong><code>.bss</code> je <code>NOLOAD</code>.</strong> V obraze nemá žiadny obsah, len veľkosť (premenná bez inicializátora s nulovou hodnotou by zbytočne plytvala flash pamäťou). Startup kód musí oblasť medzi <code>_sbss</code> a <code>_ebss</code> vyplniť nulami.</p>
<p><strong><code>.init_array</code></strong> je tabuľka ukazovateľov na konštruktory. Startup kód ju prejde a konštruktory zavolá.</p>
<p>Linker script v Embedbits BSP generuje CMake pre každý MCU zo šablóny. Obsahuje rovnaké symboly (<code>_sidata</code>, <code>_sdata</code>, <code>_edata</code>, <code>_sbss</code>, <code>_ebss</code>, <code>_stack_top</code>) a popisuje aj voliteľné oblasti, napríklad CCMRAM na STM32G4, kde možno umiestniť sekciu <code>.ccmram</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="startup-kód">Startup kód<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#startup-k%C3%B3d" class="hash-link" aria-label="Priamy odkaz na Startup kód" title="Priamy odkaz na Startup kód" translate="no">​</a></h2>
<p>Skript povedal, kde je všetko uložené, a teraz kód urobí to, čo od programu očakáva jazyk C:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">startup.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Symbols created by the linker script */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> _sidata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> _sdata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> _edata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> _sbss</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> _ebss</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> _estack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">__init_array_start</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">__init_array_end</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Reset_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Default_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* A few of the exception handlers, all unused ones point to the default one */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">NMI_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">       </span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">weak</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">alias</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"Default_Handler"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">HardFault_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">weak</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">alias</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"Default_Handler"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The vector table: the first word is the initial stack pointer, the second the reset handler */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">section</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">".isr_vector"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> used</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> vectorTable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_estack</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Reset_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    NMI_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    HardFault_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Reset_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">DEMO_DIRTY_RAM</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Only for the demo: RAM full of garbage, as after a reset of a running system.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">     * The upper 4 kB are left alone, the stack of this function lives there. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ramWord </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_sdata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> ramWord </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uintptr_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_estack </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0x1000u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> ramWord</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ramWord </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0xA5A5A5A5u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">DEMO_SKIP_INIT</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 1. Copy the initial values of .data from the flash to the RAM */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">source </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_sidata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">target </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_sdata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> target </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_edata</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">target</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">source</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 2. Zero the .bss */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">target </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_sbss</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> target </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">_ebss</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">target</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 3. Run the constructors */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">constructor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> __init_array_start</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> constructor </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> __init_array_end</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> constructor</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">constructor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 4. Hand over to the application */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Default_Handler</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><code>Reset_Handler</code> má štyri kroky (časti s <code>#ifdef</code> slúžia na nižšie uvedený experiment):</p>
<ol>
<li class=""><strong>Skopírovať <code>.data</code></strong> z flash (<code>_sidata</code>) do RAM (<code>_sdata</code> až <code>_edata</code>).</li>
<li class=""><strong>Vynulovať <code>.bss</code></strong> (<code>_sbss</code> až <code>_ebss</code>).</li>
<li class=""><strong>Zavolať konštruktory</strong> z <code>.init_array</code>.</li>
<li class=""><strong>Zavolať <code>main()</code></strong>. Ak sa niekedy vráti, program zostane v nekonečnej slučke, pretože nie je kam sa vrátiť.</li>
</ol>
<p>V Embedbits BSP robí startup modul podľa svojej dokumentácie o niečo viac: nastaví aj hodiny (RCC cez MCAL) a potom zavolá <code>AppMain()</code>. Z poradia krokov vyplýva pravidlo: <strong>čokoľvek, čo sa vykoná pred krokmi 1 a 2, sa nesmie dotknúť globálnej premennej</strong>, pretože jej obsah ešte nie je platný. Nastavenie hodín je preto funkcia, ktorá používa iba registre, alebo si kompilátor drží jej stav v lokálnych premenných.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="experiment-čo-sa-stane-bez-toho">Experiment: čo sa stane bez toho<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#experiment-%C4%8Do-sa-stane-bez-toho" class="hash-link" aria-label="Priamy odkaz na Experiment: čo sa stane bez toho" title="Priamy odkaz na Experiment: čo sa stane bez toho" translate="no">​</a></h2>
<p>Aplikácia z príkladu má štyri globálne premenné štyroch druhov:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">main.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> initializedValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0x12345678u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* .data: has a value in the flash */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> zeroedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* .bss:  has to be zero            */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> constantValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0xC0FFEE00u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* .rodata: stays in the flash      */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> constructedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* set by a constructor before main */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">__attribute__</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">constructor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Construct</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    constructedValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0xC0DE0001u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"initializedValue"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> initializedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"zeroedValue      "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> zeroedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"constantValue    "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> constantValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"constructedValue "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> constructedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"address of initializedValue"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">initializedValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">PrintHex</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"address of constantValue   "</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">constantValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Quit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>(Časť nad týmto kódom, s funkciami, ktoré tlačia cez <em>semihosting</em>, je niekoľko riadkov kódu, ktoré požiadajú QEMU, aby vypísal text a skončil. Pre túto tému nie je dôležitá.)</p>
<p>Najprv bežný build. Výsledok:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">initializedValue 0x12345678</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">zeroedValue       0x00000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">constantValue     0xC0FFEE00</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">constructedValue  0xC0DE0001</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">address of initializedValue 0x20000000</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">address of constantValue    0x080001BC</span><br></div></code></pre></div></div>
<p>Všetky štyri hodnoty sú také, aké sľubuje jazyk C, a adresy potvrdzujú príbeh: premenná v RAM je na <code>0x2000...</code>, konštanta vo flash na <code>0x0800...</code>.</p>
<p>Teraz experiment. Po resete bežiaceho systému RAM nie je prázdna: obsahuje to, čo tam bolo predtým. Studený štart MCU je často „šťastný", pretože RAM je náhodou nulová, a chyba v startup kóde tak zostane dlho skrytá. Na test som RAM znečistil (<code>-DDEMO_DIRTY_RAM</code> ju pred všetkým ostatným vyplní hodnotou <code>0xA5A5A5A5</code>) a potom som odstránil kroky 1 a 2 (<code>-DDEMO_SKIP_INIT</code>):</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">arm-none-eabi-gcc </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-mcpu</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">cortex-m4 </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-mthumb</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-Os</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-ffreestanding</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-nostartfiles</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-T</span><span class="token plain"> link.ld </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DDEMO_DIRTY_RAM</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-DDEMO_SKIP_INIT</span><span class="token plain"> startup.c main.c </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-o</span><span class="token plain"> broken.elf</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">qemu-system-arm </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-M</span><span class="token plain"> netduinoplus2 </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-nographic</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">\</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    -semihosting-config </span><span class="token assign-left variable" style="color:rgb(191, 199, 213)">enable</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">on,target</span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain">native </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-kernel</span><span class="token plain"> broken.elf</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">initializedValue 0xA5A5A5A5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">zeroedValue       0xA5A5A5A5</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">constantValue     0xC0FFEE00</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">constructedValue  0xC0DE0001</span><br></div></code></pre></div></div>
<p>Pozrite sa, čo je zlé a čo nie:</p>
<ul>
<li class=""><code>initializedValue</code> a <code>zeroedValue</code> sú nezmysel. Prvá nemá počiatočnú hodnotu, druhá nie je nulová, hoci oba riadky v súbore C hovoria opak.</li>
<li class=""><code>constantValue</code> je v poriadku, pretože je vo flash a nikto ju nemusí kopírovať.</li>
<li class=""><code>constructedValue</code> je v poriadku, pretože ju konštruktor zapísal <em>po</em> (chýbajúcej) inicializácii. Preto je tento druh chyby taký ťažko odhaliteľný: jedna polovica programu funguje a druhá má náhodné hodnoty.</li>
</ul>
<p>S znečistenou RAM a kompletným startup kódom vypíše ten istý program opäť správne hodnoty.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ako-to-vyzerá-v-praxi">Ako to vyzerá v praxi<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#ako-to-vyzer%C3%A1-v-praxi" class="hash-link" aria-label="Priamy odkaz na Ako to vyzerá v praxi" title="Priamy odkaz na Ako to vyzerá v praxi" translate="no">​</a></h2>
<p>Niekoľko príznakov a to, čo za nimi zvyčajne stojí:</p>





























<table><thead><tr><th>Príznak</th><th>Pravdepodobná príčina</th></tr></thead><tbody><tr><td>Program padne do HardFault hneď po resete</td><td>Prvé slovo vektorovej tabuľky nie je platná adresa zásobníka (nesprávne <code>_estack</code>, nesprávna veľkosť RAM) alebo tabuľka nie je na začiatku flash</td></tr><tr><td>Globálna premenná s inicializátorom má nesprávnu hodnotu, aj tá s <code>= 0</code></td><td><code>.data</code> sa nekopíruje alebo <code>.bss</code> sa nenuluje (nesprávny symbol, sekcia, ktorá v skripte chýba)</td></tr><tr><td>Funguje po zapnutí napájania a zlyháva po resete</td><td>To isté, RAM bola po zapnutí náhodou prázdna</td></tr><tr><td>Zvláštna hodnota, ktorá sa mení s veľkosťou kódu</td><td>Zásobník rastie nadol do <code>.bss</code> / <code>.data</code>, pretečenie zásobníka</td></tr><tr><td>Prvý <code>printf</code> alebo ovládač nefunguje</td><td>Kód, ktorý sa vykoná pred krokmi 1 a 2, používa globálnu premennú</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-vám-hovoria-čísla-nástroja">Čo vám hovoria čísla nástroja<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#%C4%8Do-v%C3%A1m-hovoria-%C4%8D%C3%ADsla-n%C3%A1stroja" class="hash-link" aria-label="Priamy odkaz na Čo vám hovoria čísla nástroja" title="Priamy odkaz na Čo vám hovoria čísla nástroja" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">   text	   data	    bss	    dec	    hex	filename</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    448	      8	      8	    464	    1d0	good.elf</span><br></div></code></pre></div></div>
<ul>
<li class=""><strong>Flash</strong> = <code>text</code> + <code>data</code>. Počiatočné hodnoty <code>.data</code> zaberajú miesto aj vo flash, takže veľké inicializované pole vás stojí dvakrát: vo flash aj v RAM. Pole, ktoré sa nemení, by malo byť <code>const</code> a potom je len vo flash.</li>
<li class=""><strong>RAM</strong> = <code>data</code> + <code>bss</code> (+ zásobník a halda).</li>
</ul>
<p>Skontrolovať to vie aj linker, <code>-Wl,--print-memory-usage</code> vypíše, koľko z každej oblasti je využitých:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Memory region         Used Size  Region Size  %age Used</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">           FLASH:         456 B         1 MB      0.04%</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">             RAM:          12 B       128 KB      0.01%</span><br></div></code></pre></div></div>
<p>Pridajte tento prepínač do svojho buildu a keď je niečo na neočakávanom mieste, prečítajte si súbor <code>.map</code> (<code>-Wl,-Map,out.map</code>): obsahuje adresu každej funkcie a každej premennej.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="zhrnutie">Zhrnutie<a href="https://embedbits.cz/sk/blog/before-main-startup-linker#zhrnutie" class="hash-link" aria-label="Priamy odkaz na Zhrnutie" title="Priamy odkaz na Zhrnutie" translate="no">​</a></h2>
<ol>
<li class="">Po resete jadro načíta dve slová: ukazovateľ zásobníka a adresu reset handlera. Všetko ostatné je váš kód.</li>
<li class=""><strong>Linker script</strong> je mapa: kde sú pamäte, v akom poradí ležia sekcie a ktoré symboly označujú ich hranice.</li>
<li class=""><strong>Startup kód</strong> je to, čo robí sľuby jazyka pravdivými: kopíruje <code>.data</code>, nuluje <code>.bss</code>, spúšťa konštruktory a volá <code>main()</code>.</li>
<li class="">Premenná, ktorá má hodnotu vo flash a žije v RAM, má dve adresy, load address a run address. Toto je kľúč k celej téme.</li>
<li class="">Majte zapnuté <code>-Wl,--print-memory-usage</code> a čítajte <code>arm-none-eabi-size</code> a map súbor. Povedia vám o tom, kam sa podela vaša pamäť, viac než debugger.</li>
</ol>
<p>V Embedbits BSP tieto dva súbory nepíšete sami: linker script sa generuje pre vybraný MCU a startup kód prichádza s vetvou BSP pre danú rodinu. Napriek tomu sa oplatí pochopiť, čo robia, pretože keď firmvér nenaštartuje, nikto iný vám nepomôže.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>STM32</category>
        </item>
        <item>
            <title><![CDATA[Unit testovanie embedded C na vašom PC s Unity a CMock]]></title>
            <link>https://embedbits.cz/sk/blog/unit-testing-unity-cmock</link>
            <guid>https://embedbits.cz/sk/blog/unit-testing-unity-cmock</guid>
            <pubDate>Mon, 05 Oct 2026 10:00:00 GMT</pubDate>
            <description><![CDATA[„Embedded softvér sa nedá unit testovať, potrebujete hardvér." Počúvam to často a platí to presne pre jeden druh kódu: pre kód, ktorý sa dotýka registrov. Všetko ostatné, stavové automaty, parsery protokolov, riadiaca logika, prevod hodnôt, je obyčajné C, ktoré sa skompiluje na vašom PC. A na vašom PC beží v milisekundách, bez debuggera, bez kábla a bez flashovania.]]></description>
            <content:encoded><![CDATA[<p>„Embedded softvér sa nedá unit testovať, potrebujete hardvér." Počúvam to často a platí to presne pre jeden druh kódu: pre kód, ktorý sa dotýka registrov. Všetko ostatné, stavové automaty, parsery protokolov, riadiaca logika, prevod hodnôt, je obyčajné C, ktoré sa skompiluje na vašom PC. A na vašom PC beží v milisekundách, bez debuggera, bez kábla a bez flashovania.</p>
<p>Tento článok ukazuje, ako otestovať modul pomocou <a href="https://github.com/ThrowTheSwitch/Unity" target="_blank" rel="noopener noreferrer" class="">Unity</a> (testovací framework) a <a href="https://github.com/ThrowTheSwitch/CMock" target="_blank" rel="noopener noreferrer" class="">CMock</a> (generátor mockov), od návrhu, ktorý to umožňuje, až po súbor CMake, ktorý to zostaví. Všetko bolo zostavené a spustené a výstup nižšie je skutočný.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-potrebujete-testovať-a-čo-musíte-odstrániť">Čo potrebujete testovať a čo musíte odstrániť<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#%C4%8Do-potrebujete-testova%C5%A5-a-%C4%8Do-mus%C3%ADte-odstr%C3%A1ni%C5%A5" class="hash-link" aria-label="Priamy odkaz na Čo potrebujete testovať a čo musíte odstrániť" title="Priamy odkaz na Čo potrebujete testovať a čo musíte odstrániť" translate="no">​</a></h2>
<p>Unit test spúšťa jeden modul izolovane. Testovaný modul volá nižšiu vrstvu (BSP, ovládač, iný modul) a <strong>to</strong> je problém: nižšia vrstva potrebuje hardvér. Riešením nie je dať modulu simulovaný hardvér, ale nahradiť celú nižšiu vrstvu niečím, čo test ovláda. Tým niečím je <strong>mock</strong>: funkcia s rovnakou signatúrou ako skutočná, ktorá nerobí nič skutočné. Len si pamätá, ako bola zavolaná, a vracia to, čo jej test povedal vrátiť.</p>
<p>Funguje to iba vtedy, ak má modul miesto, kde sa dá nižšia vrstva nahradiť. V článku o <a class="" href="https://embedbits.cz/sk/blog/solid-principles-c-cpp">princípoch SOLID</a> bola <em>link-time injection</em>: modul volá funkciu deklarovanú v headeri (<code>Bsp_Thermostat.h</code>) a build systém rozhoduje, ktorý zdrojový súbor ju implementuje. Na cieľovom zariadení je to skutočné BSP, v unit teste je to mock. Je to rovnaký princíp ako architektúra z článku o <a class="" href="https://embedbits.cz/sk/blog/design-architecture">návrhu a architektúre</a>: keď majú vrstvy čisté rozhrania, každú vrstvu možno testovať bez vrstiev pod ňou.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="nástroje">Nástroje<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#n%C3%A1stroje" class="hash-link" aria-label="Priamy odkaz na Nástroje" title="Priamy odkaz na Nástroje" translate="no">​</a></h2>
<ul>
<li class=""><strong>Unity</strong> je framework s asercami (<code>TEST_ASSERT_TRUE</code>, <code>TEST_ASSERT_EQUAL_UINT8</code>, <code>TEST_ASSERT_EQUAL_FLOAT</code>, <code>TEST_ASSERT_EQUAL_MEMORY</code> a mnohé ďalšie) a malým skriptom, ktorý z vášho testovacieho súboru vygeneruje <code>main()</code> so zoznamom testov, takže nikdy nemusíte registrovať test ručne. Je to niekoľko súborov v C, ktoré sa kompilujú spolu s testom.</li>
<li class=""><strong>CMock</strong> prečíta header a vygeneruje mock každej funkcie v ňom: <code>MockBsp_Thermostat.c/.h</code>. Je napísaný v Ruby, ale iba <em>generátor</em>, vygenerovaný mock je obyčajné C.</li>
<li class=""><strong>Ruby</strong> je potrebné pre oba generátory, ktoré bežia pri builde. Do testovaného kódu sa nedostane.</li>
</ul>
<p>V platforme Embedbits sú tieto tri artefakty (<code>unity</code>, <code>cmock</code> a <code>ruby</code>), takže projekt nezávisí od toho, čo je nainštalované na PC vývojára. Verzie sú v <code>ArtifactsConfig.txt</code> (syntax je <code>&lt;artifact_name&gt;;&lt;binary_version&gt;;&lt;handler_version&gt;</code>). V tomto článku som použil Unity 2.6.1 a CMock 2.6.0 s obyčajným CMake, aby príklad fungoval všade.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testovaný-modul">Testovaný modul<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#testovan%C3%BD-modul" class="hash-link" aria-label="Priamy odkaz na Testovaný modul" title="Priamy odkaz na Testovaný modul" translate="no">​</a></h2>
<p>Termostat s hysterézou. Číta teplotu z BSP, pod 20 °C zapne ohrievač a nad 22 °C ho vypne. Ak senzor neodpovedá, ohrievač vypne, pretože ohrievač bez merania je požiar. Rozhranie k hardvéru je header s dvoma funkciami:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Bsp_Thermostat.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">BSP_THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">BSP_THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Implemented by the BSP of the board - or mocked in the unit test. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Returns false if the sensor does not answer, the value is then not valid. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<p>Verejný port modulu a jeho implementácia:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Thermostat_Port.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">THERMOSTAT_THERMOSTAT_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">THERMOSTAT_THERMOSTAT_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Thermostat.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Thermostat_Port.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Bsp_Thermostat.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">THERMOSTAT_SWITCH_ON_CELSIUS</span><span class="token macro property">   </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">20.0f</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">THERMOSTAT_SWITCH_OFF_CELSIUS</span><span class="token macro property">  </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">22.0f</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> bool isHeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    isHeaterOn </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* fail safe: no value, no heating */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> THERMOSTAT_SWITCH_ON_CELSIUS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> THERMOSTAT_SWITCH_OFF_CELSIUS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* inside the hysteresis band: keep the current state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> isHeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Modul neincluduje žiadny hardvérový header, nepozná STM32 a dá sa skompilovať kompilátorom vášho PC. Toto je prvý test návrhu: ak sa nekompiluje, nie je dostatočne oddelený.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="test">Test<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#test" class="hash-link" aria-label="Priamy odkaz na Test" title="Priamy odkaz na Test" translate="no">​</a></h2>
<p>Testovací súbor includuje header testovaného modulu a header <strong>mocku</strong>, ktorý zatiaľ neexistuje. Generuje sa z <code>Bsp_Thermostat.h</code> počas buildu.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">test_Thermostat.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"unity.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Thermostat_Port.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"MockBsp_Thermostat.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">setUp</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">tearDown</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The mock reads this variable when Thermostat_Task() calls it, so it has to outlive the helper. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sensorCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Helper: the sensor answers with the given temperature. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    sensorCelsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius_ExpectAnyArgsAndReturn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius_ReturnThruPtr_celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">sensorCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">test_HeaterSwitchesOnBelowLowerLimit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">18.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">TEST_ASSERT_TRUE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">test_HeaterSwitchesOffAboveUpperLimit</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">18.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">23.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">TEST_ASSERT_FALSE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">test_HeaterKeepsStateInsideHysteresis</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">18.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">21.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* no Bsp_Set_Heater expected: the mock fails the test if it is called */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">TEST_ASSERT_TRUE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">test_HeaterSwitchesOffWhenSensorFails</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Sensor_Returns</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">18.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius_ExpectAnyArgsAndReturn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater_Expect</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">TEST_ASSERT_FALSE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Is_HeaterOn</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Prečítajme si to zhora.</p>
<ul>
<li class=""><code>setUp()</code> volá Unity pred každým testom. Modul drží svoj stav v <code>static</code> premennej, takže každý test začína s <code>Thermostat_Init()</code> a <code>Bsp_Set_Heater_Expect(false)</code> hovorí mocku, že inicializácia vypne ohrievač. Bez tohto resetu by testy závisli jeden od druhého a od svojho poradia.</li>
<li class=""><code>Sensor_Returns()</code> je pomocná funkcia, ktorá hovorí „ďalšie volanie <code>Bsp_Get_Celsius()</code> vráti <code>true</code> a nastaví hodnotu na túto teplotu". <code>_ExpectAnyArgsAndReturn</code> znamená „na ukazovateli mi nezáleží" a <code>_ReturnThruPtr_celsius</code> vyplní výstupný parameter.</li>
<li class="">Každý test je krátky príbeh o troch častiach: senzor niečo povie, modul sa spustí (<code>Thermostat_Task()</code>), výsledok sa skontroluje. Očakávanie <code>Bsp_Set_Heater_Expect(true)</code> je zároveň aserciou: ak modul zavolá funkciu s inou hodnotou alebo ju nezavolá, test zlyhá.</li>
<li class="">Tretí test ukazuje silu mockov. V pásme hysterézy sa neočakáva nič a to je aserica: mock zlyhá test hneď, ako modul zavolá <code>Bsp_Set_Heater()</code>.</li>
</ul>
<p>Úskalie, ktoré stojí za to poznať: <code>_ReturnThruPtr_celsius(&amp;value)</code> nekopíruje hodnotu v okamihu volania, zapamätá si <strong>ukazovateľ</strong> a hodnotu prečíta, keď modul zavolá mock. Ak je <code>value</code> lokálna premenná pomocnej funkcie, v tom čase už neexistuje. Prvá verzia príkladu pre tento článok mala pomocnú funkciu napísanú takto a výsledkom boli štyri zlyhané testy so správou, ktorá vyzerá ako chyba v module:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_HeaterSwitchesOnBelowLowerLimit:FAIL: Expected 1 Was 0. Function Bsp_Set_Heater</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Argument on. Function called with unexpected argument value.</span><br></div></code></pre></div></div>
<p>Modul bol správny, premenná bola nezmysel. Preto má príklad <code>static float sensorCelsius</code> s komentárom.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="build">Build<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#build" class="hash-link" aria-label="Priamy odkaz na Build" title="Priamy odkaz na Build" translate="no">​</a></h2>
<p>Dva generátory a jeden spustiteľný súbor. CMake spúšťa generátory pred kompiláciou a zmena headera mock vygeneruje znova:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">cmock.yml</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token key atrule">:cmock</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token key atrule">:mock_path</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"> mocks</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token key atrule">:plugins</span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">ignore</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">expect_any_args</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">-</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">:</span><span class="token plain">return_thru_ptr</span><br></div></code></pre></div></div>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">CMakeLists.txt</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">cmake_minimum_required</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">VERSION</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.19</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">project</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ThermostatTests C</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">enable_testing</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">find_program</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">RUBY ruby REQUIRED</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">UNITY_DIR  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/../unity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">CMOCK_DIR  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/../cmock</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">MOCK_DIR   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/mocks</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">TEST_NAME  test_Thermostat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># 1. mock of the BSP interface, generated from its header</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_custom_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    OUTPUT  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/MockBsp_Thermostat.c </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/MockBsp_Thermostat.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">RUBY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">CMOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/lib/cmock.rb -o</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/cmock.yml</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src/Bsp_Thermostat.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">WORKING_DIRECTORY</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">DEPENDS</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src/Bsp_Thermostat.h </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/cmock.yml</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># 2. the test runner (main + list of the tests), generated from the test file</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_custom_command</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    OUTPUT  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">_Runner.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">RUBY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">UNITY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/auto/generate_test_runner.rb</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/test/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">.c </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">_Runner.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token property">DEPENDS</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/test/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># 3. one test executable: the module under test + the mock + the test + the framework</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_executable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    src/Thermostat.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    test/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">_Runner.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/MockBsp_Thermostat.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">UNITY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src/unity.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">CMOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src/cmock.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_include_directories</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> src </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">MOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">UNITY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">CMOCK_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/src</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_compile_options</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"> -Wall -Wextra</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_test</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token property">NAME</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> COMMAND </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">TEST_NAME</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Konfigurácia CMock (<code>cmock.yml</code>) obsahuje iba zoznam pluginov: <code>ignore</code>, <code>expect_any_args</code> a <code>return_thru_ptr</code>, ktoré dávajú funkcie <code>_Ignore</code>, <code>_ExpectAnyArgs</code> a <code>_ReturnThruPtr_</code>, ktoré používa test vyššie. <code>mock_path</code> je relatívna k priečinku, v ktorom generátor beží, čo je build adresár.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-S</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">.</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-B</span><span class="token plain"> build</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">cmake </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">--build</span><span class="token plain"> build</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">./build/test_Thermostat        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># or: ctest --test-dir build</span><br></div></code></pre></div></div>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_Thermostat.c:26:test_HeaterSwitchesOnBelowLowerLimit:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_Thermostat.c:36:test_HeaterSwitchesOffAboveUpperLimit:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_Thermostat.c:49:test_HeaterKeepsStateInsideHysteresis:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_Thermostat.c:61:test_HeaterSwitchesOffWhenSensorFails:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">-----------------------</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">4 Tests 0 Failures 0 Ignored</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">OK</span><br></div></code></pre></div></div>
<p>Všimnite si, čo v spustiteľnom súbore <em>nie je</em>: žiadny startup kód, žiadny linker script, žiadne HAL, žiadny header od ST. Iba modul, mock, test a framework. Zostaví sa za pár sekúnd a beží v milisekundách, takže môže bežať pri každom uložení a pri každom commite.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="testuje-test-naozaj-niečo">Testuje test naozaj niečo?<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#testuje-test-naozaj-nie%C4%8Do" class="hash-link" aria-label="Priamy odkaz na Testuje test naozaj niečo?" title="Priamy odkaz na Testuje test naozaj niečo?" translate="no">​</a></h2>
<p>Test, ktorý nemôže zlyhať, nemá žiadnu hodnotu. Najlacnejšia kontrola je <strong>mutácia</strong>: zámerne pokaziť kód a pozrieť sa, či si to niektorý test všimne. Zmenil som horný limit z 22 °C na 20 °C, čím sa odstráni hysteréza:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_HeaterSwitchesOnBelowLowerLimit:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_HeaterSwitchesOffAboveUpperLimit:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_HeaterKeepsStateInsideHysteresis:FAIL:Function Bsp_Set_Heater.  Called more times than expected.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">test_HeaterSwitchesOffWhenSensorFails:PASS</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">4 Tests 1 Failures 0 Ignored</span><br></div></code></pre></div></div>
<p>Test hysterézy chybu zachytil a správa hovorí, čo sa stalo: modul zavolal <code>Bsp_Set_Heater()</code>, keď nemal. Je dobrým zvykom urobiť to raz pre každý nový test.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-mockovať-a-čo-nie">Čo mockovať a čo nie<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#%C4%8Do-mockova%C5%A5-a-%C4%8Do-nie" class="hash-link" aria-label="Priamy odkaz na Čo mockovať a čo nie" title="Priamy odkaz na Čo mockovať a čo nie" translate="no">​</a></h2>
<ul>
<li class=""><strong>Mockujte hranicu modulu, nie jeho vnútro.</strong> Mock nahrádza rozhranie nižšej vrstvy (tu <code>Bsp_Thermostat.h</code>). Nemockujte vlastné pomocné funkcie v tom istom module: test potom popisuje, ako je kód napísaný, a rozbije sa pri každom refaktoringu, aj keď je správanie rovnaké.</li>
<li class=""><strong>Testujte cez verejný port.</strong> Test includuje <code>Thermostat_Port.h</code> a nič iné z modulu. Ak potrebujete interný header na otestovanie niečoho, je to znamenie, že modul má dve zodpovednosti. Ako sa oddeľujú verejné a interné súbory, si prečítajte v článku o <a class="" href="https://embedbits.cz/sk/blog/file-organization-embedded-c">organizácii súborov</a>.</li>
<li class=""><strong>Jedno správanie, jeden test.</strong> Názov hovorí, čo sa očakáva (<code>HeaterSwitchesOffWhenSensorFails</code>), takže červený test vám povie, čo je pokazené, skôr než ho otvoríte.</li>
<li class=""><strong>Rovnaký vzor funguje v každej vrstve.</strong> Modul aplikácie sa testuje s mockom rozhrania BSP, modul MCAL s mockom portu RAL. V každom prípade sa vrstva pod ním nahradí a testovaná vrstva je skutočná.</li>
<li class=""><strong>Poradie volaní.</strong> CMock vie skontrolovať, že volania rôznych mockov prebehnú v danom poradí (voľba <code>:enforce_strict_ordering</code>). Je užitočné pri inicializačných sekvenciách, ale použite ho len tam, kde je poradie požiadavkou a nie náhodou implementácie.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-vám-host-test-nepovie">Čo vám host test nepovie<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#%C4%8Do-v%C3%A1m-host-test-nepovie" class="hash-link" aria-label="Priamy odkaz na Čo vám host test nepovie" title="Priamy odkaz na Čo vám host test nepovie" translate="no">​</a></h2>
<p>Nechcem predávať host testy ako všetko. Nenájdu:</p>
<ul>
<li class=""><strong>časovanie</strong>, prerušenia a race condition medzi nimi,</li>
<li class=""><strong>registre</strong>: že pin naozaj prejde do vysokej úrovne, že hodiny periférie boli zapnuté. To je úloha kódu v RAL a MCAL a vyžaduje si to simulátor alebo skutočný hardvér,</li>
<li class=""><strong>rozdiely medzi PC a MCU</strong>: šírku <code>int</code>, zarovnanie, optimalizátor cieľového kompilátora. Testy na PC ukazujú, že logika je správna, nie že je správny firmvér.</li>
</ul>
<p>Preto sú host testy základňou pyramídy: veľa, rýchle a bežia pri každom commite. Nad nimi sú simulátor (napríklad Renode) a hardvérové testy, ktorých je menej, sú pomalšie a pokrývajú to, čo PC nevie.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="zhrnutie">Zhrnutie<a href="https://embedbits.cz/sk/blog/unit-testing-unity-cmock#zhrnutie" class="hash-link" aria-label="Priamy odkaz na Zhrnutie" title="Priamy odkaz na Zhrnutie" translate="no">​</a></h2>
<ol>
<li class="">Navrhnite modul tak, aby všetko pod ním bolo za headerom (<em>seam</em>).</li>
<li class="">Nechajte CMock vygenerovať mock z toho headera a Unity runner z testovacieho súboru.</li>
<li class="">Zostavte jeden malý spustiteľný súbor pre PC: modul, mock, test, framework.</li>
<li class="">Píšte testy ako príbehy: mock hovorí, ako vyzerá svet, modul koná, aserica kontroluje výsledok.</li>
<li class="">Raz zámerne pokazte kód, aby ste videli, že test zlyhá.</li>
</ol>
<p>Celý príklad má asi 150 riadkov kódu a keď sa vás nabudúce niekto opýta, či termostat naozaj vypne ohrievač, keď senzor zlyhá, nepotrebujete ohrievač. Spustíte <code>ctest</code>.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>Testovanie</category>
        </item>
        <item>
            <title><![CDATA[Organizácia súborov v embedded C: ako sa z priečinka stane modul]]></title>
            <link>https://embedbits.cz/sk/blog/file-organization-embedded-c</link>
            <guid>https://embedbits.cz/sk/blog/file-organization-embedded-c</guid>
            <pubDate>Sun, 04 Oct 2026 14:00:00 GMT</pubDate>
            <description><![CDATA[Môj coding style hovorí, že názvy súborov začínajú názvom modulu a že „kompletná organizácia súborov je popísaná inde". Toto je to „inde".]]></description>
            <content:encoded><![CDATA[<p>Môj <a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/coding-style">coding style</a> hovorí, že názvy súborov začínajú názvom modulu a že „kompletná organizácia súborov je popísaná inde". Toto je to „inde".</p>
<p>Jazyk C nemá <code>private</code>, menné priestory ani balíky. Keď sa kód rozdelí do súborov, súbory a build systém sú <strong>jediné</strong> nástroje, ktorými môžete povedať, čo patrí k sebe, čo je verejné a čo nikoho iného nezaujíma. Organizácia súborov preto nie je vec vkusu, ale súčasť návrhu. Tento článok popisuje, ako organizujem embedded projekt na troch úrovniach: projekt, modul a jednotlivý súbor.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="úroveň-1-projekt">Úroveň 1: projekt<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#%C3%BArove%C5%88-1-projekt" class="hash-link" aria-label="Priamy odkaz na Úroveň 1: projekt" title="Priamy odkaz na Úroveň 1: projekt" translate="no">​</a></h2>
<p>Projekt vytvorený pomocou EmBi_Platform má vždy rovnaké rozloženie:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Project_root/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Application/          your application</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── AppMain/            entry point</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── AppCore/            top level logic</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── AppFun/             functionalities (high level logic)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── AppComp/            components (low level logic)</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   └── AppCom/             communication modules</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Middlewares/          reusable software without hardware dependency</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── ThirdParty/         vendor sources, one Git submodule per component</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── &lt;Name&gt;/             your glue code and configuration of that component</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   └── Middlewares.cmake</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Bsp/                  Board Support Package</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── Hal/  Mcal/  Ral/   the three abstraction layers</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   ├── Linker/  Startup/   linker script generator, startup code</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">│   └── Docs/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── EmBi_Platform/        build tooling (Git submodule), not part of the firmware</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── STM32CubeIDE/         generated IDE project</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── ArtifactsConfig.txt   versions of the build tools</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">└── CMakeLists.txt        project root build file</span><br></div></code></pre></div></div>
<p>Každý priečinok odpovedá na jednu otázku a odpoveď je dôvodom, prečo kód žije práve tam.</p>
<p><strong>Application</strong> je to, čo odlišuje produkt od každého iného produktu na rovnakom MCU. Má vlastné vnútorné vrstvy a ich názvy sú úrovne „stromu" z <a class="" href="https://embedbits.cz/sk/blog/design-architecture">článku o architektúre</a>: <code>AppMain</code> všetko spúšťa, <code>AppCore</code> je vrchol stromu s logikou celého zariadenia, <code>AppFun</code> obsahuje jednotlivé funkcionality, <code>AppComp</code> nízkoúrovňové komponenty, z ktorých sú postavené, a <code>AppCom</code> komunikáciu s vonkajším svetom. Volania idú zhora nadol, nikdy opačne.</p>
<p><strong>Middlewares</strong> majú pre každý komponent dve miesta a je to zámer. <code>ThirdParty/FreeRTOS</code> je kód od výrobcu, stiahnutý ako Git submodul vo verzii, ktorú si vyberiete, a <strong>nikdy ho neupravujete</strong>. Všetko, čo je vaše (port layer, konfigurácia), žije vedľa neho v <code>Middlewares/FreeRTOS</code> a neprepíše sa, keď prepnete kód výrobcu na inú verziu. Keď výrobca vydá opravu, aktualizujete submodul, nie upravenú kópiu.</p>
<p><strong>Bsp</strong> je popísaný v <a class="" href="https://embedbits.cz/sk/docs/bsp">dokumentácii BSP</a>, stručne: <code>Ral</code> pozná registre, <code>Mcal</code> periférie a <code>Hal</code> dosku. Každá rodina STM32 má vlastnú vetvu BSP, takže priečinky vyzerajú pre každý MCU rovnako.</p>
<p><strong>EmBi_Platform</strong> a <strong>STM32CubeIDE</strong> sú nástroje. Do binárneho súboru sa nedostanú a projekt IDE je generovaný, takže sa dá zahodiť a vytvoriť znova.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="úroveň-2-modul">Úroveň 2: modul<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#%C3%BArove%C5%88-2-modul" class="hash-link" aria-label="Priamy odkaz na Úroveň 2: modul" title="Priamy odkaz na Úroveň 2: modul" translate="no">​</a></h2>
<p>Modul je priečinok s pevnou sadou súborov. Nemusíte ich vytvárať ručne, platforma ich vygeneruje (pozrite koniec článku) a výsledok vyzerá takto:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Temperature/</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── CMakeLists.txt</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Temperature_Types.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Temperature_Port.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Temperature.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">├── Temperature.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">└── Temperature_Filter.c     (a component, see below)</span><br></div></code></pre></div></div>



































<table><thead><tr><th>Súbor</th><th>Úloha</th><th>Kto ho smie includovať</th></tr></thead><tbody><tr><td><code>Temperature_Types.h</code></td><td>Verejné typy, enumerácie a makrá</td><td>každý</td></tr><tr><td><code>Temperature_Port.h</code></td><td>Verejné funkcie: <strong>jediný</strong> vstupný bod modulu</td><td>každý</td></tr><tr><td><code>Temperature.h</code></td><td>Interné typy a funkcie zdieľané súbormi modulu</td><td>iba samotný modul</td></tr><tr><td><code>Temperature.c</code></td><td>Implementácia</td><td>(zdrojový súbor)</td></tr><tr><td><code>CMakeLists.txt</code></td><td>Vytvára statickú knižnicu <code>Temperature_Lib</code></td><td>build</td></tr></tbody></table>
<p>Myšlienka je taká, že používateľ modulu číta <strong>dva</strong> súbory a nič iné. Prvým sú typy (vygenerovaný súbor obsahuje aj typ verzie a bežné enumerácie pre stavy požiadaviek a funkcií, tu som ho zredukoval na to, čo príklad potrebuje):</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature_Types.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature_Types.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Temperature module global types definition</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TEMPERATURE_TEMPERATURE_TYPES_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TEMPERATURE_TEMPERATURE_TYPES_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== TYPEDEFS ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/** Temperature in tenths of a degree Celsius, 253 = 25.3 degC */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">int16_t</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/** Enumeration used to signal request processing state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    TEMPERATURE_REQUEST_ERROR </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Processing request failed  */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    TEMPERATURE_REQUEST_OK          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**&lt; Processing request succeed */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token macro property"> </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* TEMPERATURE_TEMPERATURE_TYPES_H */</span><br></div></code></pre></div></div>
<p>Druhým je port, čo je celé rozhranie modulu. Všetko, čo tu nie je, pre ostatných neexistuje:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature_Port.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature_Port.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Temperature module public functionality</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * The only header that other modules include.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TEMPERATURE_TEMPERATURE_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TEMPERATURE_TEMPERATURE_PORT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">__cplusplus</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"C"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature_Types.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================= EXPORTED FUNCTIONS ============================= */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">                       </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Init</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">                       </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Task</span><span class="token plain">     </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Get_Value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> value </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifdef</span><span class="token macro property"> </span><span class="token macro property expression">__cplusplus</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token macro property"> </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* TEMPERATURE_TEMPERATURE_PORT_H */</span><br></div></code></pre></div></div>
<p>Interný header obsahuje dáta a funkcie, ktoré súbory modulu potrebujú zdieľať a ktoré by nikto zvonku nikdy nemal vidieť:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief Temperature module internal definitions, not visible outside of the module</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TEMPERATURE_TEMPERATURE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TEMPERATURE_TEMPERATURE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature_Types.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== TYPEDEFS ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> filteredValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    bool                isValid</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_State_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================= EXPORTED FUNCTIONS ============================= */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Shared by the files of this module only */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Filter_Apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> rawValue </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><span class="token macro property"> </span><span class="token macro property comment" style="color:rgb(105, 112, 152);font-style:italic">/* TEMPERATURE_TEMPERATURE_H */</span><br></div></code></pre></div></div>
<p>A implementácia to všetko používa:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature_Port.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_State_t</span><span class="token plain"> state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">filteredValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isValid       </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">253</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* a real module reads it from the ADC */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">filteredValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Filter_Apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rawValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isValid       </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Get_Value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> value </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_RequestState_t</span><span class="token plain"> requestState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> TEMPERATURE_REQUEST_ERROR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">isValid</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">value </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> state</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">filteredValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        requestState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> TEMPERATURE_REQUEST_OK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> requestState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Všimnite si, že stav je <code>static</code> v súbore <code>.c</code>. Neexistuje žiadna globálna premenná, takže nie je ani <code>extern</code> (ktorý môj coding style zakazuje). Jediná cesta k dátam je funkcia <code>Temperature_Get_Value()</code>, getter, ktorý volajúcemu zároveň povie, či je hodnota platná.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="build-systém-robí-zo-súboru-zapuzdrenie">Build systém robí zo súboru zapuzdrenie<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#build-syst%C3%A9m-rob%C3%AD-zo-s%C3%BAboru-zapuzdrenie" class="hash-link" aria-label="Priamy odkaz na Build systém robí zo súboru zapuzdrenie" title="Priamy odkaz na Build systém robí zo súboru zapuzdrenie" translate="no">​</a></h3>
<p>„Includuj iba port" by bolo len prianie, keby to nič nevynucovalo. <code>CMakeLists.txt</code> každého modulu to vynucuje. Zostaví statickú knižnicu a <strong>do samostatného priečinka v build adresári skopíruje iba verejné headery</strong>. Tento priečinok je jediný, ktorý používatelia knižnice dostanú do svojej include cesty:</p>
<div class="language-cmake codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">CMakeLists.txt</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cmake codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Source files list for current library generation</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> Temperature_SourceFiles</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Temperature.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Temperature_Filter.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># List of public header files provided by the current library</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> Temperature_PublicHeaders</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Temperature_Types.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Temperature_Port.h</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Create library</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">add_library</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Temperature_Lib </span><span class="token namespace" style="color:rgb(178, 204, 214)">STATIC</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">Temperature_SourceFiles</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Set public headers directory path in build folder</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">PUBLIC_HEADERS_DIR </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_CURRENT_BINARY_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/PublicHeaders</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">file</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">MAKE_DIRECTORY </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">PUBLIC_HEADERS_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Copy only the public headers there</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">foreach</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">PublicHeader IN LISTS Temperature_PublicHeaders</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">configure_file</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">PublicHeader</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">PUBLIC_HEADERS_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">/</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">PublicHeader</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        COPYONLY</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">endforeach</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"># Set include directories for the created target</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">target_include_directories</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> Temperature_Lib</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token namespace" style="color:rgb(178, 204, 214)">PUBLIC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">$&lt;</span><span class="token plain">BUILD_INTERFACE:</span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token plain">PUBLIC_HEADERS_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token namespace" style="color:rgb(178, 204, 214)">PRIVATE</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">${</span><span class="token variable" style="color:rgb(191, 199, 213)">CMAKE_CURRENT_SOURCE_DIR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>(Toto je zjednodušená verzia šablóny, ktorú platforma generuje a ktorá rieši aj závislosti medzi knižnicami a cesty pre Doxygen.) Aplikácia teraz iba linkuje <code>Temperature_Lib</code>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">AppMain.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdio.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature_Port.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> value </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">TEMPERATURE_REQUEST_OK </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Get_Value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">printf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"%d\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Vyskúšal som, čo sa stane, ak aplikácia includuje interný header modulu, a kompilátor povie presne to, čo od neho chcete:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">AppMain_Cheat.c:1:10: fatal error: Temperature.h: No such file or directory</span><br></div></code></pre></div></div>
<p>Priečinok s verejnými headermi v build adresári obsahuje presne dva súbory: <code>Temperature_Port.h</code> a <code>Temperature_Types.h</code>.</p>
<p><strong>Čestné upozornenie:</strong> je to ochrana build systému, nie jazyka. Ak niekto napíše <code>#include "../../Middlewares/Temperature/Temperature.h"</code>, skompiluje sa to bez sťažností (aj to som vyskúšal). Liek je lacný: v CI odmietnite relatívne cesty s <code>..</code> v include.</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token function" style="color:rgb(130, 170, 255)">grep</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(191, 199, 213)">-rEn</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">'#include "[^"]*\.\./'</span><span class="token plain"> Application Middlewares/*/ </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(255, 203, 107)">exit</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="keď-modul-rastie-komponenty">Keď modul rastie: komponenty<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#ke%C4%8F-modul-rastie-komponenty" class="hash-link" aria-label="Priamy odkaz na Keď modul rastie: komponenty" title="Priamy odkaz na Keď modul rastie: komponenty" translate="no">​</a></h3>
<p>Modul s tisíckou riadkov v jednom súbore je ďalší problém. Odpoveďou je <strong>komponent</strong>: ďalšia dvojica súborov <code>Module_Component.c/.h</code> v tom istom priečinku. V príklade vyššie je to filter:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Temperature_Filter.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Temperature.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> lastValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Temperature_Filter_Apply</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token plain"> rawValue </span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    lastValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">temperature_Value_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">lastValue </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> rawValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> lastValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Header komponentu je tiež interný (nie je v zozname verejných headerov), takže komponent možno vymeniť alebo rozdeliť bez toho, aby si to niekto všimol. Používateľ modulu stále vidí tie isté dva súbory. Pravidlo, že názov súboru začína názvom modulu, robí komponent viditeľným v každom zozname súborov a názov funkcie <code>Temperature_Filter_Apply()</code> prezrádza, kde ju hľadať.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="úroveň-3-vnútri-súboru">Úroveň 3: vnútri súboru<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#%C3%BArove%C5%88-3-vn%C3%BAtri-s%C3%BAboru" class="hash-link" aria-label="Priamy odkaz na Úroveň 3: vnútri súboru" title="Priamy odkaz na Úroveň 3: vnútri súboru" translate="no">​</a></h2>
<p>Každý súbor <code>.c</code> a <code>.h</code> vygenerovaný platformou má rovnakú kostru s bannerom pre každú sekciu, v rovnakom poradí:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/**</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \author ...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \file Temperature.c</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \ingroup Temperature</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * \brief ...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== INCLUDES ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ============================== TYPEDEFS ================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ======================== FORWARD DECLARATIONS ============================ */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================== SYMBOLIC CONSTANTS ============================ */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* =============================== MACROS =================================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================== EXPORTED VARIABLES ============================ */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* =========================== LOCAL VARIABLES ============================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ========================= EXPORTED FUNCTIONS ============================= */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* =========================== LOCAL FUNCTIONS ============================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* =========================== INTERRUPT HANDLERS =========================== */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ================================ TASKS =================================== */</span><br></div></code></pre></div></div>
<p>Vyzerá to ako dekorácia, ale je to mapa. Keď otvoríte súbor, ktorý ste nikdy nevideli, viete, že lokálne premenné sú v piatej sekcii a obsluhy prerušení v desiatej, a nemusíte súbor čítať, aby ste ich našli. Headery majú rovnakú myšlienku, zabalenú do include guardu a do <code>extern "C"</code> pre používateľov C++:</p>
<ul>
<li class="">guard má tvar <code>MODULE_FILE_H</code>, napríklad <code>TEMPERATURE_TEMPERATURE_PORT_H</code>,</li>
<li class="">hlavička Doxygen (<code>\file</code>, <code>\ingroup</code>, <code>\brief</code>) je na začiatku každého súboru, takže dokumentácia modulu sa generuje z toho istého priečinka,</li>
<li class="">includy sú zoradené <code>&lt;systémové&gt;</code>, potom projektové, potom modulové.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="jeden-názov-na-všetkých-miestach">Jeden názov na všetkých miestach<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#jeden-n%C3%A1zov-na-v%C5%A1etk%C3%BDch-miestach" class="hash-link" aria-label="Priamy odkaz na Jeden názov na všetkých miestach" title="Priamy odkaz na Jeden názov na všetkých miestach" translate="no">​</a></h2>
<p>Sila tejto organizácie spočíva v tom, že názov modulu je všade rovnaký, takže názov možno uhádnuť bez toho, aby ste ho museli hľadať:</p>





































<table><thead><tr><th>Čo</th><th>Príklad</th></tr></thead><tbody><tr><td>Priečinok</td><td><code>Temperature/</code></td></tr><tr><td>Knižnica v CMake</td><td><code>Temperature_Lib</code></td></tr><tr><td>Súbory</td><td><code>Temperature.c</code>, <code>Temperature_Port.h</code>, <code>Temperature_Types.h</code></td></tr><tr><td>Funkcie</td><td><code>Temperature_Init()</code>, <code>Temperature_Get_Value()</code></td></tr><tr><td>Typy</td><td><code>temperature_Value_t</code>, <code>temperature_RequestState_t</code></td></tr><tr><td>Makrá a enumerátory</td><td><code>TEMPERATURE_REQUEST_OK</code></td></tr><tr><td>Include guard</td><td><code>TEMPERATURE_TEMPERATURE_PORT_H</code></td></tr></tbody></table>
<p>Ak vo výpise zásobníka volaní uvidíte <code>Gpio_Set_PinLevel()</code>, viete, že je v priečinku <code>Gpio</code>, v knižnici <code>Gpio_Lib</code> a že jej typy začínajú <code>gpio_</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="rovnaký-životný-cyklus-pre-každý-modul">Rovnaký životný cyklus pre každý modul<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#rovnak%C3%BD-%C5%BEivotn%C3%BD-cyklus-pre-ka%C5%BEd%C3%BD-modul" class="hash-link" aria-label="Priamy odkaz na Rovnaký životný cyklus pre každý modul" title="Priamy odkaz na Rovnaký životný cyklus pre každý modul" translate="no">​</a></h3>
<p>Vygenerovaný modul prichádza so štyrmi funkciami, ktoré má každý modul: <code>Get_ModuleVersion()</code>, <code>Init()</code>, <code>Deinit()</code> a <code>Task()</code>. <code>Init</code> modul nastaví a vyrieši vlastné zlyhania, <code>Task</code> sa volá periodicky z hlavnej slučky alebo zo schedulera. Dôsledkom je, že kód na vrchole (<code>AppMain</code>) môže so všetkými modulmi zaobchádzať rovnako a nový modul nepotrebuje nový koncept.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="vytvorenie-modulu">Vytvorenie modulu<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#vytvorenie-modulu" class="hash-link" aria-label="Priamy odkaz na Vytvorenie modulu" title="Priamy odkaz na Vytvorenie modulu" translate="no">​</a></h2>
<p>Tieto súbory nevytvárate ručne. Projektové nástroje platformy (položka menu <em>Create module</em>, popísaná na stránke <a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/cmake-helpertools">Project tools</a>) sa spýtajú na názov a umiestnenie a vygenerujú priečinok so všetkými súbormi vyššie a <code>CMakeLists.txt</code>. Položka <em>Add component</em> pridá dvojicu <code>Module_Component.c/.h</code> do existujúceho modulu. Raz vygenerovaný modul sa nikdy neprepíše, takže nástroj možno bezpečne spustiť znova.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-v-skratke">Pravidlá v skratke<a href="https://embedbits.cz/sk/blog/file-organization-embedded-c#pravidl%C3%A1-v-skratke" class="hash-link" aria-label="Priamy odkaz na Pravidlá v skratke" title="Priamy odkaz na Pravidlá v skratke" translate="no">​</a></h2>
<ol>
<li class="">Jeden modul je jeden priečinok a má vlastnú knižnicu.</li>
<li class="">Ostatné moduly includujú <strong>iba</strong> <code>Module_Port.h</code> a <code>Module_Types.h</code>.</li>
<li class="">Interné headery nie sú v zozname verejných headerov.</li>
<li class="">Dáta sú <code>static</code> v súbore <code>.c</code>, prístup ide cez funkcie. Žiadne <code>extern</code> premenné.</li>
<li class="">Názov súboru začína názvom modulu, rovnako ako každá funkcia, typ a makro.</li>
<li class="">Kód výrobcu sa nikdy neupravuje. Vaše zmeny žijú v priečinku handlera vedľa neho.</li>
<li class="">Volania idú vo vrstvách nadol, nikdy nahor.</li>
<li class="">Všetko v súbore je vo svojej sekcii, v rovnakom poradí.</li>
</ol>
<p>Žiadne z týchto pravidiel nie je vychytené. Ide o to, že všetky sú rovnaké vo všetkých moduloch, takže keď si prečítate jeden modul, viete, ako čítať všetky ostatné. To je aj dôvod, prečo platforma súbory generuje: konvencia, ktorej dodržiavanie si vyžaduje prácu, je konvencia, ktorá sa nedodržiava.</p>
<p>Rovnaké myšlienky, z iného pohľadu, nájdete v článkoch o <a class="" href="https://embedbits.cz/sk/blog/solid-principles-c-cpp">princípoch SOLID</a> (port header je rozhranie, na ktorom ostatné moduly závisia) a o <a class="" href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice">MISRA C</a> (niekoľko pravidiel sa dodržiava oveľa ľahšie, keď je kód takto organizovaný).</p>]]></content:encoded>
            <category>Embedded</category>
            <category>Architektúra</category>
            <category>C</category>
        </item>
        <item>
            <title><![CDATA[Pravidlá MISRA C v praxi: čo sú zač, prečo existujú a ako s nimi žiť]]></title>
            <link>https://embedbits.cz/sk/blog/misra-c-rules-in-practice</link>
            <guid>https://embedbits.cz/sk/blog/misra-c-rules-in-practice</guid>
            <pubDate>Sun, 04 Oct 2026 10:00:00 GMT</pubDate>
            <description><![CDATA[Povedzte „MISRA“ v miestnosti plnej embedded vývojárov a polovica z nich si vzdychne, zatiaľ čo druhá polovica sa opýta, aký nástroj používate. Povesť týchto pravidiel je rozporuplná: pre niekoho je to byrokracia, ktorá zje týždeň pred každým vydaním, pre iných dôvod, prečo sa auto na diaľnici nerestartuje. Obe skupiny majú sčasti pravdu.]]></description>
            <content:encoded><![CDATA[<p>Povedzte „MISRA“ v miestnosti plnej embedded vývojárov a polovica z nich si vzdychne, zatiaľ čo druhá polovica sa opýta, aký nástroj používate. Povesť týchto pravidiel je rozporuplná: pre niekoho je to byrokracia, ktorá zje týždeň pred každým vydaním, pre iných dôvod, prečo sa auto na diaľnici nerestartuje. Obe skupiny majú sčasti pravdu.</p>
<p>V tomto článku prejdem pravidlá, s ktorými sa stretávam najčastejšie, jedno po druhom: čo pravidlo žiada, čo vám prinesie, ako vyzerá zlý kód, ako vyzerá dobrý kód a kto za vás problém nájde. Všetky príklady sú skutočný C kód, ktorý som skompiloval a spustil.</p>
<!-- -->
<blockquote>
<p><strong>Poznámka k textom pravidiel</strong></p>
<p>MISRA C je dokument chránený autorskými právami konzorcia MISRA. Jeho znenie tu nekopírujem. Každé pravidlo popisujem vlastnými slovami, s vlastnými príkladmi a citujem iba čísla a kategórie. Čísla sa vzťahujú na <strong>MISRA C:2012</strong> (MISRA C:2023 zhŕňa dodatky, zachováva tieto čísla a pridáva niekoľko nových smerníc). Skôr než na tomto článku postavíte čokoľvek ďalšie, overte si pravidlo vo vlastnej kópii normy, ktorú získate na <a href="https://misra.org.uk/" target="_blank" rel="noopener noreferrer" class="">misra.org.uk</a>. Tento článok je nezávislý a MISRA ho neschválila.</p>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-je-misra-c-a-čo-nie-je">Čo je MISRA C (a čo nie je)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#%C4%8Do-je-misra-c-a-%C4%8Do-nie-je" class="hash-link" aria-label="Priamy odkaz na Čo je MISRA C (a čo nie je)" title="Priamy odkaz na Čo je MISRA C (a čo nie je)" translate="no">​</a></h2>
<p>MISRA je skratka z <em>Motor Industry Software Reliability Association</em>. Prvé smernice pre jazyk C vyšli v roku 1998 pre automobilový priemysel, dnes sa používajú v letectve, železničnej doprave, zdravotníckych pomôckach a priemyselnej automatizácii, teda všade, kde porucha softvéru niekomu ublíži.</p>
<p>Hlavná myšlienka je jednoduchá. C je jazyk, ktorý dovoľuje veľa vecí, ktoré sú legálne, ale nebezpečné: nedefinované správanie (undefined behaviour), správanie definované implementáciou, implicitné konverzie, ktoré menia hodnoty, ukazovatele, ktoré môžu ukazovať kamkoľvek. MISRA definuje <strong>podmnožinu jazyka C</strong>, v ktorej sú nebezpečné časti zakázané alebo ich treba zdôvodniť. Nie je to iný jazyk, program vyhovujúci MISRA je stále normálny C program, ktorý vám zostaví váš bežný kompilátor.</p>
<p>Čo MISRA <strong>nie je</strong>:</p>
<ul>
<li class="">Nie je to certifikácia. „Vyhovuje MISRA“ je tvrdenie, ktoré sami uvádzate a dokumentujete, nikto váš kód neopečiatkuje.</li>
<li class="">Nie je to záruka správnosti. Pravidlá odstraňujú triedy chýb, nekontrolujú, či termostat skutočne reguluje teplotu.</li>
<li class="">Nie je to o štýle. Pomenovanie, odsadenie a organizácia súborov nie sú súčasťou MISRA, na to slúži <a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/coding-style">coding style</a>.</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ako-čítať-pravidlo">Ako čítať pravidlo<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#ako-%C4%8D%C3%ADta%C5%A5-pravidlo" class="hash-link" aria-label="Priamy odkaz na Ako čítať pravidlo" title="Priamy odkaz na Ako čítať pravidlo" translate="no">​</a></h3>
<p>Každá smernica má tri vlastnosti, ktoré by ste mali poznať skôr, než prečítate prvú z nich:</p>

























<table><thead><tr><th>Vlastnosť</th><th>Hodnoty</th><th>Význam</th></tr></thead><tbody><tr><td><strong>Druh</strong></td><td><em>Directive</em> / <em>Rule</em></td><td>Pravidlo (rule) sa dá skontrolovať samotným zdrojovým kódom. Smernica (directive) potrebuje viac informácií (návrh, proces), takže nástroj môže pomôcť, ale nerozhodne.</td></tr><tr><td><strong>Kategória</strong></td><td><em>Mandatory</em> / <em>Required</em> / <em>Advisory</em></td><td>Mandatory: žiadna výnimka. Required: výnimka je možná s písomným zdôvodnením. Advisory: odporúčanie, stačí zaznamenať, že ho nedodržiavate.</td></tr><tr><td><strong>Rozhodnuteľnosť</strong></td><td><em>Decidable</em> / <em>Undecidable</em></td><td>Či nástroj dokáže dať presnú odpoveď. Pri nerozhodnuteľných pravidlách aj najlepší analyzátor produkuje falošné poplachy alebo niečo prehliadne.</td></tr></tbody></table>
<p>Číslovanie je <code>Dir 4.12</code> pre smernice a <code>Rule 9.1</code> pre pravidlá, kde prvé číslo je téma (9 = inicializácia, 10 = typy, 11 = ukazovatele, ...).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-jedno-po-druhom">Pravidlá jedno po druhom<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#pravidl%C3%A1-jedno-po-druhom" class="hash-link" aria-label="Priamy odkaz na Pravidlá jedno po druhom" title="Priamy odkaz na Pravidlá jedno po druhom" translate="no">​</a></h2>
<p>Zoskupil som ich podľa problému, ktorý riešia, nie podľa čísla.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-o-hodnotách-ktoré-nie-sú-také-ako-si-myslíte">Pravidlá o hodnotách, ktoré nie sú také, ako si myslíte<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#pravidl%C3%A1-o-hodnot%C3%A1ch-ktor%C3%A9-nie-s%C3%BA-tak%C3%A9-ako-si-mysl%C3%ADte" class="hash-link" aria-label="Priamy odkaz na Pravidlá o hodnotách, ktoré nie sú také, ako si myslíte" title="Priamy odkaz na Pravidlá o hodnotách, ktoré nie sú také, ako si myslíte" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-91---čítanie-až-po-zápise-mandatory">Rule 9.1 - čítanie až po zápise (Mandatory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-91---%C4%8D%C3%ADtanie-a%C5%BE-po-z%C3%A1pise-mandatory" class="hash-link" aria-label="Priamy odkaz na Rule 9.1 - čítanie až po zápise (Mandatory)" title="Priamy odkaz na Rule 9.1 - čítanie až po zápise (Mandatory)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> nečítajte premennú s automatickou dobou trvania skôr, než jej bola priradená hodnota.</p>
<p><strong>Čo získate:</strong> hodnota takej premennej je náhodný odpad a pri inom kompilátore alebo úrovni optimalizácie je to <em>iný</em> odpad. Chyby typu „v debugu funguje, v release nie“ sa veľmi často končia tu. Keďže je pravidlo mandatory, výnimka nie je možná.</p>
<p>Zlé, premenná sa nastaví iba na jednej ceste:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gain_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool isHigh</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> gain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">isHigh</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> gain </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> gain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* indeterminate value when isHigh is false */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Dobré, každá cesta má definovanú hodnotu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Gain_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool isHigh</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> gain </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">isHigh</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> gain </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> gain</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> kompilátor niekedy (<code>-Wall -Wmaybe-uninitialized</code> s optimalizáciou), statický analyzátor spoľahlivo. V mojom testovacom builde gcc pri tejto funkcii mlčal. Nespoliehajte sa naň.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rules-101-103-104---essential-types-required">Rules 10.1, 10.3, 10.4 - essential types (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rules-101-103-104---essential-types-required" class="hash-link" aria-label="Priamy odkaz na Rules 10.1, 10.3, 10.4 - essential types (Required)" title="Priamy odkaz na Rules 10.1, 10.3, 10.4 - essential types (Required)" translate="no">​</a></h4>
<p><strong>Pravidlá:</strong> autori MISRA vymysleli <em>model essential types</em>: typ, ktorý výraz <em>vyzerá, že má</em> (<code>uint8_t</code> zostáva v ich pohľade „unsigned 8 bit“), na rozdiel od typu, ktorý C potichu používa (<code>int</code>, kvôli integer promotion). Pravidlá zakazujú operácie medzi nevhodnými typmi, priradenie hodnoty do užšieho typu a miešanie kategórií (signed, unsigned, boolean, character, floating).</p>
<p><strong>Čo získate:</strong> integer promotion sú najväčším zdrojom prekvapení v embedded C. Všetky hodnoty menšie než <code>int</code> sa pred akoukoľvek aritmetikou povýšia na <code>int</code> a vy to nevidíte. Dva klasické dôsledky:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Flags_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token plain">flags </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0xF0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ~flags is an int: 0xFFFFFFF0 - never equal */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><code>~flags</code> nie je 8-bitová hodnota, je to <code>int</code> s hodnotou <code>0xFFFFFFF0</code>. Porovnanie nikdy neuspeje, nech je argument akýkoľvek. Oprava je povedať, čo myslíte:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Flags_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token plain">flags </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0xF0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Druhý klasický prípad je tiché zúženie:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Add_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">      </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* int result silently narrowed */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><code>200 + 100</code> sa vypočíta ako <code>int</code> (300) a priradenie do <code>uint8_t</code> ponechá iba 44. Žiadne varovanie, žiadna chyba, nesprávny súčet. Dva správne varianty: rozšíriť výsledok, alebo pretypovať zámerne a rozmyslieť si pretečenie.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Add_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">first </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> dobrý statický analyzátor. Kompilátor pomáha len čiastočne: <code>-Wsign-compare</code> (súčasť <code>-Wextra</code>) ohlásil prvý príklad, zatiaľ čo pri druhom gcc mlčal.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="directive-46---typy-s-veľkosťou-a-znamienkom-advisory">Directive 4.6 - typy s veľkosťou a znamienkom (Advisory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#directive-46---typy-s-ve%C4%BEkos%C5%A5ou-a-znamienkom-advisory" class="hash-link" aria-label="Priamy odkaz na Directive 4.6 - typy s veľkosťou a znamienkom (Advisory)" title="Priamy odkaz na Directive 4.6 - typy s veľkosťou a znamienkom (Advisory)" translate="no">​</a></h4>
<p><strong>Smernica:</strong> namiesto <code>char</code>, <code>short</code>, <code>int</code> a <code>long</code> používajte typedefy, ktoré hovoria o veľkosti a znamienku (<code>uint8_t</code>, <code>int32_t</code> alebo vlastné názvy).</p>
<p><strong>Čo získate:</strong> šírka <code>int</code> závisí od kompilátora a MCU: 16 bitov na malých 8- a 16-bitových kontroléroch, 32 bitov na Cortex-M. Kód, ktorý funguje na jednom cieli, sa na inom potichu zmení. S typmi pevnej šírky je v zdrojáku vidieť, čo kód robí. V mojich projektoch idem o krok ďalej a vytváram vlastné názvy typov pre fyzikálne veličiny (<code>temperature_t</code>, <code>humidity_t</code>), aby ma kompilátor zastavil, keď ich pomiešam.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">int</span><span class="token plain"> counter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 16 or 32 bits? the answer depends on the target */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> counter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 16 bits everywhere */</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-13---žiadne-nedefinované-správanie-required">Rule 1.3 - žiadne nedefinované správanie (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-13---%C5%BEiadne-nedefinovan%C3%A9-spr%C3%A1vanie-required" class="hash-link" aria-label="Priamy odkaz na Rule 1.3 - žiadne nedefinované správanie (Required)" title="Priamy odkaz na Rule 1.3 - žiadne nedefinované správanie (Required)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> program nesmie obsahovať nedefinované správanie. Patrí sem pretečenie so znamienkom, posuny o príliš veľa bitov, delenie nulou, použitie visiaceho ukazovateľa a mnoho ďalšieho.</p>
<p><strong>Čo získate:</strong> pri nedefinovanom správaní môže kompilátor urobiť <em>čokoľvek</em>, vrátane odstránenia vašej bezpečnostnej kontroly, pretože „tento prípad nemôže nastať“. Najznámejším príkladom je pretečenie so znamienkom: <code>first + second</code> na <code>int32_t</code>, ktoré sa nezmestí, nie je „zalomenie“, je to povolenie pre optimalizátor.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Add_Bad2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">             </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* signed overflow is undefined behaviour */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Správny kód skontroluje podmienku <em>pred</em> operáciou a nahlási problém volajúcemu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Add_Safe</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">int32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    bool isOk </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">second </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">first </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">INT32_MAX </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">||</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">second </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">first </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">INT32_MIN </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        isOk </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> isOk</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>To isté platí pre posuny. Maska bitovej pozície je definovaná iba vtedy, ak je pozícia menšia než šírka typu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bit_Mask</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> position</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">position </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">32u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token plain"> position</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> sčasti kompilátor (<code>-fsanitize=undefined</code> to počas testov nájde za behu), sčasti analyzátor. Pravidlo je vo všeobecnosti nerozhodnuteľné: nástroj vám dokáže ukázať všetky miesta, ktoré by mohli byť problém.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-o-podmienkach-a-riadení-toku">Pravidlá o podmienkach a riadení toku<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#pravidl%C3%A1-o-podmienkach-a-riaden%C3%AD-toku" class="hash-link" aria-label="Priamy odkaz na Pravidlá o podmienkach a riadení toku" title="Priamy odkaz na Pravidlá o podmienkach a riadení toku" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-144---riadiaci-výraz-je-boolean-required">Rule 14.4 - riadiaci výraz je boolean (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-144---riadiaci-v%C3%BDraz-je-boolean-required" class="hash-link" aria-label="Priamy odkaz na Rule 14.4 - riadiaci výraz je boolean (Required)" title="Priamy odkaz na Rule 14.4 - riadiaci výraz je boolean (Required)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> podmienka v <code>if</code>, <code>while</code> a <code>for</code> musí byť výraz s essential typom Boolean, t. j. výsledok porovnania alebo <code>bool</code>. Samotné celé číslo alebo ukazovateľ nie je povolené.</p>
<p><strong>Čo získate:</strong> zámer je čitateľný. <code>while (count)</code> nehovorí, či chcete „kým nie je nula“, alebo „kým nie je koniec“. Explicitný tvar vyzerá rovnako pre čísla, ukazovatele aj príznaky. (Konštantu píšem na ľavú stranu, <code>0u != count</code>, aby sa preklep s jedným <code>=</code> neskompiloval.)</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Count_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> steps </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> count</span><span class="token operator" style="color:rgb(137, 221, 255)">--</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> steps</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Count_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> steps </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">while</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> count</span><span class="token operator" style="color:rgb(137, 221, 255)">--</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> steps</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> steps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> každý analyzátor MISRA, je to rozhodnuteľné pravidlo.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-121---explicitná-precedencia-operátorov-advisory">Rule 12.1 - explicitná precedencia operátorov (Advisory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-121---explicitn%C3%A1-precedencia-oper%C3%A1torov-advisory" class="hash-link" aria-label="Priamy odkaz na Rule 12.1 - explicitná precedencia operátorov (Advisory)" title="Priamy odkaz na Rule 12.1 - explicitná precedencia operátorov (Advisory)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> nespoliehajte sa, že si čitateľ (a vy sami) zapamätá tabuľku precedencie, používajte zátvorky.</p>
<p><strong>Čo získate:</strong> precedencia <code>&amp;</code> a <code>==</code> v C je opačná, než čaká ľudský mozog. Toto je chyba, ktorú napíše každý aspoň raz:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Masked_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">flags </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> MASK </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> MASK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* == binds stronger than &amp; */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><code>MASK == MASK</code> sa vyhodnotí ako prvé a dá <code>1</code>, takže funkcia testuje bit 0 a nie masku. Vráti <code>true</code> pre <code>0x01</code> a <code>false</code> pre <code>0x0C</code>, presne naopak. So zátvorkami chyba nemôže vzniknúť:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Masked_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> flags</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">flags </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> MASK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> MASK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> kompilátor (<code>-Wparentheses</code> je súčasť <code>-Wall</code>) a každý analyzátor.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rules-156-157-163-a-164---úplné-príkazy-required">Rules 15.6, 15.7, 16.3 a 16.4 - úplné príkazy (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rules-156-157-163-a-164---%C3%BApln%C3%A9-pr%C3%ADkazy-required" class="hash-link" aria-label="Priamy odkaz na Rules 15.6, 15.7, 16.3 a 16.4 - úplné príkazy (Required)" title="Priamy odkaz na Rules 15.6, 15.7, 16.3 a 16.4 - úplné príkazy (Required)" translate="no">​</a></h4>
<p><strong>Pravidlá:</strong></p>
<ul>
<li class="">15.6: telo <code>if</code>, <code>else</code>, <code>for</code>, <code>while</code> je vždy blok v zložených zátvorkách,</li>
<li class="">15.7: každý reťazec <code>if ... else if</code> končí vetvou <code>else</code>,</li>
<li class="">16.3: každá vetva <code>switch</code> končí <code>break</code> (alebo iným bezpodmienečným skokom),</li>
<li class="">16.4: každý <code>switch</code> má <code>default</code>.</li>
</ul>
<p><strong>Čo získate:</strong> pravidlá vás nútia odpovedať na otázku „čo sa stane vo všetkých ostatných prípadoch?“ v okamihu, keď kód píšete, a nie v teréne. <code>switch</code> bez <code>break</code> je klasická chyba, <code>enum</code>, ktorý dostane novú hodnotu bez <code>default</code>, je druhá. Zložené zátvorky odstraňujú celú rodinu chýb, keď sa pod <code>if</code> pridá druhý príkaz a vyzerá, že je podmienený:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">isError</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Led_On</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Buzzer_On</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">      </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* indented like it belongs to the if - it does not */</span><br></div></code></pre></div></div>
<p>A tu je switch. Prvá verzia prepadne z <code>MODE_ON</code> do <code>MODE_ERROR</code> a nastaví zlú hodnotu, druhá ošetrí každý prípad explicitne:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Mode_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">mode_t_ mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> MODE_ON</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            gLeds </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> MODE_ERROR</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain">               </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* falls through by accident */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            gLeds </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">break</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Mode_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">mode_t_ mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">mode</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> MODE_ON</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            gLeds </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">break</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> MODE_ERROR</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            gLeds </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">break</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> MODE_OFF</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">default</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            gLeds </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">break</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>V mojom teste gcc našiel chýbajúci <code>default</code> aj prepadnutie (<code>-Wswitch-default -Wimplicit-fallthrough</code>). Pravidlo o <code>else</code> a zložené zátvorky kontroluje analyzátor alebo formátovač.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-172---žiadna-rekurzia-required">Rule 17.2 - žiadna rekurzia (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-172---%C5%BEiadna-rekurzia-required" class="hash-link" aria-label="Priamy odkaz na Rule 17.2 - žiadna rekurzia (Required)" title="Priamy odkaz na Rule 17.2 - žiadna rekurzia (Required)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> funkcia nesmie volať samu seba, ani priamo, ani cez iné funkcie.</p>
<p><strong>Čo získate:</strong> na PC má zásobník megabajty. Na mikrokontroléri máte pár kilobajtov a najhorší prípad hĺbky rekurzie závisí od vstupných dát. Ak rekurziu odstránite, maximálne využitie zásobníka sa dá <em>vypočítať</em> (stačí statická analýza stromu volaní) a pretečenie zásobníka prestane byť prekvapením.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Factorial_Recursive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">value </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> value </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Factorial_Recursive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">value </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Iteratívna verzia potrebuje konštantné množstvo zásobníka:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Factorial_Iterative</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> result </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> factor </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> factor </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> factor</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> result </span><span class="token operator" style="color:rgb(137, 221, 255)">*=</span><span class="token plain"> factor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> analyzátor a linker map (niektoré toolchainy vypíšu graf volaní, <code>-fstack-usage</code> povie veľkosť každého rámca).</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-o-pamäti-a-ukazovateľoch">Pravidlá o pamäti a ukazovateľoch<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#pravidl%C3%A1-o-pam%C3%A4ti-a-ukazovate%C4%BEoch" class="hash-link" aria-label="Priamy odkaz na Pravidlá o pamäti a ukazovateľoch" title="Priamy odkaz na Pravidlá o pamäti a ukazovateľoch" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="directive-412-a-rule-213---žiadna-dynamická-pamäť-required">Directive 4.12 a Rule 21.3 - žiadna dynamická pamäť (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#directive-412-a-rule-213---%C5%BEiadna-dynamick%C3%A1-pam%C3%A4%C5%A5-required" class="hash-link" aria-label="Priamy odkaz na Directive 4.12 a Rule 21.3 - žiadna dynamická pamäť (Required)" title="Priamy odkaz na Directive 4.12 a Rule 21.3 - žiadna dynamická pamäť (Required)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> nepoužívajte <code>malloc</code>, <code>calloc</code>, <code>realloc</code> a <code>free</code>.</p>
<p><strong>Čo získate:</strong></p>
<ul>
<li class="">halda sa <em>fragmentuje</em>. Po týždňoch behu môže zlyhať požiadavka na 64 bajtov, hoci je voľných 10 kB, len nie v jednom kuse,</li>
<li class="">doba vykonania <code>malloc</code> nie je deterministická,</li>
<li class="">únik pamäte po týždňoch behu je najhorší druh chyby, aký sa dá hľadať,</li>
<li class="">spotreba pamäte je známa v čase linkovania, nie o 3. ráno v teréne.</li>
</ul>
<p>Štandardnou alternatívou je pool s pevnou veľkosťou, ktorý má rovnaký tvar API ako alokátor:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">FRAME_POOL_SIZE</span><span class="token macro property"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">4u</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    bool    inUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">frame_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">frame_t</span><span class="token plain"> framePool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">FRAME_POOL_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">frame_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token function" style="color:rgb(130, 170, 255)">Frame_Acquire</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> FRAME_POOL_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">!</span><span class="token plain">framePool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">inUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> framePool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">inUse </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">framePool</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                       </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* the caller has to handle "no frame" - at test time, not at 3 a.m. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Funkcia vráti <code>NULL</code>, ak sú všetky rámce obsadené, takže prípad „nie je pamäť“ je v kóde ošetrený a dá sa testovať na PC. Presne to isté sa deje pri <code>malloc</code>, len to otestovať nemôžete, pretože na vašom PC alokácia nikdy nezlyhá.</p>
<p><strong>Kto to nájde:</strong> analyzátor, alebo jednoducho linker, ktorý <code>malloc</code> vôbec nelinkuje.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rules-113-a-115---opatrne-s-pretypovaním-ukazovateľov-required--advisory">Rules 11.3 a 11.5 - opatrne s pretypovaním ukazovateľov (Required / Advisory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rules-113-a-115---opatrne-s-pretypovan%C3%ADm-ukazovate%C4%BEov-required--advisory" class="hash-link" aria-label="Priamy odkaz na Rules 11.3 a 11.5 - opatrne s pretypovaním ukazovateľov (Required / Advisory)" title="Priamy odkaz na Rules 11.3 a 11.5 - opatrne s pretypovaním ukazovateľov (Required / Advisory)" translate="no">​</a></h4>
<p><strong>Pravidlá:</strong> nepretypúvajte ukazovateľ na objekt jedného typu na ukazovateľ na objekt iného typu (11.3) a vyhýbajte sa konverzii z <code>void *</code> na ukazovateľ na objekt (11.5).</p>
<p><strong>Čo získate:</strong> pretypovanie bajtového bufferu na <code>uint32_t *</code> je najčastejší spôsob, ako prečítať pole komunikačného rámca:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ReadU32_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* misaligned access, strict aliasing violation */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Je to nedefinované správanie hneď dvakrát. Adresa nemusí byť zarovnaná na štyri bajty (hard fault na Cortex-M0, pomalý prístup inde) a prístup cez ukazovateľ iného typu porušuje pravidlá aliasingu, takže ho optimalizátor môže preusporiadať alebo zahodiť. Dve správne riešenia: <code>memcpy</code> (kompilátor ho zmení na jediné načítanie, kde to hardvér dovoľuje) alebo poskladanie bajtov, ktoré zároveň vyrieši poradie bajtov a nezávisí od endianity CPU:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ReadU32_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">memcpy</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ReadU32LittleEndian</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">16</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">|</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">buffer</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">24</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Pretypovanie <code>void *</code> je typické pre generický kontext callbacku. Je advisory, pretože v C je to niekedy jediná cesta. Prínosom pravidla je, že si všimnete každé takéto miesto a pretypovanie urobíte na jedinom riadku na začiatku funkcie (ako v <a class="" href="https://embedbits.cz/sk/blog/solid-principles-c-cpp">článku o SOLID</a>), a nie všade.</p>
<p><strong>Kto to nájde:</strong> každý analyzátor. Kompilátor nájde pretypovanie len na niektorých cieľoch a s <code>-Wcast-align</code>.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-813---ukazovateľ-na-const-keď-sa-dá-advisory">Rule 8.13 - ukazovateľ na const, keď sa dá (Advisory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-813---ukazovate%C4%BE-na-const-ke%C4%8F-sa-d%C3%A1-advisory" class="hash-link" aria-label="Priamy odkaz na Rule 8.13 - ukazovateľ na const, keď sa dá (Advisory)" title="Priamy odkaz na Rule 8.13 - ukazovateľ na const, keď sa dá (Advisory)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> ak funkcia nemení dáta za ukazovateľom, ukazovateľ sa deklaruje ako ukazovateľ na <code>const</code>.</p>
<p><strong>Čo získate:</strong> signatúra je zmluva. Volajúci vidí z prototypu, že funkcia iba číta, a kompilátor to stráži. <code>const</code> buffer z flash sa dá odovzdať iba funkcii s <code>const</code>, inak sa kód neskompiluje (alebo ešte horšie, zapíše do flash a spôsobí fault).</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Checksum_Bad</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sum </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Checksum_Good</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> index</span><span class="token operator" style="color:rgb(137, 221, 255)">++</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sum </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sum</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="pravidlá-o-kóde-ktorý-ste-napísali-a-kóde-ktorý-tam-nie-je">Pravidlá o kóde, ktorý ste napísali, a kóde, ktorý tam nie je<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#pravidl%C3%A1-o-k%C3%B3de-ktor%C3%BD-ste-nap%C3%ADsali-a-k%C3%B3de-ktor%C3%BD-tam-nie-je" class="hash-link" aria-label="Priamy odkaz na Pravidlá o kóde, ktorý ste napísali, a kóde, ktorý tam nie je" title="Priamy odkaz na Pravidlá o kóde, ktorý ste napísali, a kóde, ktorý tam nie je" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-177-a-directive-47---neignorujte-výsledky-required">Rule 17.7 a Directive 4.7 - neignorujte výsledky (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-177-a-directive-47---neignorujte-v%C3%BDsledky-required" class="hash-link" aria-label="Priamy odkaz na Rule 17.7 a Directive 4.7 - neignorujte výsledky (Required)" title="Priamy odkaz na Rule 17.7 a Directive 4.7 - neignorujte výsledky (Required)" translate="no">​</a></h4>
<p><strong>Pravidlá:</strong> vrátená hodnota sa musí použiť (17.7) a keď funkcia vracia chybový kód, musí sa otestovať (4.7).</p>
<p><strong>Čo získate:</strong> ignorovaná návratová hodnota je ignorovaná chyba. Odoslanie rámca na zaneprázdnené UART, odmietnutý zápis do flash, timeout I2C: všetko to potichu prejde a aplikácia pokračuje s nesprávnym predpokladom. Ak vám na tom naozaj nezáleží, povedzte to cez <code>(void)</code>, aby čitateľ (a analyzátor) vedel, že to bolo rozhodnutie a nie chyba:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Send_Checked</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">UART_OK </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">message</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> message</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* a log message, loss is acceptable */</span><br></div></code></pre></div></div>
<p><strong>Kto to nájde:</strong> analyzátor, v gcc s <code>__attribute__((warn_unused_result))</code> na vlastnom API.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rules-21-a-22---žiadny-nedosiahnuteľný-ani-mŕtvy-kód-required">Rules 2.1 a 2.2 - žiadny nedosiahnuteľný ani mŕtvy kód (Required)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rules-21-a-22---%C5%BEiadny-nedosiahnute%C4%BEn%C3%BD-ani-m%C5%95tvy-k%C3%B3d-required" class="hash-link" aria-label="Priamy odkaz na Rules 2.1 a 2.2 - žiadny nedosiahnuteľný ani mŕtvy kód (Required)" title="Priamy odkaz na Rules 2.1 a 2.2 - žiadny nedosiahnuteľný ani mŕtvy kód (Required)" translate="no">​</a></h4>
<p><strong>Pravidlá:</strong> projekt nesmie obsahovať kód, ktorý sa nikdy nemôže vykonať (2.1), a kód, ktorý sa vykoná, ale nemá vplyv na výsledok (2.2).</p>
<p><strong>Čo získate:</strong> oba druhy sú signálom chyby: podmienka, ktorá nikdy nenastane, zabudnutý <code>return</code> alebo chyba z copy-paste. Mŕtvy kód tiež falšuje pokrytie testami (nemôžete dosiahnuť 100 % riadkov, ktoré nevykoná žiadny vstup) a núti čitateľa o ňom premýšľať. Oba sa objavujú v tejto funkcii:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Level_Get</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> raw</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> level </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* dead: overwritten before it is read */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    level </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">raw </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">2u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> level</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Level_Log</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">raw</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* unreachable */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Prvé priradenie <code>level</code> je mŕtve a posledný riadok je nedosiahnuteľný.</p>
<p><strong>Kto to nájde:</strong> analyzátor. gcc s <code>-Wall -Wextra</code> v mojom teste mlčal.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="rule-207-a-directive-49---makrá-s-parametrami-required--advisory">Rule 20.7 a Directive 4.9 - makrá s parametrami (Required / Advisory)<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#rule-207-a-directive-49---makr%C3%A1-s-parametrami-required--advisory" class="hash-link" aria-label="Priamy odkaz na Rule 20.7 a Directive 4.9 - makrá s parametrami (Required / Advisory)" title="Priamy odkaz na Rule 20.7 a Directive 4.9 - makrá s parametrami (Required / Advisory)" translate="no">​</a></h4>
<p><strong>Pravidlo:</strong> rozvinutý parameter makra musí byť v zátvorkách (20.7) a funkcia je preferovaná pred makrom podobným funkcii (4.9).</p>
<p><strong>Čo získate:</strong> makro je textová náhrada. Ak parameter nechránite, rozhodne precedencia <em>volajúceho</em>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name function" style="color:rgb(130, 170, 255)">SQUARE_BAD</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">x</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">  x </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression"> x</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name function" style="color:rgb(130, 170, 255)">SQUARE_OK</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">x</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression">   </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">x</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression">x</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">SQUARE_BAD</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* 2 + 1 * 2 + 1 = 5, not 9 */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token function" style="color:rgb(130, 170, 255)">SQUARE_OK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ((2 + 1) * (2 + 1)) = 9 */</span><br></div></code></pre></div></div>
<p>Aj chránené makro má problém: <code>SQUARE_OK(count++)</code> inkrementuje dvakrát. Preto smernica 4.9 odporúča funkciu. Inline funkcia má typ, vyhodnotí argument raz a stojí rovnako:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Square</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> value </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> value</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="misra-v-reálnom-projekte">MISRA v reálnom projekte<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#misra-v-re%C3%A1lnom-projekte" class="hash-link" aria-label="Priamy odkaz na MISRA v reálnom projekte" title="Priamy odkaz na MISRA v reálnom projekte" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="varovania-kompilátora-sú-prvý-krok-nie-posledný">Varovania kompilátora sú prvý krok, nie posledný<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#varovania-kompil%C3%A1tora-s%C3%BA-prv%C3%BD-krok-nie-posledn%C3%BD" class="hash-link" aria-label="Priamy odkaz na Varovania kompilátora sú prvý krok, nie posledný" title="Priamy odkaz na Varovania kompilátora sú prvý krok, nie posledný" translate="no">​</a></h3>
<p>Všetky vyššie uvedené príklady som skompiloval s <code>gcc -Wall -Wextra -Wconversion -Wshadow -Wswitch-default -Wimplicit-fallthrough -O2</code>. gcc nahlásil päť varovaní a týkajú sa iba troch „zlých“ príkladov: porovnania s povýšeným doplnkom, <code>switch</code> (chýbajúci <code>default</code>, neošetrená hodnota enumu a prepadnutie) a chýbajúcich zátvoriek okolo <code>==</code> pri teste masky. Mlčal o zúžení, neinicializovanej premennej, mŕtvom a nedosiahnuteľnom kóde, pretečení so znamienkom, rekurzii, pretypovaní ukazovateľa a makre.</p>
<p>Moje odporúčanie je kompilátor s maximom varovaní a <code>-Werror</code> v CI ako základ. Je to zadarmo a odstráni najzrejmejšie problémy, ale nenahrádza statickú analýzu.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="vyberte-nástroj-a-dajte-ho-do-ci">Vyberte nástroj a dajte ho do CI<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#vyberte-n%C3%A1stroj-a-dajte-ho-do-ci" class="hash-link" aria-label="Priamy odkaz na Vyberte nástroj a dajte ho do CI" title="Priamy odkaz na Vyberte nástroj a dajte ho do CI" translate="no">​</a></h3>
<p>Na kontrolu pravidiel potrebujete statický analyzátor. Existujú komerčné (Polyspace, Helix QAC, PC-lint Plus, Coverity, Parasoft C/C++test, LDRA, IAR C-STAT a ďalšie) aj bezplatné, ktoré pokrývajú časť pravidiel, napríklad <a href="https://cppcheck.sourceforge.io/" target="_blank" rel="noopener noreferrer" class="">cppcheck</a> s doplnkom pre MISRA. Doplnok potrebuje na vstupe text pravidiel a kvôli autorským právam ho musíte dodať z vlastnej kópie normy. Nástroj nie je nikdy dokonalý: pri nerozhodnuteľných pravidlách budete mať falošné poplachy a niekedy sa porušenie prehliadne.</p>
<p>Kontrola patrí do CI pri každom commite, nie do manuálneho behu pred vydaním. Inak tú istú prácu robíte trikrát: raz keď píšete, raz keď sa nájdu porušenia a raz keď ich opravujete.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="výnimky-sú-súčasťou-systému">Výnimky sú súčasťou systému<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#v%C3%BDnimky-s%C3%BA-s%C3%BA%C4%8Das%C5%A5ou-syst%C3%A9mu" class="hash-link" aria-label="Priamy odkaz na Výnimky sú súčasťou systému" title="Priamy odkaz na Výnimky sú súčasťou systému" translate="no">​</a></h3>
<p>Niekedy sa pravidlo musí porušiť. Prístup k hardvérovému registru potrebuje pretypovanie celého čísla na ukazovateľ, bootloader potrebuje zapisovať do flash cez ukazovateľ. MISRA to pozná a definuje <strong>deviation</strong> (výnimku): záznam s pravidlom, miestom, dôvodom a posúdením rizika. Záznam by mal byť hneď vedľa kódu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* MISRA deviation: Rule 11.4 (Advisory), see DEV-012</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Reason: the address of the peripheral register is fixed by the hardware.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Contained in this macro, the rest of the code uses the register type. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">UART_REGS</span><span class="token macro property"> </span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token macro property expression class-name" style="color:rgb(255, 203, 107)">uartRegisters_t</span><span class="token macro property expression"> </span><span class="token macro property expression operator" style="color:rgb(137, 221, 255)">*</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">0x40004400u</span><span class="token macro property expression punctuation" style="color:rgb(199, 146, 234)">)</span><br></div></code></pre></div></div>
<p>Výnimka nie je zlyhanie. Zoznam dobre odôvodnených výnimiek je znakom projektu, v ktorom ľudia premýšľajú. Projekt s nulou výnimiek a bez prístupu k hardvéru buď klame, alebo je veľmi malý.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="legacy-kód-a-kód-od-výrobcu">Legacy kód a kód od výrobcu<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#legacy-k%C3%B3d-a-k%C3%B3d-od-v%C3%BDrobcu" class="hash-link" aria-label="Priamy odkaz na Legacy kód a kód od výrobcu" title="Priamy odkaz na Legacy kód a kód od výrobcu" translate="no">​</a></h3>
<p>200 000 riadkov starého projektu nespravíte vyhovujúcich za týždeň. Čo funguje:</p>
<ol>
<li class=""><strong>Starý kód nechajte na pokoji,</strong> zapnite kontrolu pre <em>nové a zmenené</em> súbory. Baseline analyzátora uloží existujúce porušenia a CI zlyhá iba na nových.</li>
<li class=""><strong>Začnite s pravidlami mandatory a required,</strong> advisory neskôr.</li>
<li class=""><strong>Vylúčte kód tretích strán</strong> a zdokumentujte to. Generovaný kód od výrobcu (HAL, LL, CMSIS) nie je vaša vec opravovať. To je ďalší dôvod pre vrstvovú architektúru z článku o <a class="" href="https://embedbits.cz/sk/blog/design-architecture">dizajne a architektúre</a>: keď kód výrobcu sedí v RAL a MCAL a všetko nad ním je váš kód, hranicou kontroly je priečinok.</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-nepomáha">Čo nepomáha<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#%C4%8Do-nepom%C3%A1ha" class="hash-link" aria-label="Priamy odkaz na Čo nepomáha" title="Priamy odkaz na Čo nepomáha" translate="no">​</a></h3>
<ul>
<li class=""><strong>Naháňanie počtu porušení.</strong> Pravidlo opravené spôsobom, ktorý uspokojí nástroj a pokazí zmysel (pretypovanie pridané iba na umlčanie varovania), je horšie než pôvodný stav.</li>
<li class=""><strong>Používanie MISRA ako argumentu.</strong> „MISRA to hovorí“ nie je dôvod. Ak neviete vysvetliť, pred čím vás pravidlo chráni, nebudete vedieť rozhodnúť, kedy je čas na výnimku.</li>
<li class=""><strong>Viera, že vyhovenie znamená správnosť.</strong> MISRA robí niektoré chyby nemožnými. Požiadavky, architektúra, review a testy zostávajú na vás.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="zhrnutie">Zhrnutie<a href="https://embedbits.cz/sk/blog/misra-c-rules-in-practice#zhrnutie" class="hash-link" aria-label="Priamy odkaz na Zhrnutie" title="Priamy odkaz na Zhrnutie" translate="no">​</a></h2>
















































































<table><thead><tr><th>Pravidlo</th><th>Skrátene</th><th>Prínos</th></tr></thead><tbody><tr><td>9.1</td><td>Inicializovať pred čítaním</td><td>Žiadne náhodné hodnoty, rovnaké správanie v debugu a release</td></tr><tr><td>10.x</td><td>Rešpektovať essential types</td><td>Žiadne prekvapenia z integer promotion a zúženia</td></tr><tr><td>Dir 4.6</td><td>Typy pevnej šírky</td><td>Rovnaký kód znamená to isté na každom cieli</td></tr><tr><td>1.3</td><td>Žiadne nedefinované správanie</td><td>Optimalizátor nemôže odstrániť vaše kontroly</td></tr><tr><td>14.4</td><td>Explicitné podmienky</td><td>Zámer je čitateľný</td></tr><tr><td>12.1</td><td>Zátvorky</td><td>Žiadne chyby precedencie</td></tr><tr><td>15.6, 15.7, 16.3, 16.4</td><td>Zložené zátvorky, <code>else</code>, <code>break</code>, <code>default</code></td><td>Každý prípad je ošetrený</td></tr><tr><td>17.2</td><td>Žiadna rekurzia</td><td>Využitie zásobníka sa dá vypočítať</td></tr><tr><td>Dir 4.12, 21.3</td><td>Žiadna dynamická pamäť</td><td>Žiadna fragmentácia, úniky a prekvapenia v časovaní</td></tr><tr><td>11.3, 11.5</td><td>Žiadne triky s typmi ukazovateľov</td><td>Žiadne chyby zarovnania a aliasingu</td></tr><tr><td>8.13</td><td>Ukazovatele <code>const</code></td><td>Signatúra je zmluva</td></tr><tr><td>17.7, Dir 4.7</td><td>Používať návratové hodnoty</td><td>Chyby nezmiznú</td></tr><tr><td>2.1, 2.2</td><td>Žiadny nedosiahnuteľný ani mŕtvy kód</td><td>Chyby sú viditeľné, pokrytie má zmysel</td></tr><tr><td>20.7, Dir 4.9</td><td>Bezpečné makrá, preferovať funkcie</td><td>Žiadne skryté dvojité vyhodnotenie ani chyby precedencie</td></tr></tbody></table>
<p>Ak si zapamätáte jedinú vec: <strong>pravidlo MISRA je jazva po chybe, ktorú už niekto mal.</strong> Nemusíte tie pravidlá mať radi, ale je dobré vedieť, po čom je každé z nich jazvou. Potom budete vedieť, kedy ho dodržať a kedy napísať výnimku a prevziať zodpovednosť.</p>
<p>Tu opísané pravidlá sú len výber. Celá sada má viac než 140 smerníc a zvyšok (preprocesor, štandardná knižnica, štruktúra deklarácií) stojí za to raz prečítať vo vlastnej kópii normy.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>C</category>
            <category>MISRA</category>
        </item>
        <item>
            <title><![CDATA[Princípy SOLID: od tried v C++ po čisté C]]></title>
            <link>https://embedbits.cz/sk/blog/solid-principles-c-cpp</link>
            <guid>https://embedbits.cz/sk/blog/solid-principles-c-cpp</guid>
            <pubDate>Sat, 03 Oct 2026 21:00:00 GMT</pubDate>
            <description><![CDATA[Päť písmen, ktoré sa zrejme nachádzajú v každom pracovnom pohovore v softvérovom inžinierstve. S, O, L, I a D. Princípy boli opísané pre objektovo orientované jazyky, takže bežný záver znie „SOLID je pre C++ a Javu, my píšeme v C, takže sme z obliga“. Ten záver je nesprávny a pokúsim sa ukázať prečo. Pri každom princípe nájdete pôvodnú myšlienku s príkladom v C++ a potom tú istú myšlienku v C, bez tried, bez dedičnosti a bez jediného virtual.]]></description>
            <content:encoded><![CDATA[<p>Päť písmen, ktoré sa zrejme nachádzajú v každom pracovnom pohovore v softvérovom inžinierstve. S, O, L, I a D. Princípy boli opísané pre objektovo orientované jazyky, takže bežný záver znie „SOLID je pre C++ a Javu, my píšeme v C, takže sme z obliga“. Ten záver je nesprávny a pokúsim sa ukázať prečo. Pri každom princípe nájdete pôvodnú myšlienku s príkladom v C++ a potom tú istú myšlienku v C, bez tried, bez dedičnosti a bez jediného <code>virtual</code>.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="odkiaľ-solid-pochádza">Odkiaľ SOLID pochádza<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#odkia%C4%BE-solid-poch%C3%A1dza" class="hash-link" aria-label="Priamy odkaz na Odkiaľ SOLID pochádza" title="Priamy odkaz na Odkiaľ SOLID pochádza" translate="no">​</a></h2>
<p>Princípy zhromaždil Robert C. Martin („Uncle Bob“) na začiatku 21. storočia, samotnú skratku vymyslel Michael Feathers. Niektoré myšlienky sú oveľa staršie: <em>open/closed principle</em> pochádza od Bertranda Meyera (1988) a <em>Liskov substitution principle</em> od Barbary Liskovovej (1987).</p>
<p>Všetky odpovedajú na jednu otázku: <strong>ako napísať kód, ktorý prežije zmenu?</strong> Nie kód, ktorý funguje dnes, ale kód, ktorý sa dá rozširovať, testovať a udržiavať chlapíkom z citátu na titulnej strane, ktorý vie, kde bývate.</p>
<p>Príklady v C++ používajú triedy a virtuálne funkcie, pretože tak boli princípy pôvodne vysvetlené. Príklady v C sledujú <a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/coding-style">môj coding style</a>: názvy <code>Module_Function</code>, typy <code>_t</code> a premenné so zmysluplnými menami. Jedna výnimka kvôli dĺžke: používam obyčajné <code>uint8_t</code>, <code>uint32_t</code> a <code>float</code> tam, kde by skutočný projekt použil vlastné typedefy (<code>temperature_t</code>, <code>voltage_t</code>), čo coding style vyžaduje. Všetky príklady v tomto článku boli skompilované (<code>gcc -std=c11 -Wall -Wextra -pedantic</code> a <code>g++ -std=c++17</code>) a spustené s malým unit testom, vrátane tých „zlých“.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-je-trieda-v-skutočnosti">Čo je trieda v skutočnosti<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#%C4%8Do-je-trieda-v-skuto%C4%8Dnosti" class="hash-link" aria-label="Priamy odkaz na Čo je trieda v skutočnosti" title="Priamy odkaz na Čo je trieda v skutočnosti" translate="no">​</a></h3>
<p>Predtým, než začneme, krátka pripomienka toho, čo kompilátor robí v zákulisí. Trieda v C++ s virtuálnymi funkciami je:</p>
<ul>
<li class=""><code>struct</code> s dátami objektu,</li>
<li class="">skrytý ukazovateľ v tejto štruktúre na tabuľku ukazovateľov na funkcie (<em>vtable</em>), jedna tabuľka na triedu,</li>
<li class="">konvencia, že každá metóda dostane ukazovateľ na objekt ako prvý parameter (<code>this</code>).</li>
</ul>
<p>V C môžeme presne to isté napísať ručne: <code>struct</code> s dátami, <code>const struct</code> s ukazovateľmi na funkcie a <code>void *context</code> ako náhradu za <code>this</code>. Zapamätajte si to, celý článok je na tom postavený. C++ vám tu nedáva novú schopnosť, iba za vás píše boilerplate a kontroluje ho pri kompilácii.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="s---single-responsibility-principle">S - Single Responsibility Principle<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#s---single-responsibility-principle" class="hash-link" aria-label="Priamy odkaz na S - Single Responsibility Principle" title="Priamy odkaz na S - Single Responsibility Principle" translate="no">​</a></h2>
<blockquote>
<p>Modul by mal mať jeden, a iba jeden, dôvod na zmenu.</p>
</blockquote>
<p>Dôležitá je časť „dôvod na zmenu“. Neznamená „trieda má jednu metódu“. Znamená, že každá časť kódu zodpovedá jednému zdroju zmien: keď sa vymení senzor, zmení sa iba prepočet, keď zákazník chce iný formát logu, zmení sa iba formátovanie.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c">V C++<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c" class="hash-link" aria-label="Priamy odkaz na V C++" title="Priamy odkaz na V C++" translate="no">​</a></h3>
<p>Nasledujúca trieda robí všetko: číta ADC, prepočíta hodnotu, naformátuje text a odošle ho. Štyri dôvody na zmenu na jednom mieste:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">TemperatureMonitor</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint16_t</span><span class="token plain"> rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">AdcRead</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                                </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 1. hardware access</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.3f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4095.0f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.5f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">100.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 2. conversion</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">24</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">snprintf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"T=%.1f C\r\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 3. formatting</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">UartSend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                                                     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 4. communication</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Každá zmena (nový senzor, log cez CAN namiesto UART, iný formát textu) upravuje tú istú triedu a nič z toho sa nedá otestovať bez hardvéru. Oprava je oddeliť zodpovednosti a nechať monitor, aby ich iba prepájal:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">AdcChannel</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">uint16_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">AdcRead</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Tmp36Converter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ToCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint16_t</span><span class="token plain"> rawValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.3f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4095.0f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.5f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">100.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">UartLogger</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">24</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">snprintf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"T=%.1f C\r\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">UartSend</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">TemperatureMonitor</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> logger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">converter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">ToCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">adc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    AdcChannel   adc</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Tmp36Converter converter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    UartLogger   logger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-1">V C<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-1" class="hash-link" aria-label="Priamy odkaz na V C" title="Priamy odkaz na V C" translate="no">​</a></h3>
<p>Presne tá istá chyba je možná, a bežná, aj v čistom C, kde zvyčajne vyzerá ako jedna dlhá funkcia v <code>main.c</code>:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Monitor_Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Adc_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                                </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 1. hardware access</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.3f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4095.0f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.5f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">100.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 2. conversion</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">24</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">snprintf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"T=%.1f C\r\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 3. formatting</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">                                                     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// 4. communication</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Nástrojom na oddelenie v C je <strong>modul</strong>: dvojica súborov <code>.h</code>/<code>.c</code> so spoločným prefixom, kde hlavička je verejné rozhranie a všetko ostatné je <code>static</code>. Jeden modul, jedna zodpovednosť:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Tmp36.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">TMP36_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">TMP36_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Converts a raw ADC value of the TMP36 sensor into degrees Celsius. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Tmp36_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> rawValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Tmp36.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Tmp36.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Tmp36_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint16_t</span><span class="token plain"> rawValue</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">rawValue </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3.3f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4095.0f</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.5f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">100.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Logger.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">LOGGER_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">LOGGER_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Logger_Print_Temperature</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Logger.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Logger.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Logger_Print_Temperature</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">24</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">snprintf</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">sizeof</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(195, 232, 141)">"T=%.1f C\r\n"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Modul ADC (<code>Adc.h</code>) je rovnaká myšlienka a monitor iba prepája moduly:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Monitor.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Adc.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Logger.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Tmp36.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Monitor_Run</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Logger_Print_Temperature</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Tmp36_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Adc_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Ak sa TMP36 nahradí NTC, vymení sa iba <code>Tmp36.c</code>. Ak log ide cez CAN namiesto UART, zmení sa iba <code>Logger.c</code>. A <code>Tmp36_Get_Celsius()</code> sa dá otestovať na vašom PC obyčajným <code>assert</code>, pretože sa nedotýka žiadneho registra.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="o---openclosed-principle">O - Open/Closed Principle<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#o---openclosed-principle" class="hash-link" aria-label="Priamy odkaz na O - Open/Closed Principle" title="Priamy odkaz na O - Open/Closed Principle" translate="no">​</a></h2>
<blockquote>
<p>Softvérové entity by mali byť otvorené na rozširovanie, ale uzavreté na modifikáciu.</p>
</blockquote>
<p>Mali by ste vedieť pridať nové správanie bez úpravy kódu, ktorý už funguje a je otestovaný. Typický zápach je <code>switch</code> nad typom, ktorý rastie s každou novou funkciou.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-2">V C++<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-2" class="hash-link" aria-label="Priamy odkaz na V C++" title="Priamy odkaz na V C++" translate="no">​</a></h3>
<p>Pipeline nižšie sa musí upraviť pri každom novom filtri, vrátane <code>enum</code> a <code>switch</code>:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">FilterType</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> MovingAverage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Median </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">SamplePipeline</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">explicit</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">SamplePipeline</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">FilterType type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">filterType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Feed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">filterType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> FilterType</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">MovingAverage</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MovingAverageStep</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> FilterType</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">Median</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MedianStep</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// every new filter means editing this class again</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    FilterType filterType</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MovingAverageStep</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MedianStep</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Riešením je abstrakcia (rozhranie), ktorú pipeline pozná a nové filtre ju implementujú:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IFilter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IFilter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">MovingAverage</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IFilter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        sum </span><span class="token operator" style="color:rgb(137, 221, 255)">+=</span><span class="token plain"> sample </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">size</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">size</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">array</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token keyword" style="font-style:italic">float</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">4</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sum </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Median3</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IFilter</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">size</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">auto</span><span class="token plain"> sorted </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">sort</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">begin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">end</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sorted</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">array</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token keyword" style="font-style:italic">float</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">SamplePipeline</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">explicit</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">SamplePipeline</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">IFilter</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> filterToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">filterToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Feed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// never changes again</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    IFilter</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Nový filter je nová trieda. <code>SamplePipeline</code> je uzavretá na modifikáciu a systém je otvorený na rozširovanie.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-3">V C<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-3" class="hash-link" aria-label="Priamy odkaz na V C" title="Priamy odkaz na V C" translate="no">​</a></h3>
<p>Ten istý problém so <code>switch</code> v C:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> FILTER_MOVING_AVERAGE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> FILTER_MEDIAN </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterType_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Pipeline_Feed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">filterType_t</span><span class="token plain"> type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">type</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> FILTER_MOVING_AVERAGE</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MovingAverage_Step</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">case</span><span class="token plain"> FILTER_MEDIAN</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain">         </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Median_Step</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* every new filter means editing this function again */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Náhradou virtuálnej tabuľky v C je <strong>tabuľka ukazovateľov na funkcie</strong> a <code>void *context</code> pre dáta inštancie. Abstrakcia sa definuje raz:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Filter.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">FILTER_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">FILTER_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The "interface": a table of functions and the data they work on. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">              </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">filter_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">inline</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Filter_Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filter_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> filter</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">ops</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">filter</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<p>Každý filter je dvojica dát (<code>context</code>) a konštantnej tabuľky so správaním:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">MovingAverage.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">MOVING_AVERAGE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">MOVING_AVERAGE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Filter.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">MOVING_AVERAGE_SIZE</span><span class="token macro property"> </span><span class="token macro property expression number" style="color:rgb(247, 140, 108)">4u</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain">    window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">MOVING_AVERAGE_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain">    sum</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">unsigned</span><span class="token plain"> index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">movingAverage_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token plain"> movingAverageOps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">MovingAverage.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"MovingAverage.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">MovingAverage_Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">movingAverage_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">self </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">sum </span><span class="token operator" style="color:rgb(137, 221, 255)">+=</span><span class="token plain"> sample </span><span class="token operator" style="color:rgb(137, 221, 255)">-</span><span class="token plain"> self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">window</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> MOVING_AVERAGE_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">sum </span><span class="token operator" style="color:rgb(137, 221, 255)">/</span><span class="token plain"> MOVING_AVERAGE_SIZE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token plain"> movingAverageOps </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Process </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> MovingAverage_Process </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Druhý filter je úplne samostatný modul, prvého sa nikto nedotkol:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Median3.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">MEDIAN3_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">MEDIAN3_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Filter.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain">    last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">3</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">unsigned</span><span class="token plain"> index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">median3_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">extern</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token plain"> median3Ops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Median3.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Median3.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Median3_Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">median3_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">self </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token plain">self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">index </span><span class="token operator" style="color:rgb(137, 221, 255)">+</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">1u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">3u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> second </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> third </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> self</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">last</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token number" style="color:rgb(247, 140, 108)">2</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">first </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> second </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> second </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> third</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">||</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">third </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> second </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> second </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">second </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> third</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">||</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">third </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> first </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> second</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> first</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> third</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filterOps_t</span><span class="token plain"> median3Ops </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Process </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Median3_Process </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Pipeline pozná iba <code>filter_t</code>, takže sa už nikdy nemusí meniť:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Pipeline.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Filter.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Pipeline_Feed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filter_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Filter_Process</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">filter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* never changes again */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>A takto sa používa. Oba filtre fungujú s rovnakou pipeline:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token class-name" style="color:rgb(255, 203, 107)">movingAverage_t</span><span class="token plain"> average </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filter_t</span><span class="token plain"> averageFilter </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">movingAverageOps</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">average </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">median3_t</span><span class="token plain"> median </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">filter_t</span><span class="token plain"> medianFilter </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">median3Ops</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">median </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> output </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Pipeline_Feed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">medianFilter</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> sample</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Tabuľky sú <code>const</code>, takže žijú vo flash a nestoja žiadnu RAM. To, čo kompilátor C++ generuje pre <code>virtual</code>, je presne toto.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="l---liskov-substitution-principle">L - Liskov Substitution Principle<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#l---liskov-substitution-principle" class="hash-link" aria-label="Priamy odkaz na L - Liskov Substitution Principle" title="Priamy odkaz na L - Liskov Substitution Principle" translate="no">​</a></h2>
<blockquote>
<p>Objekty podtypu musia byť použiteľné všade, kde sa očakáva základný typ, bez toho, aby volajúci spozoroval rozdiel.</p>
</blockquote>
<p>Toto je najmenej pochopený princíp. Nejde o syntax (tú za vás skontroluje kompilátor), ide o <strong>kontrakt</strong>. Odvodená trieda nesmie vyžadovať viac, než základná trieda sľubuje, a nesmie dodať menej. Ak volajúci potrebuje <code>if (typeid(...))</code>, princíp je porušený.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-4">V C++<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-4" class="hash-link" aria-label="Priamy odkaz na V C++" title="Priamy odkaz na V C++" translate="no">​</a></h3>
<p>Tri úložné zariadenia za jedným rozhraním. Ktoré z nich porušuje kontrakt?</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IStorage</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IStorage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Eeprom</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IStorage</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// any address, any length</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Flash</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IStorage</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">||</span><span class="token plain"> length </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">            </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token boolean" style="color:rgb(255, 88, 116)">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// stronger precondition than the base class promised</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ProgramDoubleWords</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">RomImage</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IStorage</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">throw</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">logic_error</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token string" style="color:rgb(195, 232, 141)">"ROM is read-only"</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// the caller never expected an exception</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p><code>Flash</code> vyžaduje zarovnané adresy a dĺžky, o čom základná trieda nikdy nehovorila, takže kód, ktorý ukladá päť bajtov, funguje s <code>Eeprom</code> a ticho zlyhá s <code>Flash</code>. <code>RomImage</code> vyhadzuje výnimku v systéme, ktorý sa pravdepodobne zostavuje s <code>-fno-exceptions</code>. Všetky tri sa skompilujú a správa sa iba jedno.</p>
<p>Oprava je dodržať kontrakt v implementácii a nedediť, keď schopnosť chýba:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IReadable</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IReadable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IWritable</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IReadable</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// Contract: any address, any length inside the device. Returns false only on a real failure.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Flash</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IWritable</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// Honours the contract: unaligned parts are merged with the current content (read-modify-write).</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ProgramWithPadding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">RomImage</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IReadable</span><span class="token base-clause">   </span><span class="token base-clause comment" style="color:rgb(105, 112, 152);font-style:italic">// cannot write, so it is not an IWritable</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-5">V C<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-5" class="hash-link" aria-label="Priamy odkaz na V C" title="Priamy odkaz na V C" translate="no">​</a></h3>
<p>C nemá dedičnosť, je teda princíp irelevantný? Naopak, tabuľka ukazovateľov na funkcie je rozhranie presne ako v C++ a problém substitúcie je rovnaký. V C je to ešte nebezpečnejšie, pretože typické porušenia sú <code>NULL</code> v tabuľke alebo <code>assert</code> v implementácii:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">bool</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> bool </span><span class="token function" style="color:rgb(130, 170, 255)">Flash_Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">assert</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;&amp;</span><span class="token plain"> length </span><span class="token operator" style="color:rgb(137, 221, 255)">%</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">8u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* the caller was never told */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Flash_ProgramDoubleWords</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> flashStorage </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Read </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Flash_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Write </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Flash_Write </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> romStorage   </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Read </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Rom_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Write </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(130, 170, 255)">NULL</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* callers crash */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Settings_Save</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> storage</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">SETTINGS_ADDRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* NULL call or failed assert */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Liek je rovnaký ako v C++, plus jeden zvyk: <strong>kontrakt si zapíšte do hlavičky</strong> a prinúťte všetky implementácie, aby ho dodržiavali. Žiadne <code>NULL</code> v tabuľke, žiadny assert pre chybu volajúceho, žiadny skrytý predpoklad:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Storage.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">STORAGE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">STORAGE_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stddef.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    STORAGE_OK</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    STORAGE_ERROR_READ_ONLY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    STORAGE_ERROR_RANGE</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    STORAGE_ERROR_DEVICE</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/*</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> * Contract of every storage implementation:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *  - Read and Write are never NULL.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *  - Write accepts any address and any length inside the device. Alignment is the problem</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *    of the implementation, not of the caller.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> *  - Writing to a read-only device does not crash, it returns STORAGE_ERROR_READ_ONLY.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic"> */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Storage.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Flash_Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Unaligned head and tail are merged with the current content (read-modify-write). */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Flash_ProgramWithPadding</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Rom_Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> STORAGE_ERROR_READ_ONLY</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> flashStorage </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Read </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Flash_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Write </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Flash_Write </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> romStorage   </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Read </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Rom_Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">Write </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> Rom_Write   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">storageStatus_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Settings_Save</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">storageOps_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">storage</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> storage</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">SETTINGS_ADDRESS</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* works with every implementation */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p><code>Settings_Save()</code> funguje s flash, s obrazom ROM (dostane normálny chybový kód) aj s každou implementáciou, ktorá sa objaví neskôr.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="i---interface-segregation-principle">I - Interface Segregation Principle<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#i---interface-segregation-principle" class="hash-link" aria-label="Priamy odkaz na I - Interface Segregation Principle" title="Priamy odkaz na I - Interface Segregation Principle" translate="no">​</a></h2>
<blockquote>
<p>Klienti by nemali byť nútení závisieť od metód, ktoré nepoužívajú.</p>
</blockquote>
<p>„Tučné“ rozhranie viaže každého na všetko. Keď UART dostane novú metódu, musí sa prekompilovať a skontrolovať každý klient a každý mock, hoci chceli iba posielať bajty.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-6">V C++<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-6" class="hash-link" aria-label="Priamy odkaz na V C++" title="Priamy odkaz na V C++" translate="no">​</a></h3>
<p>Logger potrebuje jednu metódu, ale závisí od piatich:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IUart</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IUart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> baudrate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">SetParity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Parity parity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">EnableDma</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> enable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">        </span><span class="token function" style="color:rgb(130, 170, 255)">Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t </span><span class="token function" style="color:rgb(130, 170, 255)">Receive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t maxLength</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Logger</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">explicit</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Logger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">IUart</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> uartToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">uartToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// needs one method, depends on five</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token generic-function function" style="color:rgb(130, 170, 255)">reinterpret_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token generic-function generic class-name keyword" style="color:rgb(255, 203, 107);font-style:italic">const</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)"> </span><span class="token generic-function generic class-name keyword" style="color:rgb(255, 203, 107);font-style:italic">uint8_t</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)"> </span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">*</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">strlen</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    IUart</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Rozhranie sa rozdelí podľa úlohy klienta. Konfigurácia ostáva na konkrétnej triede a logger žiada iba schopnosť zapisovať bajty:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IByteSink</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IByteSink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IByteSource</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IByteSource</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t maxLength</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Uart</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IByteSink</span><span class="token base-clause punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token base-clause"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IByteSource</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint32_t</span><span class="token plain"> baudrate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">          </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// configuration stays on the concrete class</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">SetParity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">Parity parity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">EnableDma</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> enable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t </span><span class="token function" style="color:rgb(130, 170, 255)">Read</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">size_t maxLength</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Logger</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">explicit</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Logger</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">IByteSink</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> sinkToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sinkToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// exactly what it needs</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token generic-function function" style="color:rgb(130, 170, 255)">reinterpret_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token generic-function generic class-name keyword" style="color:rgb(255, 203, 107);font-style:italic">const</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)"> </span><span class="token generic-function generic class-name keyword" style="color:rgb(255, 203, 107);font-style:italic">uint8_t</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)"> </span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">*</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> std</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token function" style="color:rgb(130, 170, 255)">strlen</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    IByteSink</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Mock pre test loggeru má teraz jednu metódu namiesto piatich.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-7">V C<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-7" class="hash-link" aria-label="Priamy odkaz na V C" title="Priamy odkaz na V C" translate="no">​</a></h3>
<p>Tučné rozhranie existuje aj v C, ako obrovská štruktúra ukazovateľov na funkcie alebo, častejšie, ako jeden gigantický hlavičkový súbor <code>Uart.h</code>, ktorý includuje každý:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> baudrate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">SetParity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uartParity_t</span><span class="token plain"> parity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">EnableDma</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool enable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">   </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Receive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> maxLength</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">uartDriver_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Log_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uartDriver_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* needs Send, receives five functions */</span><br></div></code></pre></div></div>
<p>Existujú dva nástroje. Prvý je rovnaký ako v C++: malé rozhranie (<code>byteSink_t</code>), ktoré nesie iba to, čo klient potrebuje:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">ByteSink.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">BYTE_SINK_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">BYTE_SINK_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stddef.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdint.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">  </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">byteSink_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Log.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">LOG_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">LOG_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"ByteSink.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Log_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">byteSink_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Log_Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Log.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Log.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;string.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">byteSink_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">logSink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Log_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">byteSink_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    logSink </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sink</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Log_Print</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">char</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    logSink</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Write</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">logSink</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">strlen</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Druhý je špecifický pre C: <strong>rozdeľte hlavičku</strong>. Každý, kto iba posiela bajty, includuje <code>Uart_Tx.h</code> a nikto iný nevidí konfiguráciu:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Uart_Config.h  - used by the code that sets the peripheral up */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uart_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> baudrate</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Set_Parity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uart_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uartParity_t</span><span class="token plain"> parity</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Uart_Tx.h      - used by everybody who only sends */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Send</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uart_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> length</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Uart_Rx.h      - used by everybody who only receives */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Uart_Receive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token class-name" style="color:rgb(255, 203, 107)">uart_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">uart</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint8_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">data</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token plain"> maxLength</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Logger sa dá otestovať trojriadkovou funkciou, ktorá zachytáva bajty. Nevie, že UART existuje.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="d---dependency-inversion-principle">D - Dependency Inversion Principle<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#d---dependency-inversion-principle" class="hash-link" aria-label="Priamy odkaz na D - Dependency Inversion Principle" title="Priamy odkaz na D - Dependency Inversion Principle" translate="no">​</a></h2>
<blockquote>
<p>Moduly vyššej úrovne by nemali závisieť od modulov nižšej úrovne. Obe by mali závisieť od abstrakcií. Abstrakcie by nemali závisieť od detailov.</p>
</blockquote>
<p>Toto je princíp, ktorý spája ostatné štyri. Stojí za vrstvami z článku o <a class="" href="https://embedbits.cz/sk/blog/design-architecture">dizajne a architektúre</a>: aplikácia nesmie vedieť, ktorý register prepína LED.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-8">V C++<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-8" class="hash-link" aria-label="Priamy odkaz na V C++" title="Priamy odkaz na V C++" translate="no">​</a></h3>
<p>Termostat (politika vysokej úrovne) obsahuje triedy ADC a GPIO (detaily nízkej úrovne). Nedá sa skompilovať bez hardvéru, nedá sa testovať na PC a nedá sa preniesť na inú dosku:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Thermostat</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> adcSensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">ReadCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// knows the ADC</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">20.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> gpioHeater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">On</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// knows the GPIO pin</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">22.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> gpioHeater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Off</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    AdcSensor  adcSensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// concrete low-level classes inside a high-level policy</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    GpioHeater gpioHeater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Po inverzii vlastní politika rozhrania a ovládače ich implementujú. Šípka závislosti ukazuje na politiku:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">before:   Thermostat ───▶ AdcSensor, GpioHeater</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">after:    Thermostat ───▶ ITemperatureSensor, IHeater</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                ▲                ▲</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                                │                │</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                          AdcSensor         GpioHeater   (or a fake in the test)</span><br></div></code></pre></div></div>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">ITemperatureSensor</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">ITemperatureSensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ReadCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">IHeater</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">~</span><span class="token function" style="color:rgb(130, 170, 255)">IHeater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">default</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">virtual</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Thermostat</span><span class="token plain">   </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">// high-level policy: knows only the abstractions</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ITemperatureSensor</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> sensorToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> IHeater</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> heaterToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">sensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">sensorToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">heaterToUse</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> sensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">ReadCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">20.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token boolean" style="color:rgb(255, 88, 116)">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">22.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">Set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token boolean" style="color:rgb(255, 88, 116)">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    ITemperatureSensor</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain"> sensor</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    IHeater</span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">            heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">AdcSensor</span><span class="token plain">  </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">ITemperatureSensor</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">ReadCelsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">GpioHeater</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause keyword" style="font-style:italic">public</span><span class="token base-clause"> </span><span class="token base-clause class-name" style="color:rgb(255, 203, 107)">IHeater</span><span class="token plain">            </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Set</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">bool</span><span class="token plain"> on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">override</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="v-c-9">V C<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#v-c-9" class="hash-link" aria-label="Priamy odkaz na V C" title="Priamy odkaz na V C" translate="no">​</a></h3>
<p>C ponúka dva spôsoby a ten druhý je jedinečný pre C a lacnejší než akékoľvek virtuálne volanie.</p>
<p><strong>1. Injektovanie za behu</strong> pomocou ukazovateľov na funkcie, presne ako v príklade open/closed. Rozhranie patrí termostatu (je v <code>Thermostat.h</code>), ovládače ho vypĺňajú:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Thermostat.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* The thermostat owns the interface, the drivers implement it. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bool on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">   </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">thermostatPorts_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">thermostatPorts_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Thermostat.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Thermostat.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">thermostatPorts_t</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">ports</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">20.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">22.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">ports</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">context</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>V unit teste odovzdáte funkcie, ktoré vrátia číslo a zapamätajú si stav ohrievača. Na cieľovom zariadení odovzdáte <code>Adc_Get_Celsius</code> a <code>Gpio_Set_Heater</code> a <code>Thermostat.c</code> zostane nedotknutý.</p>
<p><strong>2. Injektovanie pri linkovaní.</strong> Niekedy nepotrebujete prepínať implementácie za behu, stačí urobiť rozhodnutie raz, v build systéme. Potom je abstrakciou <strong>hlavička s deklaráciami</strong> a implementáciou zdrojový súbor, ktorý CMake vyberie pre cieľ:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">Bsp_Thermostat.h</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">ifndef</span><span class="token macro property"> </span><span class="token macro property expression">BSP_THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">define</span><span class="token macro property"> </span><span class="token macro property macro-name">BSP_THERMOSTAT_H</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">&lt;stdbool.h&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Implemented by the BSP of the board - or by a fake in the unit test. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool on</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">endif</span><br></div></code></pre></div></div>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockTitle_OeMC">ThermostatLink.c</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"Bsp_Thermostat.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Thermostat_Update</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">float</span><span class="token plain"> celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_Celsius</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">20.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain">      </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">true</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">celsius </span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">22.0f</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_Heater</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">false</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Pre dosku sa zlinkuje <code>Bsp_Thermostat_Stm32.c</code>, ktorý implementuje obe funkcie so skutočnými perifériami. V unit teste na PC sa namiesto toho zlinkuje <code>Bsp_Thermostat_Fake.c</code>. Žiadne ukazovatele na funkcie, žiadna nepriama adresácia, žiadna RAM a termostat je stále úplne nezávislý od hardvéru. Mimochodom, presne toto robí BSP Embedbits: aplikácia volá rozhranie BSP a je jej jedno, aká rodina alebo doska je za ním.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="tie-isté-myšlienky-v-dvoch-jazykoch">Tie isté myšlienky v dvoch jazykoch<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#tie-ist%C3%A9-my%C5%A1lienky-v-dvoch-jazykoch" class="hash-link" aria-label="Priamy odkaz na Tie isté myšlienky v dvoch jazykoch" title="Priamy odkaz na Tie isté myšlienky v dvoch jazykoch" translate="no">​</a></h2>



































<table><thead><tr><th>Princíp</th><th>C++</th><th>C</th></tr></thead><tbody><tr><td><strong>S</strong></td><td>trieda</td><td>modul (dvojica <code>.h</code>/<code>.c</code>, prefix, <code>static</code>)</td></tr><tr><td><strong>O</strong></td><td>abstraktná trieda, <code>virtual</code>, <code>override</code></td><td><code>const</code> tabuľka ukazovateľov na funkcie + <code>void *context</code></td></tr><tr><td><strong>L</strong></td><td>kontrakt základnej triedy</td><td>kontrakt zapísaný v hlavičke, žiadne <code>NULL</code> v tabuľke</td></tr><tr><td><strong>I</strong></td><td>niekoľko malých rozhraní</td><td>malé štruktúry ukazovateľov, rozdelené hlavičky</td></tr><tr><td><strong>D</strong></td><td>konštruktorové injektovanie rozhrania</td><td>ukazovatele na funkcie v <code>struct</code> alebo injektovanie pri linkovaní</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="čo-kompilátor-za-vás-neurobí">Čo kompilátor za vás neurobí<a href="https://embedbits.cz/sk/blog/solid-principles-c-cpp#%C4%8Do-kompil%C3%A1tor-za-v%C3%A1s-neurob%C3%AD" class="hash-link" aria-label="Priamy odkaz na Čo kompilátor za vás neurobí" title="Priamy odkaz na Čo kompilátor za vás neurobí" translate="no">​</a></h2>
<p>Treba byť úprimný. C++ má výhody, ktoré musíte v C nahradiť disciplínou:</p>
<ul>
<li class=""><strong>Žiadna kontrola pri kompilácii.</strong> Ak sa zabudne pole tabuľky funkcií, kompilátor mlčí (designated initializers aspoň pomenúvajú polia a v C sa chýbajúce stane <code>NULL</code>). Používajte inicializátory <code>.Process = ...</code>, nikdy poziciové, a majte unit test, ktorý volá každú funkciu každej implementácie.</li>
<li class=""><strong><code>void *context</code> nie je typovo bezpečný.</strong> Zlé pretypovanie kompilátor nenájde. Držte pretypovanie v jednom riadku na začiatku každej funkcie (<code>movingAverage_t *self = context;</code>) a nikde inde.</li>
<li class=""><strong>Náklady.</strong> Nepriame volanie je pár cyklov a tabuľky stoja flash. Na Cortex-M to zvyčajne nevadí, ale nie v prerušení, ktoré beží každých 10 mikrosekúnd. Tam je variant pri linkovaní zadarmo.</li>
</ul>
<p>A najväčšia pasca: <strong>SOLID je súbor odporúčaní, nie zákon</strong>. Rozdeliť 30-riadkovú funkciu na päť modulov s tabuľkami ukazovateľov na funkcie, lebo „to hovorí princíp“, je vlastný druh špagetového kódu. Uplatnite princíp, keď existuje skutočný dôvod na zmenu, druhá implementácia alebo unit test, ktorý sa bez neho nedá napísať. Nie skôr.</p>
<p>Ak si z tohto článku zapamätáte jednu vetu, nech je to táto: <strong>princípy sú o smere závislostí a veľkosti kúskov, nie o triedach.</strong> C++ vám dáva triedy, C vám dáva moduly a ukazovatele na funkcie. Dobrý dizajn nepotrebuje ani jedno z nich, aby bol efektný.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>Architektúra</category>
            <category>C</category>
            <category>C++</category>
        </item>
        <item>
            <title><![CDATA[Návrh a architektúra]]></title>
            <link>https://embedbits.cz/sk/blog/design-architecture</link>
            <guid>https://embedbits.cz/sk/blog/design-architecture</guid>
            <pubDate>Sun, 29 Sep 2024 20:59:52 GMT</pubDate>
            <description><![CDATA[OCD. Tri skvelé písmená, ktoré ma nútia stále myslieť na architektúru softvéru. Môže to byť naozaj bolestivé, najmä ak sa musím vyrovnať s architektúrou v štýle „Arduino". Určite ju poznáte: celý projekt v pár priečinkoch, aplikácia v priečinku src, nízkoúrovňová funkcionalita v priečinku driver a tak ďalej. Ale čo robiť v komplexných systémoch?]]></description>
            <content:encoded><![CDATA[<p>OCD. Tri skvelé písmená, ktoré ma nútia stále myslieť na architektúru softvéru. Môže to byť naozaj bolestivé, najmä ak sa musím vyrovnať s architektúrou v štýle „Arduino". Určite ju poznáte: celý projekt v pár priečinkoch, aplikácia v priečinku <em>src</em>, nízkoúrovňová funkcionalita v priečinku <em>driver</em> a tak ďalej. Ale čo robiť v komplexných systémoch?</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="modularita">Modularita<a href="https://embedbits.cz/sk/blog/design-architecture#modularita" class="hash-link" aria-label="Priamy odkaz na Modularita" title="Priamy odkaz na Modularita" translate="no">​</a></h2>
<p>Každá skupina funkcionality má byť zapuzdrená v balíku. Spájaním takýchto balíkov dostávame stále zložitejšie systémy. Predstavte si projekt, v ktorom chcete merať teplotu senzorom pripojeným na ADC a aktuálne dáta posielať cez UART. Potrebujeme modul, ktorý číta surové dáta z ADC, vypočíta hodnotu v °C a poskytne ju na svojom rozhraní, a ďalší modul, ktorý obsluhuje komunikáciu cez UART.</p>
<p>Ak by sme všetku túto funkcionalitu skombinovali na jednom mieste, určovali by sme polohu a rýchlosť elementárnej častice súčasne. To by spôsobilo kolaps vlnovej funkcie a zničenie vesmíru (sarkazmus).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="abstrakčné-vrstvy">Abstrakčné vrstvy<a href="https://embedbits.cz/sk/blog/design-architecture#abstrak%C4%8Dn%C3%A9-vrstvy" class="hash-link" aria-label="Priamy odkaz na Abstrakčné vrstvy" title="Priamy odkaz na Abstrakčné vrstvy" translate="no">​</a></h2>
<p>Predstavte si strom. Vrchol stromu je jediný bod, ktorý obsluhuje alebo vykonáva potrebnú funkcionalitu. V embedded systémoch to môže byť nekonečná slučka vo funkcii main alebo nejaký handler RTOS. Čím nižšie strom ide, tým je širší. To predstavuje spojenia a hierarchiu medzi modulmi. Korene stromu predstavujú spojenia s hardvérom.</p>
<p>Základným príkladom je „blinky": LED pripojená na PA1 sa má rozsvietiť, ak je stlačené tlačidlo pripojené na PA0, a naopak.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token macro property directive-hash">#</span><span class="token macro property directive keyword" style="font-style:italic">include</span><span class="token macro property"> </span><span class="token macro property string" style="color:rgb(195, 232, 141)">"stm32g4xx_ll_gpio.h"</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token keyword" style="font-style:italic">while</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">LL_GPIO_IsInputPinSet</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIOA</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> LL_GPIO_PIN_0</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token function" style="color:rgb(130, 170, 255)">LL_GPIO_SetOutputPin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIOA</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> LL_GPIO_PIN_1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">      </span><span class="token function" style="color:rgb(130, 170, 255)">LL_GPIO_ResetOutputPin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIOA</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> LL_GPIO_PIN_1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>V tomto príklade sme zmiešali všetky vrstvy. Pre primitívny projekt to môže byť prijateľné, ale v komplexnom systéme to vedie k anarchii, neporiadku, špagetovému kódu <strong>a koncu sveta</strong>. Aby sme sa vyhli mizernému, dlhému a rozhodujúcemu armagedonu, ľudia vynašli pár úžasných vecí, ako hierarchia a abstrakčné vrstvy. Vo svojich projektoch rozdeľujem funkcionalitu do troch základných vrstiev: Application, Middleware a Board Support Package (aka BSP). Tie sa ďalej členia na viacero vrstiev, aby sa dosiahla prenositeľnosť a modularita.</p>
<p><img decoding="async" loading="lazy" alt="Štruktúra priečinkov projektu: Application, Artifacts, Bsp (Hal, LinkerFiles, Mcal, Ral, Startup), Docs a Middlewares" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAUkAAAIWCAMAAADtZI8lAAAAtFBMVEUAN9oBPc8CQsQDSLkETq4FU6QGWZkHXo0IZIQJankKb20LdWIMDAwMfFcNJQwNgkkOOQwPSAwPijoQVQwRYQwRawwRdAwRlCcSfgwShgwTHTIToQ4UkAwUmQwUoQwVqwwVtAwWvQwWxgwZKk8dNGUhISEhO3cjQoUmSJIpTp8rUqstWLYvXMAxYcszZdU1a+E3b+o5dPU7eP9FRUVUVFRubm6Dg4OMjIyUlJSdnZ3CwsLMzMzWqPBxAAAaxklEQVR42u2dCVfbypaFS7M8CCUmiQAFAk4uIQ5hcKe73+v3//9X13iqbE0eEyztWutyhVQy8KUm1dY5m01RDlPY2/p1Ft93qbPJXbv9rLdP8mZee/r78qHzVqqzWG5x124/65gk39/M55/PxNH5nJfzujrnF+80rvn8TlXekOTTS+3p+8XXmjpEUp35uXzd6i8Rdz0tl8vXx6va6z9eGi9VP4t/zpYk393dXlze3cjDi4vP9SQv9OmbuahysznJ++WP+n64vK+pY0jqMy9PTq3uIu96Wi4Wj8unWpDLF37pebMPe+BVtyR5eXf27v3H+Xvd+LpI8i+f55uTfHy96iRp6xiS6sy35ffXn1v8JfKuJ/ERj8u6668vV+JHPGz8D8OmN18+3s1vBJsPt7ozmgN76eOt6tS3l+/v5oaUJHkj2pz8cvGF9+ZbzlEVQ/Ku9pPFpU/yc37/3//q3+br8qf4lR5fXx9eX79On54fXpdP3/ifo4qtM716XC5/LtwzvA1dPb7ojiYrP4mmJr4sly/fnvl/vOm8LJe6w6q7FEkxKtAlfXC/XMhaj/ZzKnXoNzQk5ze8D37hf+X89uJadEY6WLl0eccP5ufXdx8u559qSH6af7m4uPjIR8mb+Wd+pHv33cf6T+Z3Xc8F3P/+z781yZ/Lr+JXevq+/LXgf8jT8kn2r/vF0/JxsVjYOvLS08vSOSP+1gdx9MBr/hK9kgiI2x9/8lPfeYf9+fq88jm8d78+TO0lc/BddQPe8+lzKnXoNySS71QflAfiy+qBuPTlVrTL+ft38/Mvl9Oz+UUNyWvT553eLWac8/pP5pPX/FpW+69/1G1Xr4/yV1pMl4t7SfKr7nq2d6s6V3JoUyTVGX5qwVvQD12Jt2inLYl/FtH8nkWbfVh+s3epGYd/OF0yB4sqyUod5zfUJOUfz9vbjaZAB/aSKuccnaBYS/LD3fzL5YfKOPlp/rH2k3ljv3u/NsZ/WyNpBkNL0tYRzcqe4e2EN9vXXxLk8+u36SpJdbseJe7tXfJH/OCDIV0yBw9VkpU6zm+4Ocnrc1HO3vM2+Vm0yfO5YPbBkPwivpx9/HwrhgI9/plphV+r+2Re1mb1l6dpA8kfRNLWMSTVGd4yzFiqQSoCzyskf92LcmXvkj9CVKJL5kD9iCszTorPqdRpJFnfB+WlL3d6VTg/5wPf5/nFO9kzr0Udzu6MoFyKLn7OmyGRPLu9afjka/mvQb37Yfm9ieS9mUJ1na/LX6Z36zNT2Ry/82+unjW3p2czDBiSzzTtm7vkj7jiWOkSHdDcTZ9TrdNEsmFeEJfO+Xh3cXE5nd5dvBNz9wXHcMNnlmsxjF5f3NzcfppeXIr5RczUZ3d3/Pi9nHEubnnl+k/m1dwZ5/ll2kSSD3w/F4tvVIdf+qVnHH3mm2LNmxCfWhZyenoUdZ5efqgJ66v86Fc+BPycup/Dq77wn0WX6GBh1pPmc2rq0G+o1pOEq2GtIi+dX/Pe+Jlzuz07k6Pb2eXd/O6S1zm7nt+d887KkfL55VpePBfrofeqC99dtqyCLu0qyLS7OpLT+2fec7/Ztnn1S6+CzJmFnsBf7CqI13m9598taHCc3vPbOGz7ObKyXIaaS/bAPOOYz6mpQ7/hLs848y8fzz8c40n81+vVDnU2uWu3nyVa+OKYz928Uc3nA9kFen35etS9oPfn7wey4/hgHqxOcX/ybZWviy36NytNAbg99ydBEiRBEiRRQBIkQRIkUUASJEESpZ5kXoDkQUiOWQSSByGZeQlIYpwESZBEAcljk+T//f7P/7RXKo9fQBIkQfKtkcwYYyF9M+pG1lBnOCQT5tUSmKWpTyQ9ljXgS2cddYZD0g+bKJUhkRxFRX2V1N7cUGcwJHM2kY+U7SQbS9r4zzA4kiNWxL6gFow9FkycAyIpRky1Os0ixvyU93zGvCgTHFVx60x85sWF/pww7w3Jf/2uKw5JTmvM+FgXMj9JPG9mD4gkHzFDppB6SRqwsTgT+7w1ZvxCnKapU2fCUUdiqgpZmMYs6A3J+mJJFizlLWwk/vBM7MKN7IHbu1NJKWK54KlOFSxZ7d2qTqj+WWbqIGaDaZMT0aa8SPzxggPnSgdVkp75vhiFYSjXSBWSdFZ+TsoGM07GZqDbimTAe3kqmY1AUpMUzZE3zInq1BNJUh8Yuuu9W4yXE9G7Q3k4buzdgyKZKxAs5n94wCcaSUAfiEU7nzTycixmkzTNytwTY0HMB9YwmwSBz8fSwhPN06njzDiDIplKYmXo8z987DNfrILMAcckFj2in8rCW2keefwMn5B4jXEklz1ZwC/lTh1aBQ2sd9tVOFs/wA4GSIIkSIKkLEfaDZ72p4AkSIIkSO6uUJTlLOZr9SgHyemeCsXMY1EaswQkp3sqFKF8bp+hd29IslGhmLHYkNOP2xmLPW/sebNBktxdociY0bjNFlDGwgnv8CwdJMndFYqMhk+zLZnxuizNBkpyd4UikxvC7lb5sEnurlDM5HvsILkpyRaFIjTiA3r3ngpFzqfwNI1GzowDko2lVaGYxT5jwdhZBYHkBs/d2+xhgiRIgiRIDpEkdByQBEmQBMkGkjuoDyBZS3IH9QEk60juoj6AZB3JXdQHqjMkkkdRH6jOkEgeRX2gOmiTluRO6gPVwThpSe6kPoBkDcmd1AeqA5JUdlMfqA5IUtlNfaA6ILnn/iTVAUmQBEmQxP4k9idBEiRBEiShPkB9eGMkoT78BfWhZMzPA/6fTEzA+JkhkTyk+lCKXExxwgJ5JvGCQZE8pPogtntT+YAT+DKheo42aUluoz7YXEw65VqGcdKS3EZ9cEhGmSgFSFqS26gPlmTgFZi7V8t26oPM/jdTiQH5oJCApC1bqQ8qI2VmklVy/CC57/4kVuYgCZIgif1JRJGAJEiCJEgako3qg04NH4LkdE/1IWWpKGOQnO6pPqQMvXsbks3eEERSpj4XX/pj97ADyT28IWpI9sbuYQeSe3hDqHFytkKyL3YPR2iTLd4QtInmkOxLGvMjjJMt3hCrvTsAyXaSLeqDJRloJwiQbC5t6gORjFmUhqE/AsmW0qY+EMkiYl4W8iEAJDd57kZuFpAESZAEyXaSeDsaJEFy4CRX7adB0iXZqD4wlpQ5o7co6+ynQdIl2ag+CKe70TrJVftpkHRINqsPLGGzMFojiXGykWSz+sDSIGVjuROsfKit/XTfXKePrD6wdOT54m1z40Nt7af75jp9ZPWBpTlLzHv7hY4VcwxqY4Y2uZn6IBkKktaH2pIclJvqdE/1gUhaH2qQbCbZoj4Yko4PNUg2ljb1wZC0PtRkPw2SldKmPlDvJh9qsp8GyQPtT2JlDpIgCZLYn4SOA5IgORSSjuiAt1maSDaqD3IdrhMvOaIDSDaRbFQfxINhLDYqV0UHkGwg2ZZ5ST4tJtWQCJCsI9msPujttdCKDkXMWJLiPfNt1QciuSI6hD5D7MOW6oOkN1G9W25Lqj1KH21yW/VBzjhMzTgp0ztsYq7HOFk3TraoD2IV5OlVEEjul3lpLYZRZbXyQbKutKkPRNIRHaLhzjh7qA/OPpsWHYpowKsgvB0NkiAJkiB5IJLY6QVJkARJkGwg2ez7kPqMRRlIbkqyUX0Ys0CoDwVITvdUHyLGIRYztMkNSTarDzHLdduUThpiyzcNmIjSGSTJPdSHjHky5Xbpia3yEec6Emm50zHUhy3VhzIPGUsKMSdxoJEn+ns+1N79z+/fu6sPYpc8ZIHu2MLjZcK7fTIZJMnO0qY+yJKIZsjbo9hW5/PPOPaHmVetm2SL+lAokvK7cUyLzqQPZi6HJ9mmPvhBIrTFUq45fWHglCby/Ra0yZrSpj4kAWmLKZPEY602gmTbc3f7/mTsFcNemR+K5Hg1yhskdyOZxYFYC4Hk3iRTLxwN+7m7PHSZ9rCAJEj2kSSFM2R83RiBZDvJirKQpbP1HEo585I6S4KVyoMnWVEWUvu9CWcwG7p1dgUZSCqSVWUhrWo2YVCCZBdJoywYt2jt08KcHEo6W3lp0ytJL0XfJIaXtfonOqyR3FhZMG7RysQzTW0OpSxNfV96ElB6pUyMmwEb28o9FB3WSG6sLJBbtNthU2bdhPRZmV5JSQyZ07t7KDps2SZJWbAA10na3k3plbxwfZzsoeiw5TgZ24HOABw1kqT0SpYkVe6f6LAlSVIWLMmMjetJ2vRKEa2KnMp9Ex22I0nKgnWLLgtPNL3chjMYkja9Uu6JQSF2KvdQdNiOJCkLjlu0fDTkjY7CGah3U3qlMo88seaxlXsoOmAHAyRBEiRB8pAkQRskQRIkD1VOMMz2cCSdJXqT6LCJMAGSMtlFqh4bW/bVO7fTQbLuLSCQ3I9kIJKwRMxRKIxm0SpM8Md1Fhenm5TpcLEPoTFEnnlhOWKj0ooORrNoEyYmHGziBaeblOlwsQ8h7RNNWCw3NN0N9pReuGoQJgJfvhOYn2xSpkO2Sfu2KfOLsk6qaBEmjAx0sqmEjjLjJJrkaJ1kizDBokyUAiQdkhOWqNeDSHTQJNuEiUC/NX2ySZmOsJ40Mw6JDqRZtAkTfA7iZ5LyZJMyHeEZx6yCSHSwmkWLMCHXRSJ87FSTMmEHAyRBEiRB8lRJntq/CEiC5OBIpuyIlMQLxeHKQR9I1lpLK5Iy43FctFOZxR6ZQ2ykUJTyhWI/XDnoB8kaa2lDUmThDttBevwpMWbJ5vvqKy9tOgenT7LeWjo1mTHi9m4eqlxCJUhaa+ly4qu+bHQETdLTf638ooMgbJMUj9x6K0nfbgypa1QMqlND0qgYpvLp7fSStbTQESLRl42OoF1dxg5JEwThzB0j2pNzbheG1DUqBtWpkiQVw1Q+PfWBrKVDlchqRjqCnnEyh2S0Hk6WUQc2t5MhdY2KQXWqJI2KQZVPsU1qGwIJMHV0BNW7R3wgJJImCMIhaQZYczsZrdaoGFSnStIGs+jKpzhOtpMsg1D9tUFogyCccTJqJjnahqRWMfpA0nQ90hEUk4Iv+ERkY0HLocTt4qFRKpzebQ03VlWMld69lisioNwvp0/SmTIiO+OkPr8UizOhP6IgCFtyT0xC0ci9nex01lQMd8ZJxLyU2wOjYlDlEyZpV0ERrYLElJPIM17Gv6MgiJVnHL58CcbOKohIVlQMZxUkfoifOQdaxaDK2MHADgZIgiRIgmS/AkxAEiSHQTIbtYsFLXVAsslaulYsaKkDkk3W0k1b3E11QLLJWrqRJMbJVpIr1tLk+0CKAJFcrRPmts4ASG72nvmqtbT2fSBFwOa5cu2nhcRAdQZAsjv2oVy1lra+D1YRcHq3qaMlBlOn9yS7fR8q1tLWrcBJb1UlqQ9Nnd6T7CxVa2mHJCkCLSR1HZCsWktb3werCDi11kiaOiBZay2tfR8oroE0AqeOJmnqgGSNtTT5PlBcA2kETh2SvVQdkKx91Qc7GCAJkiA5EJIDy0YFkiAJkiC5Pcnm4AUQ3JZkU/ACCG5Lsil4AQR3Iek5MQtGWQDBVZKbZFWSwQsUs2CUBRBcJblJViUZvEAxC0ZZAMFt26QOXqCYBbMfDoI7jJMyaMHELIDkHiQL8yZKIlPrK2UBBLdfT8rgBYpZMMoCCG7/jCODFyhmwSgLILjvc7fZewRBkARJkARJVbCHCZIgCZLVSAeQ3I6kpJY5AQ0U6QCSe5KktyVBEiT/Mklr7gCStSQ7s9wIz+lYkDTmDiBZT7Iz81LFdRokd2yTpneTuQNI7jlOkrkDSO5H0po7mH0OkNyNpDV3MJEOILlj77bmDjrSASSxgwGSIAmSIHlaOaxAEiRB8u+TXMuqtGGwmLzrDTg4/G2SLq61rEotJHXa95DuegMODm+J5FpWpVaS0ltw7N4VgmSzp0O5jekLSDrq7GpWpZCSkq+bMliSdFfVwcEEXPSF5MYOv9WsSvLbiBVVUwZLku6qOjiYgIu+kNwo81J9ViVxKRd54iumDHqcnK309HUHBxNwMbg2Wc1gEzKRkymvMWUonRzl6ySpsgm4GOKMUyGpFzoVU4aVGWedJFXWARcgKQ8iIUpUTBnqSa47OOiAi+GQ1K7T1axK4qDwOJiKKYMlSXdVHBwo4GI4JCmZ0npWJb0KSqqmDJYk3VVxcKCAC+xgYAcDJEESJEFyQ5LTPheQBMkhkhxGEMTRXacHEwRxdNfpwby6f3TXaZDcniS5TovnZT8tBxYEcQTX6Yx5SRqw8cCCII7gOq3EAi14DycI4giu054RWYcVBHEEX1oiOawgiCOQNFLgwIIgjkAy91jM55pyYEEQx3CdziNP5qgcVhAEdjBAEiRBEiT/PsnpIApIguSASCLz0q4rc8d1GpmX9iLpp2miXaeRL2gvkmGpXGhB8hAkxXM3Mi91kNwoy82Et0lkXuog2ak+qHGyQOalvdukKH5eIvPSIcbJWETgIPPSAUhmLC6Reekgc3fIZsi8dKBVUIzMS9jBAEmQBEmQ/FskhyHxgCRIgiRIdpJMfcbkvmSWzhoDSpougaQlOWaBiGd3MjPUpgfKQLKLpMhiUxazEiT3JRnrF1B1pjTmxD6YPEv2ktxuE1/64159uJ3ejHlyEFQ5LtK0tDKEybNkL1mSvXGvPpz6UOYhY0mx1oWVDGHyLNElh2Rf3Ks3JfnP798dbVI0x1Dk/iJcVoYgtjUk++K5vCnJzmJtlFUuupXYByI5ckkGIFlLslAkRXYaNl6LfSCS+hKfaPSl/rhXH46kHyQie1opkyzxxpiTDGHzLJlLfKKP0jD0Rz1yrz4cySTQhtS85Yl8kTnJEG4WOn2piJjHR1XWI/fqA4+TW5f++NuCJEiC5KBJDj5CBCRBEiRBcpO4hmAMkgcg6aeJLxK9guS+JEOZJD8DyYOQnIlGOfGZJ70YTHql0zBl+GMkN4prKP1QejFE6u1dnV7pNEwZ/hjJzrgG89a4tHIQXyi90mmYMryxNhmEJe3bUlKg0zBleFvjZMGiGpKnYcrwtkjGfFRc690nY8rwltaTqS8MbmjGMemVTsSU4W0948goWVoFmfRKp2HKgOdukARJkATJ/pDE29EgCZInT9JxlCYTMH7Q4hYNku7K3Ho6OI7SLskWt2iQdElaTwfHUdol2eJxDJIOyXpPB5DcnqTxdCBv6II/bycCIB1U3KJHLBeJmHifrwRBnJqj9OYkN/Z0WHGUDn3mHFTcojOWjb2kZHE1COLUHKU3J7mxp4PpyeqlZw6QDqpu0TmbpPyUHhNWgyBOzFF6U5LdcQ02V7kmqY4TZg9q3KJZGk14S85qgiBOzFF6U5KdZUuSxi2apeHMy3ijqwZBnJij9BFJzsQGuujUdFDjFh3GrAwl7UoQxIk5Sh+BpOMoHZkZJzIzzrpbdBgEZcxHxJogiBNzlD4CSfKGFjmV1CooolXQult0ytur7NQ1QRCn5Sh9OJLYwQBJkARJkOwqh90NnvawgCRIDomkif8Cye1IVuMjQHJHkpX4CJDckWQlPgIk9yAp4yOMshAykVUpczKxCKki5g/pwya5VXyEVBZMjgs3p42SKoZNcuP4CFIW5KvUcgdJkySpAm1ys/gIoyyYXEBEkjbYMU52jpMyPsIoC5JkbkgGILkNSREfYdUHVqrIJ5NniaQKkOxYT6r4CKs+MHEmKd08SxFmnC3iI1xlIZwoWULlWTJSBUgeZAcjAsnDkCy8ACT3JjkWkiybgOTeJFPGfPHSGkjuRnI6iAKSIAmSINlFclj7uiAJksMkafIS9Flr2Idk104vkaRcGX3WGvYh2aU+EEmTv6XXWsMfaZPmhfJe75D/kXESJA9F0vTuXmsNxyWZipK5M06EGWcnkjoswq6Ceqw1/IXn7ggkD0Oyr1rDnyXZZ63hz5Lss9bwF8bJwbxwDpIgOTiSKQPJLUm62ZnWSIpFu8qkCpJbZmeqkOTrodpcYSBZR7I5O5Pc3IgZSG5I0mRnWlEfEkvSc4IgeugWccD3zE12por6oHq3N3ZI9tAt4oCxDyY7U0V90DOOG5jTQ7eIQ7ZJnXWksmeuevdIpOg3JHvoFnHIcbKdpAh+ILPpHrpFHIFkRX1QJAs/tGbTPXSLOALJivqghAmfX6IgiB66RRyBZEV9UMKElzhBED10i8AOBkiCJEiC5FskOe1hAUmQBEmQ7H4vaGTz8K6WijABku0kg2aSa8IESLaS9FjeRHJdmADJVpJhGAuSuUymL3d9Y88be96MhAlyghg2yc73zMOxJ9ukzBeUCGjhhEXCn8AIE+QEMWySnbEPYemNBcmR6OF+oHZ9U/VVCRPkBIE22d4myzgSJAsW8849WiFpttO1EwTGyfZxkvOLRXuMPN65Z/UklRMESHaQLH1pMjZmEz8q60gaJwiQ7CI5Ul4EXsDG9SS1EwRIdpEsFMmYeWUtSeMEAZJ47gZJkARJkDwgyemwCkiCJEiCZCfJ1GcsyspU544OQXJHkmMWiNfPikzGOaTpGCR3JBkx8XrarCSPS5DckWSsXx0HyS6SXTu9GfOkvSdIdpHsUh/KPGQsKUBy7zYpCErNGyQPsZ5M5GAJknuRLBTJDCT3JekHSao2y0FyP5JJoMIZQBLP3SAJkiAJkn+Y5MA8vkESJAdA0k0Rn422zcUEkiQ6rJD0at47XyEpA5ajvJZcZnbphkWSRIcVkqOo6CIpQ+Zn9YnEsoH2bvWQ2GIAUUtS3piAZC3JscfCXHzPi47HyQP+n83FtDaoSn9Q/tSeOZXNcFGOxcuY/HrSF5LdO71EMuQdPeB/fJoqUPx/cZzwU5SLqYYk7+W+aISmciYO0pR/pBfKJDl5X0h2qg+W5EymjHZ6sggl4edtLqZVkhPduwv5f13Z9u5EfqDXk979z+/fm7dJF6E74tkMQqszDuMzTjEKw9CkGlodJ2cCMIt7QrKz7ExS72oGXpKmqyRH5oC3x8mbz0H9R0naXEyVZXzGSemkTEQyk1ON7P1jkSlwuCTHYsZJ00zNHbPSycVUITljYTYJAn9kK5eFJ9qpWLX7oR8PmaRxglDrmax0cjFVHy3HPvPH/LKtzD9QJKnMVWb08ZBIbl4yRnYbm5VY+NSDZLXM0lRbwGxWxicgsf0dkts14DhQr3aA5J4l9cJROSCSgy8gCZJvrfw/ScJr6XVl0eYAAAAASUVORK5CYII=" width="329" height="534" class="img_ev3q"></p>
<p><em>Application</em> obsahuje to, čo produkt robí. <em>Middleware</em> obsahuje opakovane použiteľný softvér bez závislosti od hardvéru, ako logger, zásobník ModBus alebo správca nevolatilnej pamäte. A čo je BSP? Jednoduché. Obsahuje všetko potrebné pre komunikáciu, konfiguráciu a obsluhu hardvéru. Z nášho príkladu vyššie patria operácie s GPIO do BSP. Používateľa nemá zaujímať presné zapojenie tlačidla a LED, takže rozhranie medzi BSP a aplikáciou môže vyzerať ako <em><strong>Bsp_Get_ButtonState()</strong></em> a <em><strong>Bsp_Set_LedState()</strong></em>. Ak sa v hardvéri niečo zmení, nikto nemusí upravovať viacero miest a aktualizuje sa iba BSP.</p>
<p>BSP teda obsahuje aspoň jednu vrstvu zapuzdrenia pre tieto gettery a settery. Ale čo budú používať? Budú zapisovať priamo do registrov? Nemyslím si. STMicroelectronics má dve sady „ovládačov": „HAL" a „LL". Prečo úvodzovky? Pretože ani jeden názov nie je správny. Ich balík „HAL" je v skutočnosti obrovský a pomalý špagetový kód, ktorý nemá nič spoločné so svojím popisom, pretože HAL znamená Hardware Abstraction Layer. K tomu pravému sa dostaneme na konci.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="register-abstraction-layer-ral">Register Abstraction Layer (RAL)<a href="https://embedbits.cz/sk/blog/design-architecture#register-abstraction-layer-ral" class="hash-link" aria-label="Priamy odkaz na Register Abstraction Layer (RAL)" title="Priamy odkaz na Register Abstraction Layer (RAL)" translate="no">​</a></h2>
<p>Funkcie <code>LL_GPIO_xxx</code> z príkladu sú zapuzdrený prístup k registrom MCU. Operácie s registrami môžete písať všade, ale čo ak zmeníte MCU alebo urobíte chybu? Musíte to opraviť na každom jednom mieste. To by bolo bolestivé, takže sme práve našli najnižšiu abstrakčnú vrstvu, <em>Register Abstraction Layer</em>. Predstavuje iba abstrakciu registrov, zapuzdrenú vo (zvyčajne inline) funkciách so zmysluplnými názvami.</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">__STATIC_INLINE </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">LL_GPIO_SetOutputPin</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_TypeDef </span><span class="token operator" style="color:rgb(137, 221, 255)">*</span><span class="token plain">GPIOx</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">uint32_t</span><span class="token plain"> PinMask</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">WRITE_REG</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIOx</span><span class="token operator" style="color:rgb(137, 221, 255)">-&gt;</span><span class="token plain">BSRR</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> PinMask</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Názov „LL" je z môjho pohľadu nesprávny (rovnako ako ich HAL, ale kto by ho používal?), ale dostávame prístup ku všetkým registrom so zmysluplným popisom, takže ho môžeme používať bez namáhavého ručného písania.</p>
<p>V mojich projektoch sa RAL skladá z troch častí:</p>
<ul>
<li class=""><strong>CMSIS</strong> od ARM: definície jadra Cortex-M,</li>
<li class=""><strong>CMSIS_ST</strong> od STMicroelectronics: headery zariadení s definíciami registrov a systémovou inicializáciou rodiny MCU,</li>
<li class=""><strong>RAL_ST</strong>: pôvodné ovládače LL od ST spolu s mojou vrstvou <code>Port</code>. Vrstva <code>Port</code> poskytuje jednotné pomenovanie nezávislé od rodiny MCU, takže kód nad RAL sa nemení, keď sa mení MCU.</li>
</ul>
<p>RAL pozná registre a nič iné. Nevie, že na PA1 je niečo pripojené.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="microcontroller-abstraction-layer-mcal">Microcontroller Abstraction Layer (MCAL)<a href="https://embedbits.cz/sk/blog/design-architecture#microcontroller-abstraction-layer-mcal" class="hash-link" aria-label="Priamy odkaz na Microcontroller Abstraction Layer (MCAL)" title="Priamy odkaz na Microcontroller Abstraction Layer (MCAL)" translate="no">​</a></h2>
<p>Máme teda jednoduchý prístup k registrom. Ale čo bude ďalej? Prístup ku GPIO je triviálny, ale čo ostatné periférie? Na prenos cez UART potrebujeme pri každej operácii viacero registrov: aktivovať perifériu, nastaviť baudrate, dĺžku bitov, paritu, stop bity a tak ďalej. A keďže už vieme, že každá funkcionalita, ktorá sa používa viac než raz, má byť zapuzdrená, vytvoríme funkcie na čítanie chýb, spustenie prenosu, zápis do výstupného dátového registra, čítanie zo vstupného dátového registra a mnohé ďalšie.</p>
<p>Táto funkcionalita nemôže byť RAL, pretože je hierarchicky vyššie a volá RAL. Stará sa iba o periférie mikrokontroléra, preto sa táto vrstva volá <em>Microcontroller Abstraction Layer</em> (MCAL). Používateľ vidí <code>Gpio_Set_PinLevel()</code> alebo <code>Usart_Send()</code> a nepotrebuje poznať ani jeden register. Jedna periféria, jedno rozhranie: ak I2C potrebuje DMA, modul I2C si ho obslúži interne.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hardware-abstraction-layer-hal">Hardware Abstraction Layer (HAL)<a href="https://embedbits.cz/sk/blog/design-architecture#hardware-abstraction-layer-hal" class="hash-link" aria-label="Priamy odkaz na Hardware Abstraction Layer (HAL)" title="Priamy odkaz na Hardware Abstraction Layer (HAL)" translate="no">​</a></h2>
<p>Teraz môžeme inicializovať všetky periférie MCU: RCC, DMA, USART/UART a tak ďalej. Ale konfigurácia musí byť kompatibilná so zariadeniami pripojenými na našej DPS. Nezameriavame sa teda iba na MCU, ale na celý obvod. Potrebujeme preto ďalšiu abstrakčnú vrstvu, <em>Hardware Abstraction Layer</em> (HAL). Áno, toto je skutočný význam tohto názvu, nie ako „HAL" od ST.</p>
<p>HAL je jediný bod rozhrania medzi aplikáciou (alebo middlewarom) a hardvérom. Vie, ktorý pin je LED, ktorý UART je pripojený na ladiaci konektor a ako sú periférie nakonfigurované. Na dosiahnutie potrebnej funkcionality prepája viacero modulov z MCAL. Je to posledná abstrakčná vrstva BSP.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="board-support-package">Board Support Package<a href="https://embedbits.cz/sk/blog/design-architecture#board-support-package" class="hash-link" aria-label="Priamy odkaz na Board Support Package" title="Priamy odkaz na Board Support Package" translate="no">​</a></h2>
<p>BSP je hardvérovo orientovaný balík, ktorý obsahuje všetko potrebné na inicializáciu a používanie všetkých periférií MCU a pripojeného obvodu. Okrem troch vrstiev vyššie obsahuje aj <strong>startup</strong> kód (inicializácia pamäťových sekcií a volanie aplikácie) a generovanie <strong>linker</strong> scriptu pre vybraný MCU. Každá rodina STM32 má vlastnú vetvu, takže rozhranie BSP zostáva rovnaké a mení sa iba obsah pod ním.</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Application / Middleware</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">────────────────────────</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">          HAL            what is connected to which pin, how the board is configured</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">          MCAL           peripherals: Gpio, Usart, I2c, Dma, ...</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">          RAL            registers: CMSIS, ST LL drivers, unified Port layer</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">────────────────────────</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">         Hardware</span><br></div></code></pre></div></div>
<p>Pravidlo je jednoduché: <strong>vrstva volá iba vrstvu bezprostredne pod sebou.</strong> Aplikácia nikdy neincluduje header od ST, MCAL nevie, ktorý pin je LED, a RAL nevie, ktorá periféria sa na čo používa.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="blinky-znova">Blinky znova<a href="https://embedbits.cz/sk/blog/design-architecture#blinky-znova" class="hash-link" aria-label="Priamy odkaz na Blinky znova" title="Priamy odkaz na Blinky znova" translate="no">​</a></h2>
<p>Prepíšme príklad. Aplikácia nepozná žiadny hardvér:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">main</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token keyword" style="font-style:italic">while</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token number" style="color:rgb(247, 140, 108)">1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_LedState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_ButtonState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>BSP pozná dosku a používa MCAL. Piny sú popísané v jedinej tabuľke, takže nová revízia DPS zmení jeden riadok a nič iné (zjednodušene, ošetrenie chýb je vynechané):</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">typedef</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">struct</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PortId_t</span><span class="token plain"> portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinId_t</span><span class="token plain">  pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain">   </span><span class="token class-name" style="color:rgb(255, 203, 107)">bspPin_t</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">bspPin_t</span><span class="token plain"> bspButton </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> GPIO_PORT_A</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_0 </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">bspPin_t</span><span class="token plain"> bspLed    </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> GPIO_PORT_A</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> GPIO_PIN_1 </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">bool </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Get_ButtonState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token class-name" style="color:rgb(255, 203, 107)">gpio_PinLevel_t</span><span class="token plain"> pinLevel </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> GPIO_PIN_LEVEL_LOW</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Get_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bspButton</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bspButton</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&amp;</span><span class="token plain">pinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">GPIO_PIN_LEVEL_HIGH </span><span class="token operator" style="color:rgb(137, 221, 255)">==</span><span class="token plain"> pinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Bsp_Set_LedState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bool isActive</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token function" style="color:rgb(130, 170, 255)">Gpio_Set_PinLevel</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">bspLed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">portId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> bspLed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">pinId</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">                          isActive </span><span class="token operator" style="color:rgb(137, 221, 255)">?</span><span class="token plain"> GPIO_PIN_LEVEL_HIGH </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> GPIO_PIN_LEVEL_LOW</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>A kdesi na dne, vo vnútri <code>Gpio_Set_PinLevel()</code>, funkcia RAL <code>LL_GPIO_SetOutputPin()</code> konečne zapíše register <code>BSRR</code>. Štyri vrstvy pre blikajúcu LED vyzerajú ako nezmysel a pre blinky aj sú. Ale podstatné je, čo sa stane, keď produkt rastie:</p>
<ul>
<li class=""><strong>Nová rodina MCU:</strong> stiahne sa iná vetva BSP, aplikácie sa to nedotkne.</li>
<li class=""><strong>Nová revízia DPS:</strong> LED sa presunie na iný pin, zmení sa jeden riadok v HAL.</li>
<li class=""><strong>Unit test aplikácie:</strong> BSP sa nahradí falošným a aplikácia beží na PC, bez akéhokoľvek hardvéru.</li>
<li class=""><strong>Chyba v prístupe k registru:</strong> je presne na jednom mieste.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="kde-to-nájdete">Kde to nájdete<a href="https://embedbits.cz/sk/blog/design-architecture#kde-to-n%C3%A1jdete" class="hash-link" aria-label="Priamy odkaz na Kde to nájdete" title="Priamy odkaz na Kde to nájdete" translate="no">​</a></h2>
<p>Všetky tu popísané vrstvy sú open source a zdokumentované, každá vo vlastnom repozitári organizácie <a href="https://github.com/Embedbits" target="_blank" rel="noopener noreferrer" class="">Embedbits</a>:</p>
<ul>
<li class=""><a class="" href="https://embedbits.cz/sk/docs/bsp">BSP</a>: balík so startupom, linker scriptom a HAL,</li>
<li class=""><a class="" href="https://embedbits.cz/sk/docs/bsp/ral">RAL</a>: CMSIS, CMSIS_ST a RAL_ST,</li>
<li class=""><a class="" href="https://embedbits.cz/sk/docs/bsp/mcal">MCAL</a>: moduly periférií spolu s tabuľkou podporovaných rodín STM32,</li>
<li class=""><a class="" href="https://embedbits.cz/sk/docs/platform/embi-platform/coding-style">coding style</a>, vďaka ktorému sú názvy v týchto vrstvách čitateľné.</li>
</ul>
<p>Ak chcete vidieť rovnakú myšlienku z pohľadu jazyka, prečítajte si článok o <a class="" href="https://embedbits.cz/sk/blog/solid-principles-c-cpp">princípoch SOLID v C++ a C</a>. Vrstvy vyššie nie sú nič iné než <em>dependency inversion</em> aplikovaná na celý firmvér.</p>]]></content:encoded>
            <category>Embedded</category>
            <category>Architektúra</category>
        </item>
        <item>
            <title><![CDATA[Konečné automaty]]></title>
            <link>https://embedbits.cz/sk/blog/finite-state-machines</link>
            <guid>https://embedbits.cz/sk/blog/finite-state-machines</guid>
            <pubDate>Sun, 29 Sep 2024 16:24:40 GMT</pubDate>
            <description><![CDATA[Pre vývoj embedded softvéru je správny návrh nevyhnutný. Mikrokontrolér musí zvládať spracovanie samotnej aplikácie a komunikáciu s množstvom pripojených obvodov cez interné alebo externé periférie. Vykonávanie aplikácie má byť čo najrýchlejšie. To je však pre každého hrozne neurčité vysvetlenie. V reálnom svete musí vývojár zabezpečiť optimálne krátku logickú cestu vykonávania kódu. Čo znamená, že vývojár nemá v každom hlavnom cykle kontrolovať všetky podmienky. Jedným zo spôsobov takejto optimalizácie je správne vnáranie podmienok. S rastúcou zložitosťou projektu to môže byť naozaj ťažké. Veľa vnorených podmienených príkazov môže viesť k nestabilite kódu a znižuje jeho čitateľnosť. Čitateľnosť kódu je ukrutne potrebná pre budúce úpravy alebo údržbu existujúceho kódu. Jeden z mojich obľúbených citátov hovorí:]]></description>
            <content:encoded><![CDATA[<p>Pre vývoj embedded softvéru je správny návrh nevyhnutný. Mikrokontrolér musí zvládať spracovanie samotnej aplikácie a komunikáciu s množstvom pripojených obvodov cez interné alebo externé periférie. Vykonávanie aplikácie má byť čo najrýchlejšie. To je však pre každého hrozne neurčité vysvetlenie. V reálnom svete musí vývojár zabezpečiť optimálne krátku logickú cestu vykonávania kódu. Čo znamená, že vývojár nemá v každom hlavnom cykle kontrolovať všetky podmienky. Jedným zo spôsobov takejto optimalizácie je správne vnáranie podmienok. S rastúcou zložitosťou projektu to môže byť naozaj ťažké. Veľa vnorených podmienených príkazov môže viesť k nestabilite kódu a znižuje jeho čitateľnosť. Čitateľnosť kódu je ukrutne potrebná pre budúce úpravy alebo údržbu existujúceho kódu. Jeden z mojich obľúbených citátov hovorí:</p>
<!-- -->
<p><img decoding="async" loading="lazy" alt="Ukážka tabuľky rutín automatu v jazyku C" src="https://embedbits.cz/sk/assets/images/fsm-state-machine-cc3162be67be4421b1cac2bb42f51afd.png" width="551" height="586" class="img_ev3q"></p>
<blockquote>
<p><strong>Vždy programuj tak, akoby ten, kto bude tvoj kód udržiavať, bol násilný psychopat, ktorý vie, kde bývaš.</strong></p>
</blockquote>
<p>Takže by sme mali radšej premýšľať, než napíšeme samotný kód. Tento proces sa volá „návrh“ (design) a veľmi ho mám rád. Pretože ak ho urobíte správne, množstvo nového kódu a následných úprav tohto nového kódu sa výrazne zníži. Niekedy sa môže zdať, že to zaberie veľa času, ale v skutočnosti je tento čas spolu s časom písania kódu kratší než písanie kódu, ktorý sa bude neustále prepisovať. Ale ako si to uľahčiť? Tu môžeme začať hovoriť o konečných automatoch (Finite State Machines), známych aj ako FSM.</p>
<p>Začnime teda bezvýznamným popisom vygenerovaným AI:</p>
<blockquote>
<p>Stavové automaty, najmä automaty Mealy a Moore, sú základnými modelmi pri návrhu digitálnych systémov a v teórii vypočítateľnosti. Oba tieto automaty sa používajú na reprezentáciu systémov, ktoré prechádzajú medzi stavmi na základe vstupov a v dôsledku toho produkujú výstupy. Odlišuje ich však spôsob, akým generujú výstupy.</p>
<p><strong>Mealyho automat</strong> produkuje výstupy na základe <strong>aktuálneho stavu</strong> aj <strong>aktuálneho vstupu</strong>. Vďaka tomu sú Mealyho automaty citlivejšie, pretože výstup sa môže dynamicky meniť s každým vstupným signálom.</p>
<p>Naopak, <strong>Mooreov automat</strong> generuje výstupy výlučne na základe svojho <strong>aktuálneho stavu</strong>, nezávisle od vstupu. Vďaka tomu sú Mooreove automaty jednoduchšie a predvídateľnejšie, pretože výstup zostáva konštantný, kým sa nezmení stav.</p>
<p>Tieto automaty sa široko používajú v embedded systémoch, riadiacich systémoch a digitálnych obvodoch, kde sú presné prechody stavov a výstupy kritické. V tomto blogu preskúmame, ako Mealyho a Mooreove automaty fungujú, aké sú ich kľúčové rozdiely a ako sa dajú uplatniť v praktickom návrhu systémov.</p>
</blockquote>
<p>Ale čo to znamená? Jednoducho povedané, Mealyho konečný automat kontroluje podmienky pre požadovaný stav <em><strong>pred</strong></em> vykonaním aktuálneho stavu. Mooreov automat kontroluje podmienky <em><strong>po</strong></em> vykonaní aktuálneho stavu.</p>
<p>Ale čo stav predstavuje? Predstavte si žiarovku, ktorú možno zapínať a vypínať tlačidlom. Na obsluhu tohto správania by náš automat potreboval iba dva stavy. Jeden stav, ktorý aktivuje akčný člen, a druhý stav, ktorý tento akčný člen deaktivuje. Naozaj jednoduché, nie? Ale čo v zložitých systémoch? No potrebujete jednoduchú implementáciu, ktorú možno použiť v rôznych situáciách. Presne to robí šablóna nižšie.</p>
<p>Počas mojej práce v automobilovom priemysle sme sa s kolegom <a href="https://www.linkedin.com/in/jano-sima/" target="_blank" rel="noopener noreferrer" class="">Janom Šimom</a> stretli s problémami pri návrhu konečných automatov. Existovalo množstvo rôznych štýlov, ale žiadny z nich nemal dostatočnú funkcionalitu na dosiahnutie stability a čistého návrhu. Rozhodli sme sa teda navrhnúť vlastnú šablónu. S Janovým súhlasom publikujem šablónu nášho konečného automatu pod licenciou MIT.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="stiahnite-si-šablónu">Stiahnite si šablónu<a href="https://embedbits.cz/sk/blog/finite-state-machines#stiahnite-si-%C5%A1abl%C3%B3nu" class="hash-link" aria-label="Priamy odkaz na Stiahnite si šablónu" title="Priamy odkaz na Stiahnite si šablónu" translate="no">​</a></h2>
<p>Šablóna je publikovaná pod licenciou MIT. Všetko je čistý text, takže si ju môžete prečítať ešte pred stiahnutím:</p>

























<table><thead><tr><th>Súbor</th><th>Čo to je</th></tr></thead><tbody><tr><td><a href="https://embedbits.cz/sk/downloads/fsm/FsmTemplate.c" target="_blank" rel="noopener noreferrer" class="">FsmTemplate.c</a></td><td>Šablóna v jazyku <strong>C</strong> (C99), jeden súbor so stavmi, tabuľkou rutín a stubmi</td></tr><tr><td><a href="https://embedbits.cz/sk/downloads/fsm/FsmTemplate.hpp" target="_blank" rel="noopener noreferrer" class="">FsmTemplate.hpp</a> a <a href="https://embedbits.cz/sk/downloads/fsm/FsmTemplate.cpp" target="_blank" rel="noopener noreferrer" class="">FsmTemplate.cpp</a></td><td>Šablóna v jazyku <strong>C++</strong> (C++17), trieda s jedným automatom vnútri</td></tr><tr><td><a href="https://embedbits.cz/sk/downloads/fsm/Fsm.hpp" target="_blank" rel="noopener noreferrer" class="">Fsm.hpp</a></td><td>Header-only engine pre verziu v C++ (bez haldy, bez výnimiek, bez RTTI)</td></tr><tr><td><a href="https://embedbits.cz/sk/downloads/fsm/fsm-instantiate.sh" target="_blank" rel="noopener noreferrer" class="">fsm-instantiate.sh</a></td><td>Malý skript, ktorý nahradí názvy, <code>fsm-instantiate.sh Button FsmTemplate.c src/</code> vytvorí <code>src/Button.c</code></td></tr></tbody></table>
<p>Názvy v lomených zátvorkách sa nahradia názvom vášho modulu: <code>&lt;Module&gt;</code> sa stane <code>Button</code>, <code>&lt;module&gt;</code> sa stane <code>button</code> a <code>&lt;MODULE&gt;</code> sa stane <code>BUTTON</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ako-to-funguje">Ako to funguje<a href="https://embedbits.cz/sk/blog/finite-state-machines#ako-to-funguje" class="hash-link" aria-label="Priamy odkaz na Ako to funguje" title="Priamy odkaz na Ako to funguje" translate="no">​</a></h2>
<p>Je to Mooreov automat. Každý stav má štyri rutiny a automat ich pri každom behu volá v tom istom poradí:</p>
<ol>
<li class=""><strong>Entry</strong>: volá sa raz, pri vstupe do stavu.</li>
<li class=""><strong>Execute</strong>: volá sa pri každom behu, tu je práca stavu.</li>
<li class=""><strong>CheckLeave</strong>: volá sa pri každom behu po Execute. Je to <strong>jediné</strong> miesto, kde sa žiada nový stav.</li>
<li class=""><strong>Leave</strong>: volá sa raz, pri opustení stavu.</li>
</ol>
<p>Celý engine je jedna funkcia. Toto je verzia v C:</p>
<div class="language-c codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-c codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_HandleStateTransition</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token keyword" style="font-style:italic">void</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* A corrupted actual state must not index outside of the table: start again from the default state. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">MODULE</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_STATE_COUNT </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">MODULE</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_STATE_1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_NewState    </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">MODULE</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_STATE_1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_CallRoutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_StateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Actual state is in the valid range */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Execute function shall be used for main execution of actual state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_CallRoutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_StateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">execute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* CheckLeave function shall be used for check leave condition of actual state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_CallRoutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_StateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">checkLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* In case of an invalid request (made in checkLeave), switch to the default/error state. */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">MODULE</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_STATE_COUNT </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_NewState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_NewState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">MODULE</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_STATE_1</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Requested state is in the valid range */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* Leave and entry functions shall be executed only in case if the state has to be changed to another state */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState </span><span class="token operator" style="color:rgb(137, 221, 255)">!=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_NewState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_CallRoutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_StateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">leave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_NewState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token function" style="color:rgb(130, 170, 255)">_CallRoutine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_StateRoutines</span><span class="token punctuation" style="color:rgb(199, 146, 234)">[</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">module</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token plain">_SM_ActualState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">]</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token plain">entry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">else</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">        </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* No new state required */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><br></div></code></pre></div></div>
<p>Keďže sa prechod žiada iba v <code>CheckLeave</code>, entry a leave stavu sa vždy vykonávajú ako dvojica, v známom poradí, a výstupy závisia iba od stavu. Rutina, ktorá nie je potrebná, môže byť <code>NULL</code> (<code>nullptr</code> v C++) a preskočí sa.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-was-fixed">Čo sa opravilo<a href="https://embedbits.cz/sk/blog/finite-state-machines#what-was-fixed" class="hash-link" aria-label="Priamy odkaz na Čo sa opravilo" title="Priamy odkaz na Čo sa opravilo" translate="no">​</a></h2>
<p>Prvá verzia šablóny, ktorú som tu publikoval, mala niekoľko chýb. Prešiel som ju znova, zostavil ju a spustil proti testu, ktorý zaznamenáva poradie volaní. Toto sú zmeny:</p>
<ul>
<li class="">Počiatočná hodnota stavových premenných bola pozostatkom názvu z iného projektu (<code>APPCORE_HANDLER_STATE_1</code> namiesto <code>&lt;MODULE&gt;_STATE_1</code>).</li>
<li class="">Posledný riadok tabuľky používal <code>State_2_Leave</code> namiesto <code>State_3_Leave</code>. Kód sa skompiloval a pri opustení tretieho stavu volal zlú rutinu. Tabuľka je teraz indexovaná stavom (<code>[&lt;MODULE&gt;_STATE_3] = { ... }</code>), takže pozíciu riadku nemožno zameniť.</li>
<li class=""><code>Init</code> nespúšťal entry rutinu prvého stavu.</li>
<li class="">Čísla stavov sa nekontrolovali. Poškodený aktuálny stav alebo požiadavka na neexistujúci stav indexovali mimo tabuľky. Obe sa teraz kontrolujú a automat sa vráti do prvého stavu, ktorý je bezpečný. Požiadavka sa kontroluje <strong>po</strong> <code>CheckLeave</code>, pretože tam vzniká. Moja prvá oprava to kontrolovala pred, a test to zachytil, čo je pekný dôkaz, prečo sa takýto test oplatí.</li>
<li class="">Rutina s ukazovateľom <code>NULL</code> sa preskočí namiesto pádu.</li>
<li class="">Chýbajúca forward deklarácia a komentár v hlavičke, ktorý po nahradení názvov nedával zmysel.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="verzia-v-c">Verzia v C++<a href="https://embedbits.cz/sk/blog/finite-state-machines#verzia-v-c" class="hash-link" aria-label="Priamy odkaz na Verzia v C++" title="Priamy odkaz na Verzia v C++" translate="no">​</a></h2>
<p>V C++ je ten istý vzor trieda. Stav je <code>enum class</code>, rutiny sú súkromné členské funkcie a tabuľka je <code>constexpr</code>:</p>
<div class="language-cpp codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-cpp codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">Button</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">public</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">enum</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">class</span><span class="token plain"> </span><span class="token class-name" style="color:rgb(255, 203, 107)">State</span><span class="token plain"> </span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"> </span><span class="token base-clause">std</span><span class="token base-clause double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token base-clause keyword" style="font-style:italic">uint8_t</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> Idle </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> </span><span class="token number" style="color:rgb(247, 140, 108)">0u</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Pressed</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> Count </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Init</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">noexcept</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">Task</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">noexcept</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    State </span><span class="token function" style="color:rgb(130, 170, 255)">GetState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">noexcept</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">{</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">return</span><span class="token plain"> stateMachine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">.</span><span class="token function" style="color:rgb(130, 170, 255)">GetState</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token keyword" style="font-style:italic">private</span><span class="token operator" style="color:rgb(137, 221, 255)">:</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">using</span><span class="token plain"> Machine </span><span class="token operator" style="color:rgb(137, 221, 255)">=</span><span class="token plain"> fsm</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">StateMachine</span><span class="token operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token plain">Button</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> State</span><span class="token punctuation" style="color:rgb(199, 146, 234)">,</span><span class="token plain"> </span><span class="token generic-function function" style="color:rgb(130, 170, 255)">static_cast</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&lt;</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)">std</span><span class="token generic-function generic class-name double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token generic-function generic class-name" style="color:rgb(255, 203, 107)">size_t</span><span class="token generic-function generic class-name operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token plain">State</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">Count</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token operator" style="color:rgb(137, 221, 255)">&gt;</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">IdleEntry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">IdleExecute</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">IdleCheckLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain">   </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">IdleLeave</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">void</span><span class="token plain"> </span><span class="token function" style="color:rgb(130, 170, 255)">PressedEntry</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(105, 112, 152);font-style:italic">/* ... */</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">constexpr</span><span class="token plain"> Machine</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">Table </span><span class="token function" style="color:rgb(130, 170, 255)">MakeTable</span><span class="token punctuation" style="color:rgb(199, 146, 234)">(</span><span class="token punctuation" style="color:rgb(199, 146, 234)">)</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">noexcept</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    </span><span class="token keyword" style="font-style:italic">static</span><span class="token plain"> </span><span class="token keyword" style="font-style:italic">const</span><span class="token plain"> Machine</span><span class="token double-colon punctuation" style="color:rgb(199, 146, 234)">::</span><span class="token plain">Table table</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">    Machine stateMachine</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain"></span><span class="token punctuation" style="color:rgb(199, 146, 234)">}</span><span class="token punctuation" style="color:rgb(199, 146, 234)">;</span><br></div></code></pre></div></div>
<p>Požiadavka je <code>stateMachine.RequestState(State::Pressed)</code> v rutine <code>CheckLeave</code>. Riadok tabuľky musí patriť svojmu stavu a to sa kontroluje v <strong>čase kompilácie</strong> pomocou <code>static_assert</code>, takže chyba z prvej verzie sa už nedá ani zostaviť. Nie je tu halda, výnimky ani RTTI, takže to zodpovedá obvyklým obmedzeniam embedded a štýlu MISRA. Verzia v C++ bola skompilovaná s <code>-Wall -Wextra -Wconversion -pedantic -fno-exceptions -fno-rtti</code> a bežala pod sanitizérmi adries a nedefinovaného správania s rovnakými scenármi ako verzia v C: poradie volaní, požiadavka, neplatná požiadavka, poškodený stav a preskočené rutiny <code>NULL</code>.</p>
<p>Druhá časť tejto série, <a class="" href="https://embedbits.cz/sk/blog/fsm-in-practice-button">tlačidlo s debounce a dlhým stlačením</a>, ukazuje šablónu v skutočnom module.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="licencia">Licencia<a href="https://embedbits.cz/sk/blog/finite-state-machines#licencia" class="hash-link" aria-label="Priamy odkaz na Licencia" title="Priamy odkaz na Licencia" translate="no">​</a></h2>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#bfc7d5;--prism-background-color:#292d3e"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#bfc7d5;background-color:#292d3e"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#bfc7d5"><span class="token plain">Copyright (c) 2024 Marek Petrinec, Jan Sima</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">Permission is hereby granted, free of charge, to any person obtaining a copy</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">of this software and associated documentation files (the "Software"), to deal</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">in the Software without restriction, including without limitation the rights</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">copies of the Software, and to permit persons to whom the Software is</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">furnished to do so, subject to the following conditions:</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">The above copyright notice and this permission notice shall be included in all</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">copies or substantial portions of the Software.</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span><br></div><div class="token-line" style="color:#bfc7d5"><span class="token plain">SOFTWARE.</span><br></div></code></pre></div></div>]]></content:encoded>
            <category>Embedded</category>
        </item>
    </channel>
</rss>