<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-08-20T01:42:03+00:00</updated><id>/feed.xml</id><title type="html">Abdullah’s Blog</title><subtitle>All my work pertaining to GSoC &apos;26</subtitle><author><name>Abdullah Wasiq (aftwasiq)</name></author><entry><title type="html">Final Report</title><link href="/2026/08/18/Final-Report/" rel="alternate" type="text/html" title="Final Report" /><published>2026-08-18T12:00:00+00:00</published><updated>2026-08-18T12:00:00+00:00</updated><id>/2026/08/18/Final-Report</id><content type="html" xml:base="/2026/08/18/Final-Report/"><![CDATA[<p>GSoC now comes to an end, and I learned a lot these past months. I had a great time contributing to RTEMS. That being said, I am not completely done at the time of writing, as my MRs are in review status, and after they will need to be checked/updated as per anything my mentors or other maintainers point out.</p>

<h2 id="project-scope">Project Scope</h2>

<p>This project encompassed several objectives:</p>

<ul>
  <li>Prototyping &amp; creation of a two-way UART transport that successfully initializes all Scrutiny functions.</li>
  <li>Identify which metrics to implement and add their implementation.</li>
  <li>Add example initialization code based on earlier prototyping and demo</li>
  <li>Add documentation regarding using Scrutiny with RTEMS</li>
  <li>Build recipe (already written in advance)</li>
</ul>

<p>However, another deliverable was added on while making instrumentation metrics easier to implement.</p>

<ul>
  <li>Add a new CPU usage directive to the Classic RTEMS API</li>
  <li>Add documentation for the new CPU usage directive</li>
  <li>Add testsuite for the new CPU usage directive</li>
</ul>

<h2 id="accomplishments--leftover-work">Accomplishments &amp; leftover work</h2>

<p>I ended up finishing most of my deliverables. The only thing I could not properly wrap up was sample instrumentation metrics. I did have a basic interrupt count &amp; CPU usage working, however my interrupt count metric was a bit rough, and CPU usage relied on the <code class="language-plaintext highlighter-rouge">rtems_task_get_cpu_usage()</code> directive which took far longer than expected to work on. However, I’m fine with this tradeoff, because I plan to add instrumentation metrics as incremental additions after GSoC. This API addition was a great learning experience, and I think it was a good use of time, because this directive may benefit RTEMS users, even outside of using Scrutiny.</p>

<p>I’m excited to continue contributing to RTEMS, and Scrutiny aswell. I’ll be expanding the Scrutiny integration effort over time, as I said, but also adding support for different transports.</p>

<h2 id="code-currently-at-time-of-writing-0818-it-is-all-either-draft-or-unmerged">Code (currently at time of writing 08/18, it is all either draft or unmerged)</h2>

<ul>
  <li>Adding <code class="language-plaintext highlighter-rouge">rtems_task_get_cpu_usage()</code> as a new directive to the classic RTEMS API: <a href="https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1347/diffs">MR !1347</a></li>
  <li>Documentation for the <code class="language-plaintext highlighter-rouge">rtems_task_get_cpu_usage()</code> directive: <a href="https://gitlab.rtems.org/rtems/docs/rtems-docs/-/merge_requests/248">MR !248</a></li>
  <li>Scrutiny initialization code under <code class="language-plaintext highlighter-rouge">rtems-examples</code>: <a href="https://gitlab.rtems.org/rtems/rtos/rtems-examples/-/merge_requests/34">MR !34</a></li>
  <li>Scrutiny documentation for installing &amp; running with RTEMS: <a href="https://gitlab.rtems.org/rtems/docs/rtems-docs/-/merge_requests/252">MR !252</a></li>
  <li>Scrutiny build recipe <em>(this was mainly made before GSoC)</em>: <a href="https://gitlab.rtems.org/rtems/docs/rtems-docs/-/merge_requests/252">MR !229</a></li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>I’m so glad I’ve been given the opportunity to work on this project. I feel like I’ve only scratched the surface to RTEMS and I’m eager to learn more.</p>

<p>I want to thank my mentor Pier-Yves Lessard, without him, I would be stuck debugging basic stuff for weeks. He has been an incredible help and I had several insightful conversations with him. I learnt a lot.</p>

<p>I also want to thank my other mentors Gedare Bloom, Amar Thakar, and Wayne Thornton for all their help in guiding me throughout the RTEMS-related components of the project. I’d still be lost navigating RTEMS without them. I also really appreciate the input from all other maintainers when I wrote up discussion posts regarding help.</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[GSoC now comes to an end, and I learned a lot these past months. I had a great time contributing to RTEMS. That being said, I am not completely done at the time of writing, as my MRs are in review status, and after they will need to be checked/updated as per anything my mentors or other maintainers point out.]]></summary></entry><entry><title type="html">Finalizing the Integration: documentation, example testsuites, and the build recipe</title><link href="/2026/08/08/Documentation/" rel="alternate" type="text/html" title="Finalizing the Integration: documentation, example testsuites, and the build recipe" /><published>2026-08-08T12:00:00+00:00</published><updated>2026-08-08T12:00:00+00:00</updated><id>/2026/08/08/Documentation</id><content type="html" xml:base="/2026/08/08/Documentation/"><![CDATA[<h2 id="preliminary-information">Preliminary Information</h2>

<p>todo</p>

<h2 id="documentation">Documentation</h2>

<p>todo</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Preliminary Information]]></summary></entry><entry><title type="html">Exposing Metrics from RTEMS to Scrutiny: CPU Usage</title><link href="/2026/07/30/Exposing-CPU-Usage/" rel="alternate" type="text/html" title="Exposing Metrics from RTEMS to Scrutiny: CPU Usage" /><published>2026-07-30T12:00:00+00:00</published><updated>2026-07-30T12:00:00+00:00</updated><id>/2026/07/30/Exposing-CPU-Usage</id><content type="html" xml:base="/2026/07/30/Exposing-CPU-Usage/"><![CDATA[<h2 id="getting-started">Getting Started</h2>
<p>Over the past couple weeks I’ve been working on adding a new addition to the RTEMS classic API in order to make instrumenting CPU usage easier.</p>

<p>This expands the scope of my GSoC project significantly, and is a very big addition, so I may need to postpone the instrumentation of stack/heap usage until <em>after</em> I finish the remaining integration work (example testsuite + documentation) instead of before.</p>

<p>I’m no particularly worried about instrumenting stack &amp; heap usage as these can be aspects that can be addeed to the integration work as issues even after GSoC. What matters most is that Scrutiny is able to run with RTEMS easily for any user- and clearing up my current CPU Usage API addition (which took longer than I initially anticipated)</p>

<h2 id="merge-request">Merge Request</h2>

<p>Since most of the work these couple weeks has been far more back and forth I hadn’t had too much time to lay out the exact reasoning and development choices of what I’m doing. Hopefully the current open merge request will suffice to explain most of what I’ve been doing <a href="https://gitlab.rtems.org/rtems/rtos/rtems/-/merge_requests/1347">here</a></p>

<p>This MR adds a new directive following a discussion on instrumenting a numeric CPU usage value.</p>

<p>The directive is based off the helper function getrusage_RUSAGE_THREAD from the POSIX function getrusage(). Instead of being hardcoded to the self_id however, it takes a valid rtems_id and fills a timespec struct instead of a rusage struct.</p>

<h2 id="details">Details</h2>

<p>I will elaborate more on how this will make instrumentation to Scrutiny easier within the coming days. Right now (while the MR is pending approval) I will shift over to adding documentation, writing the example testsuite, finalizing the build recipe, and integrating postbuild activity to waf.</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Getting Started Over the past couple weeks I’ve been working on adding a new addition to the RTEMS classic API in order to make instrumenting CPU usage easier.]]></summary></entry><entry><title type="html">Midterm Analysis: What’s been done and what’s left</title><link href="/2026/07/05/Midterm/" rel="alternate" type="text/html" title="Midterm Analysis: What’s been done and what’s left" /><published>2026-07-05T12:00:00+00:00</published><updated>2026-07-05T12:00:00+00:00</updated><id>/2026/07/05/Midterm</id><content type="html" xml:base="/2026/07/05/Midterm/"><![CDATA[<h2 id="getting-started">Getting Started</h2>

<p>Due to the upcoming midterm evaluation, I wanted to write out an outline of milestones that I’ve achieved, and many more that are to come following the rest of this GSoC.</p>

<p>All my work (which is all in demo files at the moment) is located in this branch of my RTEMS fork <a href="https://gitlab.rtems.org/aftwasiq/rtems/-/tree/updates?ref_type=heads">here</a>.</p>

<p>The initial deliverables presented during my proposal (and later refined per mentor discussion) document included:</p>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Deliverable 1: Creation of a two-way UART transport that successfully initalizes all Scrutiny functions.
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />UART initialization over the termios layer</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Timestamp integration using CLOCK_MONOTONIC &amp; clock_gettime()</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Initialize fixed-frequency &amp; variable datalogging with RTEMS tasks</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Scrutiny Firmware Description file postbuild generation</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Deliverable 2: Identify which metrics to implement and add their implementation.
    <ul class="task-list">
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Interrupt Count</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />CPU Usage (per task &amp; system)</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Stack Usage</li>
      <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Heap Usage</li>
    </ul>
  </li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Deliverable 3: Write documentation &amp; a comprehensive testsuite(s) regarding the process in the first deliverable.</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Deliverable 4: Build recipe (already written in advance, so this is no longer a GSoC deliverable besides minor tweaking)</li>
</ul>

<h2 id="first-deliverable-two-way-uart-transport--scrutiny-integration">First Deliverable (two-way UART transport + Scrutiny integration)</h2>

<p>This was my primary focus throughout the first half of GSoC. Making sure Scrutiny boots up with RTEMS through not only physical hardware, but emulation was my primary goal, on both little endian &amp; big endian architectures. The focus on the emulator aspect is due to the easiness of testing the integration for maintainers.</p>

<p>So far, this integration effort has been tested on STM32F401RE physical hardware &amp; LEON3 QEMU.</p>

<p>The first week introduced one roadblock in running Scrutiny with RTEMS via SIS. Before I chose QEMU, my initial idea was to test it through SIS (sparc instruction simulator). Unfortunately, this is the only target (so far) which this integration does not work on. My first week was spent constantly debugging through the emulated firmware handshaking with the Scrutiny server whilst using socat as a middleman. Thankfully, it is not required for this integration to work on all targets due to the nature of it being an optional experience. However, I will still raise an issue after GSoC to look into this, more info on my blog post from the first week.</p>

<p>The rest of the process that went on for the following 2 weeks involved a lot of research. Mainly research into the best timestamp methodology to use from RTEMS and how to initialize RTEMS tasks in a seamless manner. I took a lot of inspiration from existing testsuites, aswell as discussion with my mentors. For getting timestamps for Scrutiny, I settled on using CLOCK_MONOTONIC with clock_gettime(). For setting up RTEMS tasks to hook onto Scrutiny datalogging, I followed through the implementation of RTEMS tasks from the testsuite ticker.c.</p>

<p>The final bit of this deliverable was to ensure variable from my RTEMS demo file are actually available to instrument to Scrutiny. This involved either initializing runtime published variables (which the user does themselves) or postbuild generation of an SFD, which is a Scrutiny Firmware Description file. The SFD contains important information like the firmware id, variable map, and aliases in order to tell the Scrutiny GUI what to instrument. I integrated this postbuild integration to my demo file and was able to successfully instrument variables from my demo file.</p>

<p>After all this, we successfully got RTEMS running with Scrutiny.</p>

<h2 id="second-deliverable-exposing-metrics">Second Deliverable (Exposing metrics)</h2>

<p>The Metrics I decided to implement for the core of this GSoC project are interrupt count (across all vectors or one), cpu utilization usage, stack usage, &amp; heap usage. If time permits, I will also look into other metrics like networking and device I/O.</p>

<p>Interrupt count took me awhile to tackle, namely because I had to do a lot of research with trial &amp; error. My initial approach was using deprecated old functions from the RTEMS interrupt directive, but over the week I was working on this function I was able to settle on the best approach using the handler install directive. I was able to successfully extract an interrupt count, across all possible working vectors.</p>

<p>At the time of writing, the current metric I’m working towards is CPU usage. This is actually not as hard as I thought it would be, however, there is still a lot of trial &amp; error with determining the best method in accordance to RTEMS conventions. The approach I’m settling on is to measure CPU usage during the idle task, and using that to calculate the usage when it isn’t in the idle task (henceforth, getting the CPU load when active). I’m also contemplating adding another additional metric for CPU time elapsed in seconds, which won’t be too difficult to add (I hope).</p>

<p>The next metrics to follow are stack usage &amp; heap usage, which I will approach following the completion of CPU usage in the following week. Can’t wait.</p>

<p>One thing that I will need to discuss with my mentors is how the implementation of the metrics will be merged to RTEMS. I intended to add some sort of library and expose these as Scrutiny-agnostic functions. I don’t know if this approach is right. I will need to look into how “glue” code like this is typically implemented in RTEMS more in-depth, and to get advice from my mentors on the RTEMS side.</p>

<h2 id="third-deliverable-documentation-and-testsuites">Third Deliverable (Documentation and testsuites)</h2>

<p>I don’t expect this deliverable to be too lengthy. My testsuite will most likely just be the same as my demo file (which includes my rough work in my local fork), just polished and cleaned up, with the metrics implemented as function calls.</p>

<h2 id="fourth-deliverable-build-recipe">Fourth Deliverable (Build Recipe)</h2>

<p>The current build recipe I have in my fork of the RSB works quite well. There are some small tweaks I need to make however. There is also the matter of integrating the postbuild activity (SFD stuff) with waf as it’s currently sitting around in CMakeList files.</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Getting Started]]></summary></entry><entry><title type="html">Exposing Metrics from RTEMS to Scrutiny: Interrupts</title><link href="/2026/06/30/Exposing-Metrics/" rel="alternate" type="text/html" title="Exposing Metrics from RTEMS to Scrutiny: Interrupts" /><published>2026-06-30T12:00:00+00:00</published><updated>2026-06-30T12:00:00+00:00</updated><id>/2026/06/30/Exposing-Metrics</id><content type="html" xml:base="/2026/06/30/Exposing-Metrics/"><![CDATA[<h2 id="getting-started">Getting Started</h2>
<p>The next couple weeks will document one of the biggest parts of this GSoC project, exposing the actual raw metrics from RTEMS to Scrutiny so they can be instrumented. Unfortunately, RTEMS does not provide any “raw” constantly updating numeric values exclusively for any of the metrics I want to implement (namely for this blog, interrupts).</p>

<p>Counting the amount of interrupts as a single numeric updating value is something RTEMS does not provide either. Using the example of determining memory usage through <code class="language-plaintext highlighter-rouge">stackchk.h</code> (an RTEMS library under <code class="language-plaintext highlighter-rouge">libmisc/</code>), it does provide numeric values, but only as information within a struct that is given to you via callbacks, therefore this cannot be used as a metric to hook onto Scrutiny.</p>

<p>The most roundabout but obvious way to get around this is to parse the printer functions that RTEMS does provide and extract the numeric values from them. Unfortunately, this is unefficient and may not even fit with the rate at which Scrutiny runs its instrumentation. We need a variable that is always available, consistently updated, numeric, and has one memory address to instrument off of.</p>

<p>My proposal initially was to create a small library under <code class="language-plaintext highlighter-rouge">libmisc/</code> that provides these numeric metrics in a Scrutiny-agnostic way. This may or may not be the proper approach. Regardless, the matter at hand is to first get some sort of metric running through my demo file.</p>

<p>During my last blog post I initialized datalogging through the Scrutiny C Wrapper with RTEMS via my demo file. If we look back at the 100hz function:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>void task_100hz() {
    counter++;
    scrutiny_c_loop_handler_fixed_freq_process(task_100hz_lh, 10000U);
}
</code></pre></div></div>

<p>We don’t return the counter variable or anything. Scrutiny will instrument its value through the varmap generated by the SFD or as a runtime published variable (RPV) if initialized otherwise.</p>

<p>Now to count interrupts, I initialize an interrupt count variable with <code class="language-plaintext highlighter-rouge">_Atomic</code> before it. If an interrupt fires while the counter variable is being read it can cause corruption, so we need to make sure the interrupt count is an atomic value.</p>

<p><code class="language-plaintext highlighter-rouge">_Atomic uint32_t interrupts = 0;</code></p>

<p><em>Later edit: better to probably use <code class="language-plaintext highlighter-rouge">volatile</code></em></p>

<p>Now the real challenge comes, actually counting interrupts in a hardware agnostic way. We want this abstract enough to work across all architectures.</p>

<h3 id="my-initial-approach">My initial approach</h3>

<p>My initial approach involved using rtems_interrupt_catch to “catch” whenever an interrupt fired…</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rtems_status_code interrupt_counter(rtems_vector_number vector) { 
    rtems_isr_entry old_isr_handler;

    rtems_status_code catch = rtems_interrupt_catch(
            interrupt_counter_isr,
            vector,
            &amp;old_isr_handler
            );

    return catch;
}
</code></pre></div></div>

<p>Establishing a new ISR that just increments everytime time an interrupt is caught:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rtems_isr interrupt_counter_isr(rtems_vector_number vector) {
    interrupts++;
}
</code></pre></div></div>

<p>Then feeding it to the Init() past the Scrutiny config and task config:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>status = interrupt_counter(LEON3_VECTOR);
directive_failed( status, "interrupt" );
</code></pre></div></div>

<p>Later edit: rtems_interrupt_catch() may be deprecated. A more modern replacement would need to be found. The overall logic remains the same however.</p>

<h3 id="attempting-a-new-solution">Attempting a new solution:</h3>

<p>Unfortunately this methodology does not seem to work effectively. The problem is that this is far too much of a simple approach (coupled with rtems_interrupt_catch() not being optimal) to count interrupts across all hardwares. After testing on both STM32F4 physical hardware &amp; LEON3 QEMU, the <code class="language-plaintext highlighter-rouge">interrupts</code> variable doesn’t seem to increment.</p>

<p>There may not be a possible way to expose an interrupt count that is hardware-agnostic. Almost every solution requires something specific design that takes from the BSPs in question.</p>

<p>After some more research, I’m aiming towards another solution using <code class="language-plaintext highlighter-rouge">rtems_interrupt_handler_install()</code>, this would require something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rtems_status_code rtems_interrupt_handler_install(
  rtems_vector_number     vector,
  const char             *info,
  rtems_option            options,
  rtems_interrupt_handler routine,
  void                   *arg
);
</code></pre></div></div>

<p>(taken from the documentation on interrupt directive <a href="https://docs.rtems.org/docs/main/c-user/interrupt/directives.html#interfacertemsinterruptserverhandlerinstall/">here</a>)</p>

<p>This way, I’d be able to handle counting interrupt more seamlessly. However, this isn’t entirely hardware agnostic since you still need to pass a vector value. If I take the approach of a telemetry library (or even any other sort of “glue” code), this function would take in the vector number as a parameter. This would be provided by the user depending on which BSP they’re using.</p>

<p>I wrote up this directive,</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rtems_interrupt_handler_install(
    LEON3_VECTOR, /* test vector on 14 */
    "interrupt counter",
    RTEMS_INTERRUPT_SHARED,
    interrupt_counter,
    NULL
);
</code></pre></div></div>

<p>However, I still got issues with getting the interrupt count to increment. On the Scrutiny GUI, it simply stays at 0. After various hours of siphoning through solutions, I realized the problem may be linked to whether an interrupt was being picked up at all.</p>

<p>At the current moment, there is one glaring issue with counting interrupts this way, it only counts interrupts from ONE vector. And there weren’t any interrupts firing from that vector while I was testing. That being said, I manually edited the leon3 vector 14 register so I create a fake interrupt:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>volatile uint32_t *irq = (volatile uint32_t*) 0x80000208;
*irq = (1 &lt;&lt; 14);
</code></pre></div></div>

<p>But there was also another issue, with Scrutiny. This is specific to the LEON3 architecture since it’s big endian. Scrutiny has some issues with byte-swapping and decoding on big endian architecture which will be fixed soon after I discussed it with my mentor. Regardless, all I had to do to fix this was assign a new interrupt count variable and byte swap it (though this took me quite a while to figure out):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>interrupts_count = __builtin_bswap32(interrupts);
</code></pre></div></div>

<p><em>As of 2026-07-02 this has been fixed, so I no longer need to byte swap. Scrutiny now supports big endian architecture seamlessly</em></p>

<p>And finally, after running Scrutiny, we can see that this interrupt was counted:</p>

<p><img width="415" height="56" alt="image" src="https://github.com/user-attachments/assets/75eb09d2-23a3-437e-ab73-00c368ba84a5" /></p>

<p>However, that’s not all there is to interrupt counts. As I said, this only counts an interrupt from ONE vector, we need to loop through all interrupt vectors in order to establish a handler on each one. Some will fail (so I won’t use directive) for sure, but we’ll be able to extract a count for all interrupts through this manner. All the user needs to provide is the amount of vectors according to their BSP, instead of the vector number itself. In the case of LEON3 architecture, it’s 15 vectors, and the STM32F4 has 96.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>for (uint32_t i = 0; i &lt; LEON3_VECTOR_COUNT; i++) { /* or STM32F4_VECTOR_COUNT */
    status = rtems_interrupt_handler_install(
        i,
        "interrupt counter",
        RTEMS_INTERRUPT_SHARED,
        interrupt_counter,
        NULL
    );
    // directive_failed( status, "interrupt counter" );
}
</code></pre></div></div>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Getting Started The next couple weeks will document one of the biggest parts of this GSoC project, exposing the actual raw metrics from RTEMS to Scrutiny so they can be instrumented. Unfortunately, RTEMS does not provide any “raw” constantly updating numeric values exclusively for any of the metrics I want to implement (namely for this blog, interrupts).]]></summary></entry><entry><title type="html">Scrutiny Firmware Description (SFD) files &amp;amp; Datalogging</title><link href="/2026/06/13/SFD-and-Datalogging/" rel="alternate" type="text/html" title="Scrutiny Firmware Description (SFD) files &amp;amp; Datalogging" /><published>2026-06-13T12:00:00+00:00</published><updated>2026-06-13T12:00:00+00:00</updated><id>/2026/06/13/SFD-and-Datalogging</id><content type="html" xml:base="/2026/06/13/SFD-and-Datalogging/"><![CDATA[<h2 id="preliminary-information">Preliminary Information</h2>

<p>This post documents my findings and work during the third week of GSoC ‘26 with RTEMS. Last post I ending up getting Scrutiny up and running with RTEMS via UART on both QEMU and physical hardware. The QEMU route took some extra effort in networking the Scrutiny server to an emulator. Nonetheless we ended up getting it working. I also discussed a potential issue regarding the Scrutiny server communicating with SIS (Sparc Instruction Simulator) which is a simulator typically used for RTEMS applications.</p>

<h2 id="why-do-we-need-a-scrutiny-firmware-description-file">Why do we need a “Scrutiny Firmware Description” file?</h2>

<p>An SFD provides Scrutiny with all information regarding the firmware id (a 128 bit hash), a variable map (to store debugging symbols), aliases, and its metadata. You can read more about how it works <a href="https://scrutinydebugger.com/guide-instrumentation.html#postbuild-toolchain">here</a>.</p>

<h2 id="generating-an-sfd-then-using-cmake-to-automate-the-process">Generating an SFD then using CMake to automate the process</h2>

<p>First we need to recompile our test program with the ability to produce an .elf file. This will be crucial as we cannot create an SFD without it.</p>

<p>Then we run the following in order:</p>

<p><em>Create a variable map:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny elf2varmap scrutiny_demo.elf --output .</code></p>

<p><em>Generate a firmware id:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny get-firmware-id scrutiny_demo.elf --output .</code></p>

<p><em>Tag a firmware id to an .elf:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny tag-firmware-id scrutiny_demo.elf scrutiny_demo_tagged.elf</code></p>

<p><em>Write metadata:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny make-metadata --output . --project-name RTEMS_DEMO --version "V1"</code></p>

<p><em>Add aliases:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny add-alias . --file alias.json</code></p>

<p><em>Create the SFD:</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny make-sfd . scrutiny_demo_v1.sfd</code></p>

<p><em>Install it (It is crucial that this is installed in the same directory where you run the server)</em></p>

<p><code class="language-plaintext highlighter-rouge">scrutiny install-sfd scrutiny_demo_v1.sfd</code></p>

<p>And as we can see, our firmware finally has an SFD:</p>

<p><img width="1919" height="131" alt="image" src="https://github.com/user-attachments/assets/21c98e51-6e99-42fc-8cee-e8514ba3ce4e" /></p>

<p>And over on the GUI..</p>

<p><img width="431" height="31" alt="image" src="https://github.com/user-attachments/assets/f91f457e-5c79-44ac-87ae-7306d3504c12" /></p>

<p>(i forgot to add a version to the metadata when taking this screenshot)</p>

<p>HOWEVER, we will need to make this process more efficient via CMakeLists.txt. The Scrutiny documentation specifies the process for this. Originally I had plans to integrate this entire post-build process through the RSB (RTEMS source builder). Since I already have a working Scrutiny package under it in my personal fork.</p>

<p>Unfortunately I don’t think this is possible, because generating the SFD is post-build activity. The package I have and the system (RSB) that builds it is only a one time build. It cross compiles the Scrutiny library and builds it for the BSP specified. Generating the SFD is a seperate process that comes with linking the demo file. This is something I may have to bring up with mentors from the RTEMS side to see if there is a way to integrate this into the RSB.</p>

<p>Regardless, to automate this process I am using the following CMakeLists.txt (I also had to create a toolchain.cmake to store my previous compile statement). Normally I would build through waf, but I also need to talk with my mentors on the RTEMS side to see if I can integrate a post-build process into waf. So for the time being I’ll manually compile the demo file and generate its SFD through a simple CMakeLists:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>project(scrutiny_demo C CXX)
set(RTEMS_BSP_PATH $ENV{HOME}/gsoc/quick-start/rtems/7/sparc-rtems7/leon3)
include_directories(
    ${RTEMS_BSP_PATH}/lib/include
    ${RTEMS_BSP_PATH}/lib/include/cwrapper
    $ENV{HOME}/gsoc/quick-start/src/rtems/testsuites/support/include
)
link_directories(${RTEMS_BSP_PATH}/lib)
add_definitions(-DSCRUTINY_ENABLE_DATALOGGING=1)
add_executable(scrutiny_demo scrutiny_demo.c)

target_link_libraries(scrutiny_demo
    scrutiny-cwrapper
    scrutiny-embedded
    rtemstest
    stdc++
)

include(${RTEMS_BSP_PATH}/lib/cmake/scrutiny/scrutiny-config.cmake)

scrutiny_postbuild(scrutiny_demo
    INSTALL_SFD
    METADATA_PROJECT_NAME "RTEMS_DEMO"
    METADATA_VERSION "1"
    CPPFILT sparc-rtems7-c++filt
)
</code></pre></div></div>

<p>And it works.</p>

<h2 id="datalogging">Datalogging</h2>

<p>After getting the SFD running, I decided to go ahead and add datalogging to my current test file in order to create an embedded graph.</p>

<p>We’ll start by intializing two different loop handlers (using the C wrapper function equivalents), but make sure we have buffers for them. Since the C Wrapper needs memory sizes and addresses.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uint8_t ff_buffer[CPP_CONST_SCRUTINY_C_LOOP_HANDLER_FF_SIZE];
uint8_t vf_buffer[CPP_CONST_SCRUTINY_C_LOOP_HANDLER_VF_SIZE];
</code></pre></div></div>

<p>Then I construct the loop handlers:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>static scrutiny_c_loop_handler_ff_t *task_100hz_lh = NULL;
static scrutiny_c_loop_handler_vf_t *task_idle_lh = NULL;
</code></pre></div></div>

<p><em>Why did I split them up instead of declaring them in one line like I did last time with the main handler? Now we’re using lot’s of tasks for datalogging, and so I can’t declare everything right in the Init(). At least for now, since this demo code is currently experimental.</em></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>task_100hz_lh = scrutiny_c_loop_handler_fixed_freq_construct(ff_buffer, sizeof(ff_buffer), 100000, "task_100hz_lh");
task_idle_lh = scrutiny_c_loop_handler_variable_freq_construct(vf_buffer, sizeof(vf_buffer), "task_idle_lh");
</code></pre></div></div>

<p>Oh, and we also need to make sure to allocate a large datalogging buffer. It should be as big as possible.</p>

<p><code class="language-plaintext highlighter-rouge">uint8_t scrutiny_datalogging_buffer[4096];</code></p>

<p>We need to create a <code class="language-plaintext highlighter-rouge">task_idle()</code>. We then move the contents of our while loop (which is elaborated on in the last post) into this task. Make sure to remove the while loop. There are some slight changes, before we had a decleration of clock_gettime() with CLOCK_MONOTONIC to get the timestamp before the while loop, and another one in it. This time we only need to declare it once and set `    static uint32_t last_timestamp = 0U;` at the start of the function</p>

<p>We then need to create a <code class="language-plaintext highlighter-rouge">task_100hz()</code> that simply processes the task without a timestamp.</p>

<p>Here, now we need to change it up by hooking those tasks up to RTEMS tasks entrypoints. We make two rtems_tasks (<code class="language-plaintext highlighter-rouge">task_idle_rtems</code> and <code class="language-plaintext highlighter-rouge">task_100hz_rtems</code>, although the names should be _entrypoint instead of _rtems now that I think about it at the time of writing). Both these tasks run a while loop which calls the task and then runs <code class="language-plaintext highlighter-rouge">rtems_task_wake_after()</code>. The idle tasks uses RTEMS_YIELD_PROCESSOR as a parameter and the 100hz one uses 100ms.</p>

<p><em>later edit: We have several functions running for this, I am considering ways to integrate them all into a minimal amount. Expect future changes to the structure of how I layed things out here. Please remember this code is like a rough draft at the moment.</em></p>

<p>Okay. Now we have the tasks ready, now to start them. I took a look at a testsuite called ticker.c and basically used the exact same implementation and it worked. I won’t change it for now, since it’s working well. In short, I simply create arrays for the tasks ids and names, initialize the clock with the time of day, build the task names, create the tasks, and then start them. This is all in the Init() function.</p>

<p>And… it works!</p>

<p><img width="488" height="30" alt="image" src="https://github.com/user-attachments/assets/b719d5bd-9c47-4df5-8b11-896343723e11" /></p>

<p>As you can see here, it says “Debugger: Standby”. But we want more than that, let’s get to generating an embedded graph.</p>

<p>I’m going to initialize a basic variable <code class="language-plaintext highlighter-rouge">counter</code> and increment it in my task:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>volatile uint32_t counter = 0;

void task_100hz() {
    counter++;
    scrutiny_c_loop_handler_fixed_freq_process(task_100hz_lh, 0U);
}
</code></pre></div></div>
<p>And you can see it works!</p>

<p><img width="1842" height="976" alt="image" src="https://github.com/user-attachments/assets/14eb5b96-3cda-43cf-98c6-ff0d60cb49fb" /></p>

<p>You can also watch the variable:</p>

<p><img width="411" height="58" alt="image" src="https://github.com/user-attachments/assets/f62bd0fa-1f28-4688-873d-c72bf6840f95" /></p>

<h2 id="next-steps">Next steps:</h2>

<p>The next step is to create telemetry functions from RTEMS to expose to Scrutiny. This will be code that will actually be merged upstream!</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Preliminary Information]]></summary></entry><entry><title type="html">Running Scrutiny with RTEMS via UART</title><link href="/2026/06/10/UART-Transport/" rel="alternate" type="text/html" title="Running Scrutiny with RTEMS via UART" /><published>2026-06-10T12:00:00+00:00</published><updated>2026-06-10T12:00:00+00:00</updated><id>/2026/06/10/UART-Transport</id><content type="html" xml:base="/2026/06/10/UART-Transport/"><![CDATA[<h2 id="preliminary-information">Preliminary Information</h2>
<p>This post documents my findings and the work I’ve done through the first two weeks of GSoC ‘26. I’ve taken the first big step towards the completion of my first deliverable (out of four), which is a working UART transport.</p>

<p>The first order of business is to get the Scrutiny server handshaking with the firmware. For the sake of this blog I’ll be going along the QEMU route, so that anybody following along or observing can follow along more easily.</p>

<h2 id="getting-started">Getting started</h2>
<p>We will setup UART through the termios layer that RTEMS provides (since it is a POSIX-compliant OS).</p>

<p>For my current demo, I initialized buffers with the size of 248 bytes, for flexible testing. I am using the C wrapper provided by Scrutiny.</p>

<p>We’ll need to open UART2 via the open() system call (not UART1, the reason is because UART1 is used by the operating system, and ideally we do not want to suppress the console):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>int32_t UART2 = open( "/dev/console_b", O_RDWR | O_NONBLOCK | O_NOCTTY );
</code></pre></div></div>
<p><em>This example assumes the leon3 BSP. Open “/dev/console_b” with the name of the UART stream your BSP provides if it is different. On real hardware (STM32F4 example), you’d use <code class="language-plaintext highlighter-rouge">dev/ttyS1</code>.</em></p>

<p>Disclaimer: As I said, if you are using QEMU which this post entails, you may not be able to open a second UART. Some chips that are emulated by QEMU only provide one UART. In this case, purely for testing reasons, you will need to suppress the console in order to let Scrutiny handshake with the firmware. Using this approach on real hardware is dangerous, it should only be used for testing and integration efforts, which I am pursuing right now. In order to suppress the console, you’ll need to enter raw mode. You will also need to suppress the tmacros defines and functions if this is a test file</p>

<p>Back on track with the UART transport. Now that we’ve opened UART, we’ll need to hook it up to Scrutiny and initalize the MainHandler &amp; ConfigHandler.</p>

<p>Two buffers need to be initialized for the main handler and the config buffer. They use specific definitions written here:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>uint8_t main_handler_buffer[CPP_CONST_SCRUTINY_C_MAIN_HANDLER_SIZE];
uint8_t config_buffer[CPP_CONST_SCRUTINY_C_CONFIG_SIZE];
</code></pre></div></div>

<p>Then these structs will be initialized in order, the scrutiny config struct (<code class="language-plaintext highlighter-rouge">scrutiny_c_config_t *config</code>), which takes a construct function as a parameter (<code class="language-plaintext highlighter-rouge">scrutiny_c_config_construct()</code>).</p>

<p>Then we set its buffers, adding the scrutiny_rx &amp; scrutiny_tx buffers we initialized earlier through <code class="language-plaintext highlighter-rouge">scrutiny_c_config_set_buffers</code>.</p>

<p>We then set up the main handler (<code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_t *scrutiny_handler</code>) struct and assign it its specific construct parameter (<code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_construct()</code>). We finish off with <code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_init(scrutiny_handler, config);</code>.</p>

<h2 id="using-clock_monotonic-and-clock_gettime-for-timestamps">Using CLOCK_MONOTONIC and clock_gettime() for timestamps</h2>

<p>Then we’ll need to hook up a clock to Scrutiny. Scrutiny typically uses microseconds as a timestep. We will be using clock_gettime() with CLOCK_MONOTONIC. More on that choice shortly.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>clock_gettime(CLOCK_MONOTONIC, &amp;ts);
uint32_t last_timestamp = (ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
</code></pre></div></div>

<h2 id="sending-data-over-uart">Sending data over UART</h2>

<p>We’ll need to read from the actual UART stream from the firmware. The earlier rx &amp; tx buffers were initialized for Scrutiny internal functionality. We will need a seperate to call read() with, so another rx &amp; tx buffer for reading the UART stream.</p>

<p>Then we establish a primary while() loop which will run indefinitely till the program ends. It will call clock_gettime() again with CLOCK_MONOTONIC. The first clock_gettime() gets the current time, and this one gets the next one, so we can have an accurate timestamp. After calculating the time_delta (the current timestamp minus the last_timestamp) we can hook it up to             <code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_process(scrutiny_handler, time_delta * 10U);</code>.</p>

<p>Before that however, we need to actually read the data from the UART stream. Using read():</p>

<p><code class="language-plaintext highlighter-rouge">ssize_t bytes = read(UART2, in_buffer, sizeof(in_buffer));</code></p>

<p><em>Why use ssize_t? Because read() can return -1 in the case of error. size_t only takes unsigned integer values</em></p>

<p>Then we will receive the data with <code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_receive_data();</code></p>

<p>Then we will send the data to the scrutiny server. We first check if there are bytes to send with: <code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_data_to_send();</code>, If there are, we use <code class="language-plaintext highlighter-rouge">scrutiny_c_main_handler_pop_data()</code> to pop data from the scrutiny_handler and send over the write() syscall with:</p>

<p><code class="language-plaintext highlighter-rouge">write(UART2, out_buffer, sent)</code></p>

<p>At the end of the while make sure to set the last_timestamp to the timestamp otherwise the loop will never increase the timer.</p>

<h2 id="results">Results?</h2>

<p>I’ve saved my file as <code class="language-plaintext highlighter-rouge">scrutiny_demo.c</code>. For this example using QEMU, I compile against the leon3 BSP with my rtems-scrutiny package, on real hardware I compiled against the stm32f4 BSP. Then we use the following QEMU command:</p>

<p><code class="language-plaintext highlighter-rouge">qemu-system-sparc -M leon3_generic -m 64M -kernel scrutiny_demo.exe -serial tcp:localhost:5678,server=on,wait=on</code></p>

<p>Then you must run socat (socket cat) which is a tool for connecting network streams. Although we wrote a UART transport, since we’re emulating this process, we need to do this to connect QEMU and the scrutiny server.</p>

<p><code class="language-plaintext highlighter-rouge">socat UDP4-LISTEN:1234,fork TCP:localhost:5678</code></p>

<p>Then run the scrutiny server:</p>

<p><code class="language-plaintext highlighter-rouge">scrutiny server --config config.json</code></p>

<p>And… it works!</p>

<p><img width="1919" height="335" alt="image" src="https://github.com/user-attachments/assets/0cb00514-91e1-4251-b3c6-4baed1e1f688" /></p>

<p>On the Scrutiny GUI, we can see we’ve succesfully connected:</p>

<p><img width="510" height="32" alt="image" src="https://github.com/user-attachments/assets/29bbc572-7810-4302-8529-68e4f95a83ca" /></p>

<h2 id="why-qemu-why-not-sis">Why QEMU? Why not SIS?</h2>

<p>SIS (Sparc Instruction Simulator) is a commonly used simulator in RTEMS for the sparc family BSPs. I originally planned to run Scrutiny for emulation via this simulator. However, the (simulated) firmware was not able to handshake with SIS. Using socat I exposed a PTY (pseudo terminal) to SIS, though despite my best efforts I could not get SIS to handshake with the Scrutiny server.</p>

<p>The bytes the Scrutiny server sends as a DISCOVER request do not get received by the simulated firmware and the firmware responds back with garbage (which we assume, but on further research I found that it sends back a frame delimiter).</p>

<p>This may warrant an issue afer or during GSoC in order to fix. During the 06/10 meeting, one of my mentors, Gedare, mentioned that due to Scrutiny being an optional debugger, it is fine that it does not work on every single simulator. For the time being QEMU + physical hardware should suffice, but I would be happy to work on this as a seperate issue after GSoC.</p>

<h2 id="next-steps">Next steps:</h2>

<p>Next, we will need make changes to the rtems-scrutiny package I currently have made, and add the ability to create an SFD (Scrutiny Firmware Description) file. This file will provide us with the ability to set the debugging symbols in the firmware so we can actually expose instrumentation metrics from RTEMS.</p>

<p>After that, we will need to actually expose instrumentation metrics from RTEMS to Scrutiny. This may involved creating new functions that will read CPU internals and hardware information from RTEMS that are not currently available.</p>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Preliminary Information This post documents my findings and the work I’ve done through the first two weeks of GSoC ‘26. I’ve taken the first big step towards the completion of my first deliverable (out of four), which is a working UART transport.]]></summary></entry><entry><title type="html">Getting started with Scrutiny + RTEMS</title><link href="/2026/05/26/Running-Scrutiny-with-RTEMS/" rel="alternate" type="text/html" title="Getting started with Scrutiny + RTEMS" /><published>2026-05-26T12:00:00+00:00</published><updated>2026-05-26T12:00:00+00:00</updated><id>/2026/05/26/Running-Scrutiny-with-RTEMS</id><content type="html" xml:base="/2026/05/26/Running-Scrutiny-with-RTEMS/"><![CDATA[<h2 id="preliminary-information">Preliminary Information</h2>
<h3 id="what-is-rtems">What is RTEMS?</h3>

<p>RTEMS is an open source real-time operating system for embedded systems used in a multitude of applications ranging from spacecraft to experimental physics.</p>

<h3 id="what-is-scrutiny">What is Scrutiny?</h3>

<p>Scrutiny is a C++ instrumentation library which provides the user with a seamless real-time debugging experience, it works via a client GUI and a compiled firmware library which communicate with eachother over any protocol.</p>

<h3 id="why-bring-scrutiny-to-rtems">Why bring Scrutiny to RTEMS?</h3>

<p>RTEMS currently relies primarily on stop-mode debugging via JTAG tools. Unfortunately, stop-mode debugging actively halts your processor during hardware analysis. This means that it cannot be used to debug a live or real time system that is already running, hence why JTAG based tools are more suitable for startup. Another issue is that JTAG based debugging tools tend to be proprietary or expensive, and ones that are not are often difficult and complex to use. With efforts to bring RTEMS forward as more usable for a greater degree of engineers beyond specific scientific niches, easy to use debugging tools will prove invaluable to the projects future. With Scrutiny, this will be possible, allowing users to debug systems that are already live, aswell as providing a beginner &amp; amateur friendly framework for debugging in the first place.</p>

<h2 id="getting-started">Getting Started</h2>

<h3 id="cross-compiling-rtems-with-scrutiny">Cross-Compiling RTEMS with Scrutiny</h3>

<p>To use Scrutiny with RTEMS for initial development, you’ll need to build RTEMS with Scrutiny. This is a relatively straightforward process.</p>

<p><em>todo: add details</em></p>

<h3 id="building-scrutiny-with-rtems">Building Scrutiny with RTEMS</h3>

<p>For this GSoC ‘26, I’ve completed the preliminary work of creating a build recipe so that Scrutiny can build with the RTEMS Source Builder as a third party package. That being said, it is currently posted as a draft merge request will be assessed after the completion of the deliverables for this GSoC project. You can view the draft merge <a href="https://gitlab.rtems.org/rtems/tools/rtems-source-builder/-/merge_requests/229">here</a> for more details.</p>

<h3 id="next-post-running-scrutiny-with-rtems-successfully-launching-the-gui-via-uart">Next post: Running Scrutiny with RTEMS (successfully launching the GUI via UART)</h3>]]></content><author><name>Abdullah Wasiq (aftwasiq)</name></author><summary type="html"><![CDATA[Preliminary Information What is RTEMS?]]></summary></entry></feed>