<?xml version="1.0" encoding="UTF-8"?>        <rss version="2.0"
             xmlns:atom="http://www.w3.org/2005/Atom"
             xmlns:dc="http://purl.org/dc/elements/1.1/"
             xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
             xmlns:admin="http://webns.net/mvcb/"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
             xmlns:content="http://purl.org/rss/1.0/modules/content/">
        <channel>
            <title>
									EDGEMTech Forum - Recent Posts				            </title>
            <link>https://dev.edgemtech.ch/community/</link>
            <description>EDGEMTech Discussion Board</description>
            <language>en-US</language>
            <lastBuildDate>Sat, 18 Apr 2026 14:57:56 +0000</lastBuildDate>
            <generator>wpForo</generator>
            <ttl>60</ttl>
							                    <item>
                        <title>Rendering QR Codes in LVGL: From Pixels to Philosophy</title>
                        <link>https://dev.edgemtech.ch/community/embedded-user-interface/rendering-qr-codes-in-lvgl-from-pixels-to-philosophy/#post-38</link>
                        <pubDate>Sat, 10 Jan 2026 10:07:37 +0000</pubDate>
                        <description><![CDATA[QR codes have become a ubiquitous way to encode and share information, URLs, contact details, configuration parameters, and more. With LVGL, embedding a QR code into your embedded UI is stra...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-n5y3u1052">QR codes have become a ubiquitous way to encode and share information, URLs, contact details, configuration parameters, and more. With LVGL, embedding a QR code into your embedded UI is straightforward. In this post, we’ll explore how to use QR codes in LVGL, discuss the limits of QR code sizing on embedded displays, and take a step back to reflect on the design philosophy behind these clever square patterns.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-u8hr41193" class="wp-block-heading">Using QR Codes in LVGL</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-btrzq1202">Starting from LVGL v8, the library includes a built-in widget for generating and displaying QR codes.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-6g1az1815">Here's a simple example:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">int main(lv_obj_t * qr = lv_qrcode_create(lv_scr_act(), 100, lv_color_black(), lv_color_white());
lv_qrcode_update(qr, "https://www.edgemtech.com");) {
  return 0;
}

lv_obj_t * qr = lv_qrcode_create(lv_scr_act(), 100, lv_color_black(), lv_color_white());
lv_qrcode_update(qr, "https://www.edgemtech.com");
}</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>int</span><span> </span><span>main</span><span>(</span><span>lv_obj_t</span><span> </span><span>*</span><span> </span><span>qr</span><span> </span><span>=</span><span> </span><span>lv_qrcode_create</span><span>(</span><span>lv_scr_act</span><span>()</span><span>,</span><span> </span><span>100</span><span>,</span><span> </span><span>lv_color_black</span><span>()</span><span>,</span><span> </span><span>lv_color_white</span><span>());</span></span>
<span class="line"><span>lv_qrcode_update</span><span>(</span><span>qr</span><span>,</span><span> </span><span>"</span><span>https://www.edgemtech.com</span><span>"</span><span>);) </span><span>{</span></span>
<span class="line"><span>  </span><span>return</span><span> </span><span>0</span><span>;</span></span>
<span class="line"><span>}</span></span>
<span class="line"></span>
<span class="line"><span>lv_obj_t</span><span> </span><span>*</span><span> </span><span>qr</span><span> </span><span>=</span><span> </span><span>lv_qrcode_create</span><span>(</span><span>lv_scr_act</span><span>()</span><span>,</span><span> </span><span>100</span><span>,</span><span> </span><span>lv_color_black</span><span>()</span><span>,</span><span> </span><span>lv_color_white</span><span>())</span><span>;</span></span>
<span class="line"><span>lv_qrcode_update</span><span>(</span><span>qr</span><span>,</span><span> </span><span>"</span><span>https://www.edgemtech.com</span><span>"</span><span>)</span><span>;</span></span>
<span class="line"><span>}</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-kvzjt1863">This snippet creates a 100x100 pixel QR code in black on a white background. The <strong>lv_qrcode_update</strong> function encodes the string into the QR pattern.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-fpcoa2070" class="wp-block-heading">Display Limitations and Scaling</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-xxmt52100">The size of your QR code is constrained by:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>The screen resolution</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>The desired readability (especially when using a camera)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>The error correction level and data complexity</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-8n2wv2112">LVGL supports scaling the QR pattern with pixel-perfect precision. However, embedded displays often have limited resolution. For example, on a 128x128 screen, you might only fit a version 2 QR code (~25x25 modules) cleanly, assuming each module is 4-5 pixels.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-9op822114">&#x26a0;&#xfe0f; <strong>Rule of thumb:</strong> Always scale each module (square) to at least 3x3 pixels for reliable scanning.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-5l7y72552" class="wp-block-heading">A Word on QR Code Structure</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-b5nih2609">QR codes are built using a defined standard (ISO/IEC 18004), consisting of:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Finder patterns</strong>: the large corner squares</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Alignment patterns</strong>: help correct distortion</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Timing patterns</strong>: guide scanning across rows/columns</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Error correction</strong>: allows reading even if damaged</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-ym5ej2628">The LVGL QR widget internally uses a compact QR generation algorithm, based on <strong>qrcodegen</strong>, optimized for embedded use. You won’t need to implement these patterns yourself, but understanding them helps debug issues (e.g., too much data, unreadable codes).</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-dn4u84903" class="wp-block-heading">Philosophy: More Than a Matrix</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-mddb84968">What makes QR codes elegant is their <strong>balance between redundancy and compression</strong>. They:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Handle data loss gracefully with Reed-Solomon error correction</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Encode multiple formats (text, binary, etc.)</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Remain visually consistent while encoding vastly different content</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-srst04982">In an embedded system, this philosophy matches our priorities: reliability, compactness, and clarity. With LVGL, you can embed this visual language into your UI effortlessly.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-9d66j9531" class="wp-block-heading">LVGL QR Code Integration Limitations</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-wqvwy9354">While the QR code widget in LVGL provides a convenient interface for rendering QR codes, it’s important to be aware of its design constraints and lack of configurability, especially if you need finer control for production-level applications.</p>
<p><!-- /wp:paragraph -->

<!-- wp:image --></p>
<figure class="wp-block-image"><img src="https://static.wixstatic.com/media/19c787_e39c29fe27a04c4cae006baf341b6446~mv2.png/v1/fill/w_704,h_268,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/19c787_e39c29fe27a04c4cae006baf341b6446~mv2.png" alt="" /></figure>
<p><!-- /wp:image -->

<!-- wp:heading --></p>
<h2 id="viewer-xgrz414059" class="wp-block-heading">&#x1f51a;Conclusion</h2>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-1st6j16193">LVGL’s QR code integration is simple, efficient, and well-suited for many embedded use cases, especially where memory and performance matter.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-c14q817836">It gets the job done when you need to display a basic QR code, and it integrates cleanly into the LVGL object model using lv_canvas. However, it stops short of offering full control. Features like error correction level, mask pattern selection, quiet zone size, and detailed error feedback are fixed or not exposed. For most developers, this may not be an issue, but for those needing fine-tuned QR generation (e.g., for branding, versioning, or resilience), the current implementation feels limiting.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-pf46d8135">That said… who knows? Maybe a patch is on the way to bring these missing features to LVGL. Stay tuned &#x1f609;</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>gabriel.catel torres</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/embedded-user-interface/rendering-qr-codes-in-lvgl-from-pixels-to-philosophy/#post-38</guid>
                    </item>
				                    <item>
                        <title>Realtime embedded systems</title>
                        <link>https://dev.edgemtech.ch/community/realtime-systems/realtime-embedded-systems/#post-37</link>
                        <pubDate>Sat, 10 Jan 2026 09:51:37 +0000</pubDate>
                        <description><![CDATA[Hard realtime systems is the third axis of competences we have at EDGEMTech.



It concerns all aspects (development, tuning and optimization, porting, debugging, etc.) related to hard r...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p>Hard realtime systems is the third axis of competences we have at EDGEMTech.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-43mj61697">It concerns all aspects (development, tuning and optimization, porting, debugging, etc.) related to hard realtime systems (mainly x86 and ARM Linux-based systems).</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-pf46d8135">Do not hesitate to contact our expert <a href="mailto:daniel.rossier@edgemtech.ch" target="_blank" rel="noreferrer noopener"><u>Daniel Rossier</u></a> for any advice.</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/realtime-systems/realtime-embedded-systems/#post-37</guid>
                    </item>
				                    <item>
                        <title>x86 is far from being sidelined</title>
                        <link>https://dev.edgemtech.ch/community/realtime-systems/x86-is-far-from-being-sidelined/#post-36</link>
                        <pubDate>Sat, 10 Jan 2026 09:51:00 +0000</pubDate>
                        <description><![CDATA[Have you ever thought that x86 would gradually leave the world of embedded systems?




The Sapphire Edge+ VPR-4616-MB is a Mini-ITX motherboard that includes the AMD Versal AI Edge VE2...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p>Have you ever thought that x86 would gradually leave the world of embedded systems?</p>
<p><!-- /wp:paragraph -->

<!-- wp:quote --></p>
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p>The Sapphire Edge+ VPR-4616-MB is a Mini-ITX motherboard that includes the AMD Versal AI Edge VE2302 device plus an AMD Ryzen Embedded R2314 processor, along with a flexible I/O interface to connect to various peripherals and sensors.</p>
<!-- /wp:paragraph --></blockquote>
<p><!-- /wp:quote -->

<!-- wp:image --></p>
<figure class="wp-block-image"><a class="m5Unu has-custom-focus zEYzC" href="https://www.amd.com/en/products/embedded/embedded-plus.html?utm_source=press+release&amp;utm_medium=referral&amp;utm_campaign=embedded-plus#product-brief"><img src="https://static.wixstatic.com/media/d1e2ca_f7be01a53ffc484698c180e77ecc266f~mv2.png/v1/fill/w_270,h_198,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/d1e2ca_f7be01a53ffc484698c180e77ecc266f~mv2.png" alt="" /></a></figure>
<p><!-- /wp:image -->

<!-- wp:paragraph --></p>
<p id="viewer-pf46d8135">Our Engineers are on hand to give you the necessary expertises in hard realtime systems based on Linux for your new development, if you envisage to start a new product or to port an existing realtime sy</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/realtime-systems/x86-is-far-from-being-sidelined/#post-36</guid>
                    </item>
				                    <item>
                        <title>EVL/Xenomai 4</title>
                        <link>https://dev.edgemtech.ch/community/realtime-systems/evl-xenomai-4/#post-35</link>
                        <pubDate>Sat, 10 Jan 2026 09:50:10 +0000</pubDate>
                        <description><![CDATA[If your embedded system requires real-time constraints, don&#039;t worry! The Linux operating system remains a top choice. With significant advancements in the upstream RT-PREEMPT extension over ...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-foo">If your embedded system requires real-time constraints, don't worry! The Linux operating system remains a top choice. With significant advancements in the upstream RT-PREEMPT extension over the past three years, you can now run applications on isolated CPU cores with minimal latency and jitter.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-n4tyt5681">However, some specific use cases—particularly those requiring hard real-time performance in user-space applications—can be tricky. Combining RT and non-RT tasks in the same environment may lead to interference, and implementing non-GPL closed-source code within the kernel only adds to the complexity.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-iatvv5683">For these challenges, the<u> </u><a href="https://evlproject.org/" target="_blank" rel="noreferrer noopener"><strong><u>EVL (Xenomai 4)</u></strong></a> extension is a powerful alternative to RT-PREEMPT. Here’s why</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-vy35i6091">:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Out-of-Band (OOB) Functions</strong>: Guarantee hard real-time conditions across execution paths, ensuring deterministic behavior for critical tasks.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Clean RT/Non-RT Separation</strong>: Isolates the real-time domain from standard Linux tasks, minimizing interference.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Scalable Architecture</strong>: Works seamlessly on popular ARM-based SoCs, such as Raspberry Pi, NXP, TI platforms, making it versatile for various embedded projects.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Hard Real-Time User-Space Applications</strong>: Ideal for scenarios where real-time functionality must remain closed-source without relying on kernel modifications.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-u9o0g5704">Whether you're tackling hard real-time constraints, maintaining user-space applications, or working with ARM-based systems, EVL offers an innovative and reliable solution.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-omuum6633">It's definitely worth considering for your next project!</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/realtime-systems/evl-xenomai-4/#post-35</guid>
                    </item>
				                    <item>
                        <title>Hard realtime with Linux RT-Preemt</title>
                        <link>https://dev.edgemtech.ch/community/realtime-systems/hard-realtime-with-linux-rt-preemt/#post-34</link>
                        <pubDate>Sat, 10 Jan 2026 09:49:39 +0000</pubDate>
                        <description><![CDATA[se of Linux RT-Preempt Kernel 6.12 marks another significant step in enhancing real-time performance for critical applications. This version introduces improved low-latency scheduling, deter...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-foo">se of <strong>Linux RT-Preempt Kernel 6.12</strong> marks another significant step in enhancing real-time performance for critical applications. This version introduces improved <strong>low-latency scheduling</strong>, <strong>deterministic behavior</strong>, and <strong>better IRQ handling</strong>, providing a more stable foundation for <strong>industrial automation, robotics, and other real-time workloads</strong>.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-gt2hn2858">With <strong>enhanced IRQ threading</strong>, latency spikes are significantly reduced, even under high-load scenarios. The improved <strong>preemptibility</strong> ensures consistent response times for real-time applications, making the system more predictable. <strong>CPU isolation techniques</strong> have also been refined, minimizing jitter and improving determinism.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-agkd03559">Additionally, <strong>real-time scheduling policies</strong> have been optimized, increasing efficiency for time-sensitive operations.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-2uduy1055">However, some areas in the kernel still pose potential risks for latency spikes during real-time operations. For instance, the <em>seccomp()</em> syscall triggers a call to the tlb_flush_all() function, which invalides all TLBs on all CPUs.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-3o5pf57565">On an <strong>x86 machine with an SMP configuration</strong>, this function relies on a special APIC mechanism to <strong>broadcast IPIs to all CPUs in a single instruction</strong>. The problem? There’s no check against an <strong>isolated CPU</strong>, which should not be disturbed especially if an RT application is performing constant <strong>read/write operations</strong>. The IPI results in a <strong>CPU interrupt</strong>, introducing a <strong>latency spike</strong>.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-gwyla1069">Here's a excerpt of function call path:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">tlb_flush_all(void) -&gt; ... -&gt; x2apic_send_IPI_allbutself() -&gt; .. -&gt; __wrmsr()</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>tlb_flush_all</span><span>(</span><span>void</span><span>) </span><span>-&gt;</span><span> </span><span>...</span><span> </span><span>-&gt;</span><span> </span><span>x2apic_send_IPI_allbutself</span><span>() </span><span>-&gt;</span><span> </span><span>..</span><span> </span><span>-&gt;</span><span> </span><span>__wrmsr</span><span>()</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p>At the end, there is only one instruction doing the work:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">static __always_inline void __wrmsr(unsigned int msr, u32 low, u32 high)
{
	asm volatile("1: wrmsr\n"
		     "2:\n"
		     _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_WRMSR)
		     : : "c" (msr), "a"(low), "d" (high) : "memory");
}</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>static</span><span> </span><span>__always_inline</span><span> </span><span>void</span><span> </span><span>__wrmsr</span><span>(</span><span>unsigned</span><span> </span><span>int</span><span> </span><span>msr</span><span>,</span><span> </span><span>u32</span><span> </span><span>low</span><span>,</span><span> </span><span>u32</span><span> </span><span>high</span><span>)</span></span>
<span class="line"><span>{</span></span>
<span class="line"><span>	</span><span>asm</span><span> </span><span>volatile</span><span>(</span><span>"</span><span>1: wrmsr</span><span>\n</span><span>"</span></span>
<span class="line"><span>		     </span><span>"</span><span>2:</span><span>\n</span><span>"</span></span>
<span class="line"><span>		     </span><span>_ASM_EXTABLE_TYPE</span><span>(1</span><span>b</span><span>,</span><span> 2</span><span>b</span><span>,</span><span> </span><span>EX_TYPE_WRMSR</span><span>)</span></span>
<span class="line"><span>		     : : </span><span>"</span><span>c</span><span>"</span><span> (</span><span>msr</span><span>)</span><span>,</span><span> </span><span>"</span><span>a</span><span>"</span><span>(</span><span>low</span><span>)</span><span>,</span><span> </span><span>"</span><span>d</span><span>"</span><span> (</span><span>high</span><span>) : </span><span>"</span><span>memory</span><span>"</span><span>)</span><span>;</span></span>
<span class="line"><span>}</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-roy481077">Fortunately, there's a workaround: pass the <strong><em>no_ipi_broadcast=1</em></strong> argument to the kernel command line. A simple fix, but not an obvious one! This problem became apparent when we noticed unexpected high latency spikes when performing basic operations such as ssh'ing to the remote machine running an RT application.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-3yzt218251">.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-orl9z1085" class="wp-block-heading">Looking Ahead</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-g9zg91087">Beyond these considerations, <strong>Linux RT-Preempt 6.12</strong> continues to push the boundaries of real-time performance, making it an <strong>excellent choice</strong> for embedded systems and time-critical applications. As adoption grows, its impact will likely extend further into <strong>robotics, telecommunications, and automotive systems</strong>.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-if8h91095">Looking forward to sharing insights and experiences on its implementation in various real-time environments!</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/realtime-systems/hard-realtime-with-linux-rt-preemt/#post-34</guid>
                    </item>
				                    <item>
                        <title>OpenCN: Hard Real-Time Motion Control for Embedded and Industrial Automation</title>
                        <link>https://dev.edgemtech.ch/community/realtime-systems/opencn-hard-real-time-motion-control-for-embedded-and-industrial-automation/#post-33</link>
                        <pubDate>Sat, 10 Jan 2026 09:48:40 +0000</pubDate>
                        <description><![CDATA[ndustrial automation, robotics, and CNC systems, achieving hard real-time determinism is crucial for safety, precision, and performance. Many systems rely on costly proprietary solutions to ...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-qnd1e3280">ndustrial automation, robotics, and CNC systems, achieving <strong>hard real-time determinism</strong> is crucial for safety, precision, and performance. Many systems rely on costly proprietary solutions to meet those demands—but <strong>OpenCN</strong> offers an open, modular alternative specifically built for <strong>embedded motion control</strong> with <strong>microsecond-level timing precision</strong>. Released under the <strong>GPLv2 license</strong>, OpenCN promotes transparency, adaptability, and long-term sustainability—making it an excellent foundation for building reliable, real-time automation systems without vendor lock-in.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-lpbdl3290">OpenCN is ideal for developers and integrators looking for <strong>affordable</strong>, <strong>real-time</strong>, and <strong>production-grade</strong> control systems that don't compromise on timing guarantees or long-term maintainability.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-dputz21492">OpenCN originates from the well-known <a href="https://linuxcnc.org/" target="_blank" rel="noreferrer noopener"><strong><u>LinuxCNC project</u></strong></a>, whose architecture has powered machine tools and motion platforms for decades. However, traditional LinuxCNC relies on either soft real-time or hybrid userspace/hard real-time setups, often with considerable complexity or overhead.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-wmujg3298" class="wp-block-heading">&#x1f9e0; Real-Time Core: Xenomai/Cobalt, Streamlined and Evolved</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-mgr3l3300">At the foundation of OpenCN lies a <strong>customized hard real-time core</strong> based on <strong>Xenomai/Cobalt</strong>. Unlike traditional implementations, OpenCN’s version <strong>removes the I-Pipe layer</strong>—a legacy abstraction once required to enable real-time co-kernels within Linux. This results in a <strong>lighter</strong>, <strong>cleaner</strong>, and <strong>more maintainable</strong> integration with the Linux kernel.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-5incp3314">This architecture not only reduces latency and jitter but aligns with the forward-looking design principles of <strong>Xenomai 4 / EVL</strong>—while retaining the mature and proven scheduling and interrupt management features of Cobalt.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-g645z3318">Benefits include:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Hard real-time determinism</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Reduced system overhead</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Compatibility with recent Linux kernels</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Customizability for embedded deployments</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-tzvjc4241">The overall picture below shows the general OpenCN environment.</p>
<p><!-- /wp:paragraph -->

<!-- wp:image --></p>
<figure class="wp-block-image"><img src="https://static.wixstatic.com/media/d1e2ca_831502d75efb4ad5bb53d618e310216d~mv2.png/v1/fill/w_873,h_704,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d1e2ca_831502d75efb4ad5bb53d618e310216d~mv2.png" alt="OpenCN General Architecture" /></figure>
<p><!-- /wp:image -->

<!-- wp:paragraph --></p>
<p>OpenCN General Architecture</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-jz6oc10796" class="wp-block-heading">&#x2699;&#xfe0f; Multicore Isolation for Determinism</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-vipr410798">OpenCN fully leverages <strong>asymmetric multicore processing</strong>, a key strategy for ensuring hard real-time behavior in modern multi-core systems. This allows:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Time-critical control loops to run on dedicated CPU cores</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Background tasks such as networking, data logging, or user interfaces to be confined to separate cores</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>A predictable and interference-free real-time environment</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-iyxgu10812">This isolation model is essential for systems where control loops must execute with <strong>fixed cycle times</strong>, regardless of system load.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-knan110816" class="wp-block-heading">&#x1f4bb; Runs on x86 and Raspberry Pi 4/5</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-vb9ps10818">OpenCN runs natively on both:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>x86 industrial PCs</strong> for performance-intensive applications</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>ARM-based platforms</strong>, including <strong>Raspberry Pi 4 and 5</strong>, for compact and low-cost deployments</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-ts44i10831">This range of support makes it well-suited for:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Prototyping motion systems</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Retrofitting legacy equipment</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Deploying cost-sensitive automation solutions</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Educational and academic use cases</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-gpwyx10846">Despite its efficiency, OpenCN delivers the <strong>hard real-time behavior expected in high-end industrial controllers</strong>.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-7uk3d10850" class="wp-block-heading">&#x1f50c; EtherCAT for Real-Time Industrial Communication</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-vo7h110852">OpenCN includes <strong>native support for EtherCAT drivers</strong>, allowing deterministic, synchronized communication with:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Servo and stepper motor drives</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>I/O expansion modules</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Distributed sensors and actuators</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li> </li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-1y60410866">EtherCAT is the <strong>primary fieldbus supported</strong>, ensuring seamless integration into modern industrial automation ecosystems. This makes OpenCN particularly well-suited for motion control platforms, where high-speed field communication is critical.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-thfbj10870" class="wp-block-heading">&#x1f4e1; User Interface and System Monitoring</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-oaram10872">OpenCN includes a <strong>remote user interface</strong>, which can run on a separate PC or tablet. This interface allows users to:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Configure the system</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Monitor machine operations in real time</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Visualize and log control signals</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Optimize control parameters based on process feedback</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-ys5b810889">Such capabilities are essential for maintaining high precision and quality in automated machining and robotic workflows.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-uc1t710891" class="wp-block-heading">&#x1f6e0; EDGEMTech: Your Partner for Real-Time Embedded Control</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-xr1h410893">At <strong>EDGEMTech</strong>, we have <strong>deep experience with OpenCN</strong>—many of our engineers were directly involved in its development and deployment. We offer:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Long-term support and maintenance</strong></li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Custom adaptations</strong> to specific hardware platforms or motor drive integrations</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Kernel and driver-level customization</strong> to meet hard real-time requirements</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Consulting on deploying OpenCN in production systems or as part of Industry 4.0 strategies</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-i8do210914">Whether you’re building a CNC machine, an advanced robot, or a precision automation line, <strong>EDGEMTech can provide the expertise and support</strong> to make OpenCN a stable, tailored, and sustainable solution.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h3 id="viewer-63nil10918" class="wp-block-heading">&#x1f527; Summary</h3>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-9sysa10920"><strong>OpenCN proves that hard real-time control, open-source freedom, and embedded efficiency can go hand in hand.</strong>With native EtherCAT support, deterministic execution, and lightweight architecture, it offers a powerful foundation for next-generation control systems.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-5dc8q10923">&#x1f517; <a href="https://mecatronyx.gitlab.io/opencnc/opencn/" target="_blank" rel="noreferrer noopener"><u>Learn more about OpenCN</u></a></p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-8a0bp10926"><strong>We invite you to share your experiences, ask technical questions, or explore OpenCN's capabilities with us here in the Realtime Systems section.</strong></p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-dk4ag18274">Let’s build deterministic systems—together.</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/realtime-systems/opencn-hard-real-time-motion-control-for-embedded-and-industrial-automation/#post-33</guid>
                    </item>
				                    <item>
                        <title>Exploring Embedded Virtualization for Versatile Embedded Systems</title>
                        <link>https://dev.edgemtech.ch/community/orchestration-and-services/exploring-embedded-virtualization-for-versatile-embedded-systems/#post-32</link>
                        <pubDate>Sat, 10 Jan 2026 09:47:02 +0000</pubDate>
                        <description><![CDATA[mbedded virtualization is an innovative approach that significantly enhances the versatility of multi-core microcontroller units (MCUs) by enabling multiple execution environments on a singl...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-foo">mbedded virtualization is an innovative approach that significantly enhances the versatility of multi-core microcontroller units (MCUs) by enabling multiple execution environments on a single platform. This technique allows different operating systems and applications to coexist, offering a range of powerful use cases. Here’s a closer look at its potential and benefits.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h4 id="viewer-mqohn1984" class="wp-block-heading">Key Use Cases for Embedded Virtualization</h4>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ol class="wp-block-list"><!-- wp:list-item -->
<li><strong>Critical Systems:</strong> Running a real-time operating system (RTOS) alongside a general-purpose OS, like Linux, to manage time-sensitive tasks without sacrificing usability.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Secure Environments:</strong> Isolating secure applications with a dedicated OS while allowing non-secure apps to run separately.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Hardware Resource Partitioning:</strong> Efficiently dividing CPU cores, memory, and peripherals among different virtual environments.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Heterogeneous Environments:</strong> Managing different operating systems (e.g., Linux, Windows) on the same MCU.</li>
<!-- /wp:list-item --></ol>
<p><!-- /wp:list -->

<!-- wp:heading --></p>
<h4 id="viewer-bwqez2003" class="wp-block-heading">Enhanced Device Management</h4>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-3xp9w2005">Managing a large fleet of embedded devices becomes more streamlined with virtualization. During software upgrades, virtualization minimizes disruption, allowing seamless updates while maintaining service availability.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h4 id="viewer-t40by2007" class="wp-block-heading">Improved Security and Resource Management</h4>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-mhfmq2009">Virtualization significantly bolsters application security by isolating memory and dedicating CPU cores to specific tasks. A hypervisor, acting as a bare-metal software layer, manages the guest operating systems, coordinates interactions, and optimizes hardware utilization.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h4 id="viewer-cyfup2011" class="wp-block-heading">Hypervisors vs. Containers</h4>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-22k5k2013">It’s essential to distinguish between hypervisors and containerized environments:</p>
<p><!-- /wp:paragraph -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Hypervisors:</strong> Operate directly on the hardware, offering robust isolation and control. Suitable for lightweight guest OS environments, especially when resources are constrained.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Containers:</strong> Managed by a daemon (e.g., Docker), tightly integrated with a host OS (like Linux). While ideal for scalability and performance, containers may consume significant RAM and CPU, making them less suitable for low-resource systems.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-91iku2024">One promising combination is leveraging <a href="https://www.toradex.com/operating-systems/torizon-os" target="_blank" rel="noreferrer noopener"><strong><u>TorizonOS</u></strong></a> with Docker for scalable application management, while using a hypervisor with lightweight guest OS (such as <a href="https://github.com/smartobjectoriented/so3" target="_blank" rel="noreferrer noopener"><strong><u>SO3</u></strong></a>, developed by HEIG-VD) for data processing and analysis. This dual approach can optimize performance and security, particularly in constrained hardware environments.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h4 id="viewer-dxeyo2030" class="wp-block-heading">EDGEMTech’s Vision</h4>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-lnp9k2032">At EDGEMTech, we are actively exploring the synergy between containerized environments (via TorizonOS) and hypervisor-based lightweight OS approaches (like SO3). Our goal is to create robust, secure, and efficient solutions that maximize the potential of embedded systems, even within limited hardware constraints.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-ruej32034">Join the discussion and share your thoughts on embedded virtualization. What challenges have you faced, and how have you addressed them in your projects?</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/orchestration-and-services/exploring-embedded-virtualization-for-versatile-embedded-systems/#post-32</guid>
                    </item>
				                    <item>
                        <title>Debugging LVGL with QEMU/aarch64</title>
                        <link>https://dev.edgemtech.ch/community/embedded-user-interface/debugging-lvgl-with-qemu-aarch64/#post-31</link>
                        <pubDate>Sat, 10 Jan 2026 09:46:03 +0000</pubDate>
                        <description><![CDATA[In Debugging embedded applications — especially graphical ones — without hardware can be challenging.



Fortunately, emulated environments like QEMU offer an ideal solution for running ...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p>In Debugging embedded applications — especially graphical ones — without hardware can be challenging.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-dc1hd82408">Fortunately, emulated environments like <strong>QEMU</strong> offer an ideal solution for running and debugging cross-compiled <strong>ARM64</strong> applications. Using QEMU with IDEs such as <strong>Eclipse</strong> or <strong>VSCode</strong> provides a powerful and flexible setup for developers.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-45im382653">Personally, after many years of experience with <strong>Eclipse + GDB</strong>, I still consider it among the best free solutions for graphical debugging. That said, <strong>VSCode</strong> has made significant strides recently, offering a smooth and efficient debugging experience.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h4 id="viewer-j1z9282146" class="wp-block-heading"><strong>Why QEMU for LVGL Development?</strong></h4>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-jg74882148">In this new series of articles, we will explore the fascinating world of QEMU emulation, with a focus on <strong>debugging LVGL applications</strong> — a library we actively deploy across various hardware platforms.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-pf46d8135">In this first post, we will cover the basics of how to set up a GDB debugging environment with <strong>QEMU (AArch64)</strong>.</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/embedded-user-interface/debugging-lvgl-with-qemu-aarch64/#post-31</guid>
                    </item>
				                    <item>
                        <title>Debugging LVGL on Infrabase (QEMU, no hardware needed) — a step-by-step guide</title>
                        <link>https://dev.edgemtech.ch/community/embedded-user-interface/debugging-lvgl-on-infrabase-qemu-no-hardware-needed-a-step-by-step-guide/#post-30</link>
                        <pubDate>Sat, 10 Jan 2026 09:45:02 +0000</pubDate>
                        <description><![CDATA[through source-level debugging of an LVGL application, all inside a QEMU/virt64 environment. No hardware needed — just a modern Linux host and developer tools



Today we’ll dive into th...]]></description>
                        <content:encoded><![CDATA[<p><!-- wp:paragraph --></p>
<p id="viewer-kva4193448">through source-level debugging of an LVGL application, all inside a QEMU/virt64 environment. No hardware needed — just a modern Linux host and developer tools</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-d97y41113">Today we’ll <strong>dive into the execution of an LVGL application</strong> and explore the <strong>LVGL library internals</strong> — all inside a <strong>QEMU/virt64</strong> emulated environment. Yep: <strong>no hardware required</strong>. &#x1f642;</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h2 id="viewer-tppc94626" class="wp-block-heading">What you’ll do</h2>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Build the default Infrabase environment and QEMU.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Enable <strong>debug symbols</strong> for your LVGL app and the LVGL library.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Launch the emulated GUI and attach <strong>VS Code + gdb-multiarch</strong>.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Inspect the <strong>call stack</strong> and step through the LVGL main loop.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:heading --></p>
<h2 id="viewer-rbwd15088" class="wp-block-heading">1) Build the base system</h2>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-jtyou5090">From a fresh clone, bootstrap and build the default configuration:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">$ source env.sh
$ build.sh -a</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>$</span><span> </span><span>source</span><span> </span><span>env</span><span>.</span><span>sh</span></span>
<span class="line"><span>$</span><span> </span><span>build</span><span>.</span><span>sh</span><span> </span><span>-</span><span>a</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-u3ze45094">The first build takes ~<strong>45 minutes</strong> (it compiles a Buildroot-based root filesystem).</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-97mb55098">Since we’re using an emulated target, build QEMU as well:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">$ build.sh -q</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>$</span><span> </span><span>build</span><span>.</span><span>sh</span><span> </span><span>-</span><span>q</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p>Start the graphical environment:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">$ ./stg.sh</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>$</span><span> </span><span>.</span><span>/</span><span>stg</span><span>.</span><span>sh</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-uqeuh5106">You should see the LVGL demo windows pop up in a desktop-like session.</p>
<p><!-- /wp:paragraph -->

<!-- wp:quote --></p>
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p><strong>Tip:</strong> <a href="http://stg.sh" target="_blank" rel="noreferrer noopener">stg.sh</a> launches QEMU with a GDB server so your debugger can attach on <a href="http://localhost:1234" target="_blank" rel="noreferrer noopener">localhost:1234</a>.</p>
<!-- /wp:paragraph --></blockquote>
<p><!-- /wp:quote -->

<!-- wp:image --></p>
<figure class="wp-block-image"><img src="https://static.wixstatic.com/media/d1e2ca_4b4b1b4631744145a72a5d1278fcc243~mv2.png/v1/fill/w_880,h_473,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d1e2ca_4b4b1b4631744145a72a5d1278fcc243~mv2.png" alt="The lvglsim application running in the QEMU/virt64 environment" /></figure>
<p><!-- /wp:image -->

<!-- wp:paragraph --></p>
<p>The lvglsim application running in the QEMU/virt64 environment</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h2 id="viewer-vxvbt11952" class="wp-block-heading">2) Turn on debug symbols for the app and LVGL</h2>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-syhng11954">We want source-level debugging with function names and line info.</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-ngoie12403">Edit <strong>linux/usr/src/lvgl/lv_port_linux/CMakeLists.txt</strong> and set a debug build. If there’s a line that sets CMAKE_BUILD_TYPE to Debug, <strong>uncomment</strong> it (or add this if needed):</p>
<p><!-- /wp:paragraph -->

<!-- wp:preformatted --></p>
<pre id="viewer-954sw11962" class="wp-block-preformatted" contenteditable="false">set(CMAKE_BUILD_TYPE Debug)</pre>
<p><!-- /wp:preformatted -->

<!-- wp:image --></p>
<figure class="wp-block-image"><img src="https://static.wixstatic.com/media/d1e2ca_ca3c3b51b0b54f82bcdb5897c4c1c873~mv2.png/v1/fill/w_880,h_516,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d1e2ca_ca3c3b51b0b54f82bcdb5897c4c1c873~mv2.png" alt="Uncomment the line to enable Debug (line 13)" /></figure>
<p><!-- /wp:image -->

<!-- wp:paragraph --></p>
<p>Uncomment the line to enable Debug (line 13)</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-s4j5820894">Then <strong>clean the user build</strong> and rebuild with debug info:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">$ cd linux/usr
$ rm -rf build/
$ ./build.sh
# or from repo root:
$ build.sh -u</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>$</span><span> </span><span>cd</span><span> </span><span>linux</span><span>/</span><span>usr</span></span>
<span class="line"><span>$</span><span> </span><span>rm</span><span> </span><span>-</span><span>rf</span><span> </span><span>build</span><span>/</span></span>
<span class="line"><span>$</span><span> </span><span>.</span><span>/</span><span>build</span><span>.</span><span>sh</span></span>
<span class="line"><span># </span><span>or</span><span> </span><span>from</span><span> </span><span>repo</span><span> root</span><span>:</span></span>
<span class="line"><span>$</span><span> </span><span>build</span><span>.</span><span>sh</span><span> </span><span>-</span><span>u</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-bwyd920900">This ensures your binaries are compiled with -g.</p>
<p><!-- /wp:paragraph -->

<!-- wp:quote --></p>
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p><strong>Heads-up:</strong> Make sure any stripping step is disabled for your debug build (don’t strip symbols).</p>
<!-- /wp:paragraph --></blockquote>
<p><!-- /wp:quote -->

<!-- wp:heading --></p>
<h2 id="viewer-jff1f21359" class="wp-block-heading">3) VS Code debug configuration</h2>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-zsvlk21361">Install the <strong>C/C++ extension</strong> (Microsoft) and ensure <strong>gdb-multiarch</strong> is available on your host (e.g., sudo apt install gdb-multiarch on Debian/Ubuntu).</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-iubyq21367">Create or update <strong>.vscode/launch.json</strong> with:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "(gdb) USR lvglsim",
      "type": "cppdbg",
      "request": "launch",
      "program": "${workspaceFolder}/linux/usr/build/bin/lvglsim",
      "args": [],
      "stopAtEntry": false,
      "cwd": "${fileDirname}",
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb-multiarch",
      "miDebuggerServerAddress": "localhost:1234",
      "setupCommands": 
    }
  ]
}</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>{</span></span>
<span class="line"><span>  </span><span>"</span><span>version</span><span>"</span><span>: </span><span>"</span><span>0.2.0</span><span>"</span><span>,</span></span>
<span class="line"><span>  </span><span>"</span><span>configurations</span><span>"</span><span>: [</span></span>
<span class="line"><span>    </span><span>{</span></span>
<span class="line"><span>      </span><span>"</span><span>name</span><span>"</span><span>:</span><span> </span><span>"</span><span>(gdb) USR lvglsim</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>type</span><span>"</span><span>:</span><span> </span><span>"</span><span>cppdbg</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>request</span><span>"</span><span>:</span><span> </span><span>"</span><span>launch</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>program</span><span>"</span><span>:</span><span> </span><span>"</span><span>${workspaceFolder}/linux/usr/build/bin/lvglsim</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>args</span><span>"</span><span>:</span><span> []</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>stopAtEntry</span><span>"</span><span>:</span><span> </span><span>false</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>cwd</span><span>"</span><span>:</span><span> </span><span>"</span><span>${fileDirname}</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>environment</span><span>"</span><span>:</span><span> []</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>externalConsole</span><span>"</span><span>:</span><span> </span><span>false</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>MIMode</span><span>"</span><span>:</span><span> </span><span>"</span><span>gdb</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>miDebuggerPath</span><span>"</span><span>:</span><span> </span><span>"</span><span>/usr/bin/gdb-multiarch</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>miDebuggerServerAddress</span><span>"</span><span>:</span><span> </span><span>"</span><span>localhost:1234</span><span>"</span><span>,</span></span>
<span class="line"><span>      </span><span>"</span><span>setupCommands</span><span>"</span><span>:</span><span> </span></span>
<span class="line"><span>    </span><span>}</span></span>
<span class="line"><span>  ]</span></span>
<span class="line"><span>}</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:quote --></p>
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p><strong>Why this works:</strong> When <a href="http://stg.sh" target="_blank" rel="noreferrer noopener">stg.sh</a> starts QEMU, it exposes a GDB server on <a href="http://localhost:1234" target="_blank" rel="noreferrer noopener">localhost:1234</a>. VS Code’s cppdbg connects to it using gdb-multiarch, while program points to your <strong>local</strong> ELF with symbols so the debugger can resolve sources.</p>
<!-- /wp:paragraph --></blockquote>
<p><!-- /wp:quote -->

<!-- wp:heading --></p>
<h2 id="viewer-xze1c22578" class="wp-block-heading">4) Attach, pause, and inspect the stack</h2>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>Launch the <strong>“(gdb) USR lvglsim”</strong> configuration in VS Code.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>It will auto-connect to QEMU (<a href="http://localhost:1234" target="_blank" rel="noreferrer noopener">localhost:1234</a>).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Hit <strong>Pause</strong> to freeze the target and open the <strong>Call Stack</strong>.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:paragraph --></p>
<p id="viewer-ad07j22598">You should land somewhere inside the LVGL driver/timer machinery.</p>
<p><!-- /wp:paragraph -->

<!-- wp:image --></p>
<figure class="wp-block-image"><img src="https://static.wixstatic.com/media/d1e2ca_814d82c5429642ecbe1c9c9d0ab22ffc~mv2.png/v1/fill/w_880,h_514,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/d1e2ca_814d82c5429642ecbe1c9c9d0ab22ffc~mv2.png" alt="Inspect the source code and stack trace of a running LVGL application" /></figure>
<p><!-- /wp:image -->

<!-- wp:paragraph --></p>
<p>Inspect the source code and stack trace of a running LVGL application</p>
<p><!-- /wp:paragraph -->

<!-- wp:paragraph --></p>
<p id="viewer-l90y887986"> Typical path:</p>
<p><!-- /wp:paragraph -->

<!-- wp:kevinbatdorf/code-block-pro --></p>
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono"><span></span>
<pre class="code-block-pro-copy-button-pre" contenteditable="false" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" readonly="readonly" aria-hidden="true">main()
  → run_loop_fbdev()
     → lv_timer_handler()
        → lv_timer_exec()  // internal timer execution
           → … draw/invalidations …</textarea></pre>
<pre class="shiki nord" contenteditable="false"><code><span class="line"><span>main</span><span>()</span></span>
<span class="line"><span>  → </span><span>run_loop_fbdev</span><span>()</span></span>
<span class="line"><span>     → </span><span>lv_timer_handler</span><span>()</span></span>
<span class="line"><span>        → </span><span>lv_timer_exec</span><span>()  </span><span>// internal timer execution</span></span>
<span class="line"><span>           → … </span><span>draw</span><span>/</span><span>invalidations</span><span> …</span></span></code></pre>
</div>
<p><!-- /wp:kevinbatdorf/code-block-pro -->

<!-- wp:paragraph --></p>
<p id="viewer-ysrq722602">LVGL runs a <strong>timer-driven event loop</strong> that triggers area invalidation and re-drawing. Stepping through this loop is incredibly useful for understanding rendering flow, timing, and where your app’s events slot in.</p>
<p><!-- /wp:paragraph -->

<!-- wp:heading --></p>
<h2 id="viewer-jgspy22606" class="wp-block-heading">5) Handy breakpoints to try</h2>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>main()</strong> — entry point of your app.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>run_loop_fbdev()</strong> — where the frame-buffer loop hooks into LVGL.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>lv_timer_handler()</strong> — heart of LVGL’s scheduling.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>lv_refr_area() / lv_disp_refr_*</strong> — screen refresh paths.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Your widget callbacks</strong> (e.g., event handlers) — to trace UI interaction flow.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:quote --></p>
<blockquote class="wp-block-quote"><!-- wp:paragraph -->
<p><strong>Pro-tip:</strong> If you see an enormous stack, use <strong>stack filtering</strong> in VS Code and add <strong>function breakpoints</strong> for specific LVGL symbols to jump right where it matters.</p>
<!-- /wp:paragraph --></blockquote>
<p><!-- /wp:quote -->

<!-- wp:heading --></p>
<h2 id="viewer-u8pyd22637" class="wp-block-heading">6) Troubleshooting</h2>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li><strong>Can’t connect to </strong><a href="http://localhost:1234" target="_blank" rel="noreferrer noopener"><strong>localhost:1234</strong></a><strong>?</strong>Make sure <a href="http://stg.sh/QEMU" target="_blank" rel="noreferrer noopener">stg.sh/QEMU</a> is running. If your setup uses a different port, update miDebuggerServerAddress.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>No source lines / function names?</strong>Confirm CMAKE_BUILD_TYPE=Debug is active and that you rebuilt after cleaning linux/usr/build/. Check your final binary with file linux/usr/build/bin/lvglsim (should mention “with debug_info”).</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li><strong>Wrong architecture warnings in gdb?</strong>Use <strong>gdb-multiarch</strong> (not the host’s default gdb). The target is aarch64/virt64.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:heading --></p>
<h2 id="viewer-p8jpd22658" class="wp-block-heading">What you learn</h2>
<p><!-- /wp:heading -->

<!-- wp:list --></p>
<ul class="wp-block-list"><!-- wp:list-item -->
<li>How LVGL’s timer engine orchestrates redraws.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>Where your app code participates in the event → draw pipeline.</li>
<!-- /wp:list-item -->

<!-- wp:list-item -->
<li>How to pause anywhere, read a <strong>precise call stack</strong>, and step through rendering.</li>
<!-- /wp:list-item --></ul>
<p><!-- /wp:list -->

<!-- wp:heading --></p>
<h2 id="viewer-vnr0q22672" class="wp-block-heading">That’s it — enjoy LVGL debugging with Infrabase!</h2>
<p><!-- /wp:heading -->

<!-- wp:paragraph --></p>
<p id="viewer-vuacy22674">If you haven’t read the intro to our BitBake/OpenEmbedded setup yet, <a href="https://www.edgemtech.com/forum/general-discussion/an-introduction-to-infrabase-for-running-linux-lvgl-on-qemu-aarch64" target="_blank" rel="noreferrer noopener"><u>start here</u></a>.Questions or tips from your own sessions are very welcome in the thread!</p>
<p><!-- /wp:paragraph --></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/embedded-user-interface/debugging-lvgl-on-infrabase-qemu-no-hardware-needed-a-step-by-step-guide/#post-30</guid>
                    </item>
				                    <item>
                        <title>Yocto</title>
                        <link>https://dev.edgemtech.ch/community/general-discussions/yocto/#post-29</link>
                        <pubDate>Sat, 10 Jan 2026 09:43:38 +0000</pubDate>
                        <description><![CDATA[The Yocto Project is an open-source collaboration that provides templates, tools, 
and methods to create custom Linux-based systems. 
Yocto offers unparalleled flexibility and control.
 ...]]></description>
                        <content:encoded><![CDATA[<p id="viewer-5iwj81050" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">The Yocto Project is an open-source collaboration that provides templates, tools, </span></p>
<p id="viewer-90my91052" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">and methods to create custom Linux-based systems. </span></p>
<p id="viewer-gxjil1054" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">Yocto offers unparalleled flexibility and control.</span></p>
<div id="viewer-obshp1161" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj"> </span></div>
<p id="viewer-74vai1056" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">&#x1f527; Why Yocto?</span></p>
<div id="viewer-9x6p61072" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj"> </span></div>
<p id="viewer-jhhqj1058" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">&#x2714; Customizability: Tailor your Linux distribution to meet specific project needs.</span></p>
<p id="viewer-t2m8l1060" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">&#x2714; Scalability: Easily adapt to different hardware platforms.</span></p>
<p id="viewer-83ocn1062" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">&#x2714; Community Support: Leverage a vibrant community for continuous improvement and innovation.</span></p>
<div id="viewer-eyqvx1064" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj"> </span></div>
<p id="viewer-dg4o31155" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">Incorporating Yocto into the workflow enables the dev team to streamline development, </span></p>
<p id="viewer-k656d1066" class="SpiL2 kjztB _4OSHH wHFxW" dir="auto"><span class="G7Gjj">reduce time-to-market, and maintain robust, secure systems.</span></p>]]></content:encoded>
						                            <category domain="https://dev.edgemtech.ch/community/"></category>                        <dc:creator>Daniel Rossier</dc:creator>
                        <guid isPermaLink="true">https://dev.edgemtech.ch/community/general-discussions/yocto/#post-29</guid>
                    </item>
							        </channel>
        </rss>
		