<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>blog.bkpt.party</title>
    <link>https://blog.bkpt.party/</link>
    <description>Recent content on blog.bkpt.party</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 18 Aug 2025 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://blog.bkpt.party/index.xml" rel="self" type="application/rss+xml" />
    
    
    
    <item>
      <title>GSoC Project Updates, Threads!</title>
      <link>https://blog.bkpt.party/posts/gsoc7/</link>
      <pubDate>Mon, 18 Aug 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc7/</guid>
      <description>&lt;p&gt;Since my last update I have been busy with MicroPython tests- enabling new features and testing them, isolating problematic test cases, sometimes placing appropriate definitions and function calls in the C code.&lt;/p&gt;
&lt;p&gt;I traced the failure of &lt;code&gt;builtin_compile&lt;/code&gt; to the &lt;code&gt;__globals__&lt;/code&gt; attribute not being available for function objects. Enabling that fixed it.&lt;/p&gt;
&lt;p&gt;I also now include the previously ignored &lt;code&gt;float&lt;/code&gt; test group, giving us 9 more passing tests.&lt;/p&gt;
&lt;p&gt;Turns out that the &lt;code&gt;int_big_div&lt;/code&gt; and &lt;code&gt;int_big_mul&lt;/code&gt; tests that I mentioned in my previous post were failing because of hardware flow control issues and I fixed it by enabling the &lt;code&gt;IXON&lt;/code&gt; termios flag.&lt;/p&gt;
&lt;p&gt;The latest update with test cases is that I have 588 passing test cases out of 591 executed. The failing test cases are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;io_iobase&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;print_exception&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sys_atexit&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am tracking progress on test cases in this &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/issues/1&#34;&gt;issue&lt;/a&gt;. Here is a list of all MicroPython modules that have been enabled so far:&lt;br&gt;
&lt;code&gt;array&lt;/code&gt;, &lt;code&gt;builtins&lt;/code&gt;, &lt;code&gt;cmath&lt;/code&gt;, &lt;code&gt;collections&lt;/code&gt;, &lt;code&gt;errno&lt;/code&gt;, &lt;code&gt;gc&lt;/code&gt;, &lt;code&gt;heapq&lt;/code&gt;, &lt;strong&gt;io&lt;/strong&gt;, &lt;code&gt;json&lt;/code&gt;, &lt;code&gt;math&lt;/code&gt;, &lt;strong&gt;os&lt;/strong&gt;, &lt;code&gt;platform&lt;/code&gt;, &lt;code&gt;random&lt;/code&gt;, &lt;strong&gt;re&lt;/strong&gt;, &lt;code&gt;struct&lt;/code&gt;, &lt;strong&gt;sys&lt;/strong&gt;, &lt;code&gt;time&lt;/code&gt;, &lt;strong&gt;machine&lt;/strong&gt;, &lt;code&gt;uctypes&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The highlighted ones are either partially enabled, or have a failing testcase.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;io&lt;/strong&gt;: failing &lt;code&gt;io_iobase&lt;/code&gt; test&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;os&lt;/strong&gt;: no filesystem, so the &lt;code&gt;fs&lt;/code&gt; functions are not enabled&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;re&lt;/strong&gt;: failing &lt;code&gt;re_stack_overflow&lt;/code&gt; test&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sys&lt;/strong&gt;: &lt;code&gt;settrace&lt;/code&gt;, &lt;code&gt;ps1&lt;/code&gt;, &lt;code&gt;ps2&lt;/code&gt;, &lt;code&gt;std{out,in,err}&lt;/code&gt; not enabled. failing &lt;code&gt;sys_atexit&lt;/code&gt; test&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;machine&lt;/strong&gt;: only the bare minimum is enabled as we are using the qemu pc-686 BSP and there is no I2C, SPI, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;threads&#34;&gt;threads&lt;/h2&gt;
&lt;p&gt;I have also been able to get threads working on MicroPython. The threads use RTEMS Tasks internally. As for testing threads, I currently have five passing test cases. There are around 8 to 9 more tests but those need locks on the MicroPython side, which is still a work in progress.&lt;/p&gt;
&lt;p&gt;I wanted to talk more about how threads are implemented in MicroPython. MicroPython doesn&amp;rsquo;t have documentation for the &lt;a href=&#34;https://docs.micropython.org/en/latest/library/_thread.html&#34;&gt;_thread&lt;/a&gt; module as it is &amp;ldquo;highly experimental and its API is not yet fully settled&amp;rdquo;, so I think that makes it a really good topic for a blog post. The thread functions are listed in &lt;code&gt;py/mpthread.h&lt;/code&gt;. Ports that implement threads, i.e. the &lt;code&gt;_thread&lt;/code&gt; module, need to implement these functions in a &lt;code&gt;mpthreadport.c&lt;/code&gt;. Here&amp;rsquo;s a link to my current &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/threads_experiments/ports/rtems/mpthreadport.c&#34;&gt;mpthreadport.c&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s some debugging output that visualizes the order in which different functions are called:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;MicroPython v1.26.0-preview.154.g0dbda0e0c.dirty on 2025-08-20; rtems-i386/pc686 with unknown-cpu
THREAD: get_state
&amp;gt;&amp;gt;&amp;gt; import _thread as th
THREAD: get_state
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
THREAD: get_state
&amp;gt;&amp;gt;&amp;gt; x = lambda: print(&amp;#34;thread!&amp;#34;)
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
&amp;gt;&amp;gt;&amp;gt; th.start_new_thread(x, ())
THREAD: get_state
...
THREAD: get_state
THREAD: get_state
167837698
THREAD: get_state
THREAD: get_state
&amp;gt;&amp;gt;&amp;gt; THREAD: set_state
THREAD: get_state
THREAD: mutex_lock
THREAD: thread_start
THREAD: get_state
thread!
THREAD: get_state
THREAD: thread_finish
THREAD: get_state
THREAD: get_state
...
&amp;gt;&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The state for multiple threads is tracked using a linked list, access to which is protected by a mutex. An internal task is created for a new thread using the RTMS task API and a new node is added to the linked list. Here&amp;rsquo;s the structure of a node:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; _mp_thread_t {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rtems_id id;               &lt;span style=&#34;color:#75715e&#34;&gt;// RTEMS task ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt; ready;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;arg;                 &lt;span style=&#34;color:#75715e&#34;&gt;// thread-entry args
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; _mp_thread_t &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;next;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;mp_state_thread_t&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;state;  &lt;span style=&#34;color:#75715e&#34;&gt;// pointer to this thread&amp;#39;s mp state
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;} &lt;span style=&#34;color:#66d9ef&#34;&gt;mp_thread_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I will document the threads implementation in detail when I&amp;rsquo;m able to get MicroPython locks working.&lt;/p&gt;
&lt;h2 id=&#34;final-work&#34;&gt;final work&lt;/h2&gt;
&lt;p&gt;GSoC coding period ends on 25th August! Here&amp;rsquo;s a list of action items I am currently working towards:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;implementing MicroPython mutexes (this will help pass all or most of the threads test cases)&lt;/li&gt;
&lt;li&gt;getting the 3 failing testcases to pass, making more skipped tests pass&lt;/li&gt;
&lt;li&gt;preparing a code cleanup branch&lt;/li&gt;
&lt;li&gt;collecting project learnings and milestones for the final work product&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thank you for your time :)&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>GSoC Project Updates, Progress with MicroPython Tests</title>
      <link>https://blog.bkpt.party/posts/gsoc6/</link>
      <pubDate>Mon, 04 Aug 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc6/</guid>
      <description>&lt;p&gt;The first item we decided to focus on after the mid-term was getting the MicroPython test suite to work with the RTEMS Port. In the previous post I wrote about the test &amp;ldquo;framework&amp;rdquo; (run-tests.py) and how it works, along with features required on the MicroPython side that allow the test framework to communicate with it (a &amp;ldquo;raw&amp;rdquo; REPL, and a so-called &amp;ldquo;raw paste mode&amp;rdquo;). There was a problem with raw paste mode where MicroPython would freeze up and not send the ACKs back to the test runner that are expected in this mode. I wanted to focus on getting the tests to run first, so I decided to look into this later and commented out the lines in the &lt;code&gt;pyboard&lt;/code&gt; module that ask the device if raw paste mode is supported and flip a flag to use that mode.&lt;/p&gt;
&lt;p&gt;So I focused on making the tests pass. I have been recording the progress on that in &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/issues/1&#34;&gt;this issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is still just the &amp;ldquo;basics&amp;rdquo; tests. We currently ignore the &amp;ldquo;extmod&amp;rdquo;, &amp;ldquo;micropython&amp;rdquo; and &amp;ldquo;float&amp;rdquo; test groups because they require dependencies (probably not float, I haven&amp;rsquo;t changed these since my early trials with run-tests.py where I wanted to get at least &lt;em&gt;something&lt;/em&gt; to run, and I kept adding test groups to the &amp;ldquo;exclude&amp;rdquo; flag until I got there), like the &lt;code&gt;unittest&lt;/code&gt; module to be installed at runtime (using a tool like &lt;code&gt;mpremote&lt;/code&gt;, that once again needs Raw Paste mode).&lt;/p&gt;
&lt;p&gt;I have made steady progress and currently, 501 out of 504 executed tests (around 16119 individual testcases) pass, 46 are skipped, and 3 are failing. As guided by my mentors, I wanted to get to this point with the &amp;ldquo;basics&amp;rdquo; tests where I could no longer just enable a feature in &lt;code&gt;mpconfigport.h&lt;/code&gt; and make the test pass, and it is here (at least with the current set of excludes). Currently I am looking closely at the three failing testcases: &lt;code&gt;builtin_compile&lt;/code&gt;, &lt;code&gt;int_big_div&lt;/code&gt; and &lt;code&gt;int_big_mul&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;int_big_div&lt;/code&gt; stands out here as it &lt;em&gt;mostly&lt;/em&gt; fails. There is no random number generation in the test, here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; lhs &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;1000000000000000000000000&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10000000000100000000000000&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;10012003400000000000000007&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;12349083434598210349871029923874109871234789&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;for&lt;/span&gt; rhs &lt;span style=&#34;color:#f92672&#34;&gt;in&lt;/span&gt; range(&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;, &lt;span style=&#34;color:#ae81ff&#34;&gt;555&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        print(lhs &lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt; rhs)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# these check an edge case on 64-bit machines where two mpz limbs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# are used and the most significant one has the MSB set&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x8000000000000000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print((x &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt; x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;x &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0x86c60128feff5330&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print((x &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt; x)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# these check edge cases where borrow overflows&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print((&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;48&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;48&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;print((&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;) &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;//&lt;/span&gt; (&lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Looking at a diff of expected and logged outputs (expected ouptut on the right):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;28258772161551968764006933464242814350651                       28258772161551968764006933464242814350651
28194254416890891209751209871858698336152                       28194254416890891209751209871858698336152
281300306027294008541847448573745124991423                    | 28130030602729408541847448573745124991423
280660987149959326133432498269866133                          | 28066098714995932613343249826986613343715
28002456767796395351181473750281428279443                       28002456767796395351181473750281428279443
27939102793208620701065678560801153554829                       27939102793208620701065678560801153554829
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We see that one of the numbers seems larger than it should be, and the next one has a lot of digits missing. This might be related to the port using the &lt;code&gt;MPZ&lt;/code&gt; module as the &lt;code&gt;longint&lt;/code&gt; implementation, but I am currently not sure. I did try switching to &lt;code&gt;MICROPY_LONGINT_IMPL_LONGLONG&lt;/code&gt;, but that just causes a crash, so it is also worth looking into.&lt;/p&gt;
&lt;p&gt;I solved &lt;code&gt;builtin_compile&lt;/code&gt; after I started writing this post. That testcase uses the &lt;code&gt;__globals__&lt;/code&gt; attribute on a function object, and I didn&amp;rsquo;t have that functionality enabled. So now we have 2 failing tests: &lt;code&gt;int_big_div&lt;/code&gt; and &lt;code&gt;int_big_mul&lt;/code&gt;. I am currently trying to fix &lt;code&gt;int_big_div&lt;/code&gt; as I think it could be something related to the serial output. I did try calling &lt;code&gt;fflush&lt;/code&gt; before printing stuff to the console but that didn&amp;rsquo;t fix it. And there&amp;rsquo;s of course the fact that it randomly fails. (so we have 1.5 passing testcases? :P)&lt;/p&gt;
&lt;p&gt;I also compared the output of &lt;code&gt;int_big_mul&lt;/code&gt; to the expected output but the diff tool just highlights the whole file so that is interesting.&lt;/p&gt;
&lt;h2 id=&#34;more-passing-tests&#34;&gt;more passing tests!&lt;/h2&gt;
&lt;p&gt;I also tried &lt;em&gt;not&lt;/em&gt; ignoring the &lt;code&gt;float&lt;/code&gt; group and got 55 more tests to pass! Here&amp;rsquo;s a snippet from the end of my latest run:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./run-tests.py -t /dev/pts/2 -e &amp;#34;(extmod|micropython)/*&amp;#34;

...

559 tests performed (18668 individual testcases)
557 tests passed
55 tests skipped: async_await async_await2 async_def async_for async_for2 async_syntaxerror async_with async_with2 async_with_break async_with_return attrtuple2 builtin_help builtin_next_arg2 cexample_class cexample_module cexample_subclass class_inplace_op cmath_dunder cmath_fun cmath_fun_special exception_chain float2int_doubleprec_intbig float_divmod float_format_ints_doubleprec float_parse_doubleprec fun_code io_buffered_writer io_bytesio_cow io_bytesio_ext io_bytesio_ext2 io_iobase io_stringio1 io_stringio_base io_stringio_with io_write_ext math_constants_extra math_domain_special math_factorial_intbig math_fun_special math_isclose memoryview_slice_size nanbox_smallint print_exception rge_sm subclass_native_call subclass_native_init sys_atexit sys_exc_info sys_path sys_settrace_features sys_settrace_generator sys_settrace_loop sys_stdio sys_stdio_buffer sys_tracebacklimit
2 tests failed: int_big_div int_big_mul
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Other than the test groups I explicitly ignore, the tests that are being executed are determined by &lt;code&gt;run-tests.py&lt;/code&gt; based on the detected &amp;ldquo;minimal&amp;rdquo; (the default) configuration of the port. Before executing any tests it sends a little script to MicroPython that checks for certain features and returns a detected platform type (pre-defined). The RTEMS MicroPython port could, in the future, have its own set of test groups/individual testcases to ignore specified directly in the test runner (like the other &amp;ldquo;platforms&amp;rdquo;/ports), but the minimal configuration seems like a good set of tests for now.&lt;/p&gt;
&lt;h2 id=&#34;raw-paste-mode-now-works&#34;&gt;raw-paste mode now works&lt;/h2&gt;
&lt;p&gt;I also mentioned raw-paste mode being a problem and how I had to comment out some lines from &lt;code&gt;tools/pyboard.py&lt;/code&gt; to get the tests to run. Well now that is also fixed!&lt;/p&gt;
&lt;p&gt;I started using &lt;code&gt;write&lt;/code&gt; in my implementation of &lt;code&gt;mp_hal_stdout_tx_strn&lt;/code&gt; instead of &lt;code&gt;printf&lt;/code&gt; (I thought it was only used for printing characters to the screen but apparently it is also relevant for stuff like raw-paste mode) as using printf was leading to poorly formatted output that was making a &lt;em&gt;lot&lt;/em&gt; of tests fail in the beginning. I removed the comments in &lt;code&gt;tools/pyboard.py&lt;/code&gt; to see if the problem had changed now, but it just worked.&lt;/p&gt;
&lt;p&gt;Raw Paste mode also brings niceties like being able to use &lt;code&gt;mpremote run&lt;/code&gt; and &lt;code&gt;mpremote connect&lt;/code&gt;. We can now also start looking into what&amp;rsquo;s required to be able to install &lt;code&gt;mip&lt;/code&gt; packages to MicroPython at runtime.&lt;/p&gt;
&lt;p&gt;I am currently working on getting the remaining tests to pass and simultaneously looking into how &lt;code&gt;threads&lt;/code&gt; can be implemented. I looked at other ports&amp;rsquo; implementations of this a few weeks ago so I already have some idea of it. They are not finalized yet but &lt;code&gt;threads&lt;/code&gt; would be nice to have in the &lt;strong&gt;final deliverables&lt;/strong&gt;. Networking is also something worth looking into. There are other available modules listed at &lt;a href=&#34;https://docs.micropython.org&#34;&gt;docs.micropython.org&lt;/a&gt; that can simply be enabled, so I will be going through these and see if there&amp;rsquo;s anything there that needs implementation at the port level.&lt;/p&gt;
&lt;p&gt;Thank you for your time!&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>GSoC Project Updates, Post-Midterm</title>
      <link>https://blog.bkpt.party/posts/gsoc5/</link>
      <pubDate>Sun, 27 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc5/</guid>
      <description>&lt;p&gt;We are now past the GSoC midterm and the second phase of this project is now underway. I want to quickly share what I worked on during this first week after the midterm.&lt;/p&gt;
&lt;p&gt;The main deliverables I covered in my proposal were (we also ended up doing other things):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;MicroPython implementation (as a shell subcommand or standalone app as per discussion with mentors) - REPL and script running support.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is partially complete. &amp;ldquo;script running support&amp;rdquo; is a bit vague, but we do have an interactive shell and a raw mode (more on this later) for the same, along with imports from IMFS. The scope for this can be discussed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Full support for using RTEMS APIs through MicroPython.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Implementations of the &lt;code&gt;time&lt;/code&gt; and &lt;code&gt;machine&lt;/code&gt; modules rely directly on RTEMS APIs. The second phase will see more such modules, along with perhaps a separate &lt;code&gt;rtems&lt;/code&gt; module that could be used to perform specific system tasks. This is a point of discussion as we can&amp;rsquo;t use things like GPIO, I2C in the &lt;code&gt;pc686&lt;/code&gt; BSP that we are using for development.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Test cases for API support.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is what I have been working on this week. MicroPython has a test suite and runner (&lt;code&gt;tests/run-tests.py&lt;/code&gt;) that tests the &lt;code&gt;unix&lt;/code&gt; port by default, and can test other ports by communicating with them over a serial port.&lt;/p&gt;
&lt;h2 id=&#34;micropython-test-suite&#34;&gt;MicroPython Test Suite&lt;/h2&gt;
&lt;p&gt;MicroPython&amp;rsquo;s tests can be run for a platform (other than the default unix port) by providing a serial port to the &lt;code&gt;-t&lt;/code&gt; flag. We can make the serial output from our test application available at a pseudoterminal using:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;qemu-system-i386 --cpu core2duo -no-reboot -append &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;--console=/dev/com1&amp;#34;&lt;/span&gt; -serial chardev:char0 -chardev pty,id&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;char0,logfile&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;chardev.log,signal&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;off -kernel build/test_app.exe
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then run the test suite using (N is the pty number assigned to the output by qemu):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;./run-tests.py -t /dev/pts/N
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So this didn&amp;rsquo;t work at first, and now I&amp;rsquo;ll talk about each problem I faced.&lt;/p&gt;
&lt;h2 id=&#34;raw-repl&#34;&gt;Raw REPL&lt;/h2&gt;
&lt;p&gt;I have covered this before, but MicroPython supports a &amp;ldquo;Raw&amp;rdquo; REPL alongside the normal &amp;ldquo;friendly&amp;rdquo; REPL. There&amp;rsquo;s this problem I faced early on with serial input where calls like &lt;code&gt;fgets()&lt;/code&gt; or &lt;code&gt;getchar()&lt;/code&gt; wouldn&amp;rsquo;t block for input. I eventually figured out the required &lt;code&gt;termios&lt;/code&gt; flags and calls from &lt;code&gt;shell-wait-for-input.c&lt;/code&gt; and was able to get input working. Thing is, input is line-buffered (&lt;code&gt;ICANON&lt;/code&gt;, &amp;ldquo;canonical input&amp;rdquo; mode) so even if I send a Ctrl+A (MicroPython&amp;rsquo;s expected sequence that makes it drop into a Raw REPL), I have to send a newline after it. Sure, I can do that, but the tools won&amp;rsquo;t. They just send Ctrl+A and start listening for the Raw REPL prompt:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;raw REPL; CTRL-B to exit
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Earlier in the first phase this wasn&amp;rsquo;t a priority (the &amp;ldquo;tool&amp;rdquo; at that point was &lt;code&gt;mpremote&lt;/code&gt;, not the test runner), so we decided to spend more time on stuff like &lt;code&gt;import&lt;/code&gt;, the &lt;code&gt;time&lt;/code&gt; and &lt;code&gt;machine&lt;/code&gt; modules.&lt;/p&gt;
&lt;p&gt;I picked this up again this week and found some &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/45ae04a197362bff7af824e2710e92f3630c48ff/ports/rtems/test_app/main.c#L58-66&#34;&gt;&amp;ldquo;raw mode&amp;rdquo; flags&lt;/a&gt; from the &lt;a href=&#34;https://www.man7.org/linux/man-pages/man3/termios.3.html&#34;&gt;termios man page&lt;/a&gt;. These, along with changes to the &amp;ldquo;micropython&amp;rdquo; &lt;code&gt;readline&lt;/code&gt; implementation, allow us to instantly drop into a Raw REPL. The problem here is that the &amp;ldquo;friendly&amp;rdquo; input doesn&amp;rsquo;t work very well, in that we can&amp;rsquo;t see what we are typing. Fixing this is simple enough, we can just have an if-elseif-else chain and simply print the normal characters :D&lt;/p&gt;
&lt;p&gt;Earlier I was trying to fix everything using termios flags. I think that was a mistake.&lt;/p&gt;
&lt;p&gt;This works nicely but I have to discuss this with my mentors because a &lt;code&gt;readline&lt;/code&gt; function now needs access to internal state (a variable, &lt;code&gt;pyexec_mode_kind&lt;/code&gt; stores the currently active type of REPL) to work properly.&lt;/p&gt;
&lt;h2 id=&#34;raw-paste-mode&#34;&gt;Raw Paste Mode&lt;/h2&gt;
&lt;p&gt;With that fixed, the tool was able to send Ctrl+A and the shell would immediately change to a Raw REPL, and it was also detected, but I wasn&amp;rsquo;t seeing any characters being sent. I just saw this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.bkpt.party/images/micropython_raw_paste_mode_output.webp&#34; alt=&#34;the shell returning &amp;lsquo;R&amp;rsquo; as acknowledgement that Raw Paste mode is available&#34;&gt;&lt;/p&gt;
&lt;p&gt;That &amp;lsquo;R&amp;rsquo; at the end there means that &lt;a href=&#34;https://docs.micropython.org/en/latest/reference/repl.html#raw-mode-and-raw-paste-mode&#34;&gt;Raw Paste Mode&lt;/a&gt; is supported on the port. Raw Paste mode is a mode in the MicroPython Raw REPL where bytes are sent as a sequence of fixed-size windows, terminated by Ctrl+D. As soon as the terminator is received, the sent code (bytecode) is executed and the output is displayed. We are not supposed to see the bytecode being sent, just the output so the test runner can process it.&lt;/p&gt;
&lt;p&gt;I got the tests (well, a large subset of them) to run on the RTEMS MicroPython port by commenting out &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/master/tools/pyboard.py#L452-469&#34;&gt;these lines&lt;/a&gt; that try to use Raw Paste Mode if it is available, in the helper module &lt;code&gt;pyboard.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The output can be found &lt;a href=&#34;https://gitlab.rtems.org/-/snippets/15&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At first it seemed to randomly stop at certain test cases, i.e. the test runner would just freeze. I tried sequentially excluding those test groups as I ran into this problem until I got it to complete. This freezing issue is encountered with three test groups, specifically &amp;ldquo;extmod&amp;rdquo;, &amp;ldquo;micropython&amp;rdquo; and &amp;ldquo;float&amp;rdquo;. There&amp;rsquo;s quite a lot of test groups besides these that amount to 452 testcases. Out of these, the RTEMS MicroPython port passes 250 tests. There are cases that are skipped automatically because there are no &amp;ldquo;settings&amp;rdquo; right now for the RTEMS port in the test runner. It is an unidentified port and the test runner uses the &amp;ldquo;minimal&amp;rdquo; test configuration, skipping a lot of tests. Many that fail could also be irrelevant to the current scope of the port. Overall, the test runner needs an &amp;ldquo;RTEMS&amp;rdquo; configuration that, like the other ports, will specifically exclude some tests and include special tests for this port.&lt;/p&gt;
&lt;p&gt;Other than that, the freezing issue- I haven&amp;rsquo;t been able to fix it yet, but a possible reason could be that the test case code being transmitted is longer than the size of some internal buffer which rolls over by default, so MicroPython is just waiting for more input, while the test runner is waiting for the output. This would also explain the need for a fixed-window transfer mode. Even in the friendly REPL, the input buffer size is only 32 bytes, so my test programs have to be very short.&lt;/p&gt;
&lt;p&gt;So, a big task up ahead would be to get this Raw Paste mode working so we can run all the test cases and then start working on filtering them out and enabling/implementing more features.&lt;/p&gt;
&lt;p&gt;Thank you for your time!&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>I made a RISC-V SoC!</title>
      <link>https://blog.bkpt.party/posts/rv32i/</link>
      <pubDate>Fri, 18 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/rv32i/</guid>
      <description>&lt;div style=&#34;padding:75% 0 0 0;position:relative;&#34;&gt;&lt;iframe src=&#34;https://player.vimeo.com/video/1102650923?badge=0&amp;amp;autopause=0&amp;amp;player_id=0&amp;amp;app_id=58479&#34; frameborder=&#34;0&#34; allow=&#34;autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share&#34; referrerpolicy=&#34;strict-origin-when-cross-origin&#34; style=&#34;position:absolute;top:0;left:0;width:100%;height:100%;&#34; title=&#34;cpu_demo&#34;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;script src=&#34;https://player.vimeo.com/api/player.js&#34;&gt;&lt;/script&gt;
&lt;p&gt;I recently finished building a RISC-V RV32I core on my GOWIN GW1NR-9 based FPGA (here&amp;rsquo;s the &lt;a href=&#34;https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-9K/Nano-9K.html&#34;&gt;exact board&lt;/a&gt;). This was my second attempt ever at implementing some sort of instruction set. First was a &lt;a href=&#34;https://en.wikipedia.org/wiki/CHIP-8&#34;&gt;CHIP-8&lt;/a&gt; emulator I wrote in Python.&lt;/p&gt;
&lt;p&gt;I want to document the features of the SoC here as I keep working on it and adding new stuff.&lt;/p&gt;
&lt;p&gt;Current Hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU Core implementing the 32-bit Base Integer instruction set (RV32I)&lt;/li&gt;
&lt;li&gt;Memory-mapped UART TX, RX&lt;/li&gt;
&lt;li&gt;6 onboard memory-mapped LEDs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Current Software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;super minimal C library with &lt;code&gt;getc&lt;/code&gt;, &lt;code&gt;getchar&lt;/code&gt;, &lt;code&gt;putchar&lt;/code&gt; implemented in RISC-V assembler using the &lt;code&gt;ilp32&lt;/code&gt; ABI&lt;/li&gt;
&lt;li&gt;headers with &lt;code&gt;#define&lt;/code&gt;s for the memory map&lt;/li&gt;
&lt;li&gt;working on a &lt;code&gt;no-std&lt;/code&gt; Rust example&lt;/li&gt;
&lt;li&gt;looking at &lt;a href=&#34;https://github.com/picolibc/picolibc&#34;&gt;picolibc&lt;/a&gt; as a candidate for a standard library&lt;/li&gt;
&lt;li&gt;working on an SPI peripheral for external Flash+RAM&lt;/li&gt;
&lt;li&gt;looking at adding a Wishbone or AXI bus for easier integration of pre-built open-source peripherals into the SoC&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fun tools I learned about while building this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/YosysHQ/yosys&#34;&gt;yosys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/YosysHQ/nextpnr&#34;&gt;nextpnr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/YosysHQ/apicula&#34;&gt;Project Apicula&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some related links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Verilog: &lt;a href=&#34;https://hdlbits.01xz.net/wiki/Main_Page&#34;&gt;HDLBits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/riscv-collab/riscv-gnu-toolchain&#34;&gt;riscv-gnu-toolchain&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Open-Source RISC-V: &lt;a href=&#34;https://github.com/Wren6991/Hazard3&#34;&gt;Hazard3&lt;/a&gt;, &lt;a href=&#34;https://github.com/olofk/serv&#34;&gt;SERV&lt;/a&gt;, &lt;a href=&#34;https://github.com/BrunoLevy/learn-fpga/&#34;&gt;Bruno Levy&amp;rsquo;s LearnFPGA Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://riscv.org/specifications/ratified/&#34;&gt;RISC-V Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    
    
    <item>
      <title>GSoC Project Updates, Mid-Term</title>
      <link>https://blog.bkpt.party/posts/gsoc4/</link>
      <pubDate>Tue, 15 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc4/</guid>
      <description>&lt;p&gt;I have completed work on all the mid-term deliverables that I finalized with my mentors and wanted to make a quick summary of the work done so far in this post.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the list of deliverables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Getting Serial input to work&lt;/li&gt;
&lt;li&gt;Working on an RSB Recipe&lt;/li&gt;
&lt;li&gt;Implementing &lt;code&gt;time&lt;/code&gt;, &lt;code&gt;random&lt;/code&gt; and &lt;code&gt;machine&lt;/code&gt; to be able to get uptime, reset the machine&lt;/li&gt;
&lt;li&gt;Getting floating point values to work on the pc686 BSP&lt;/li&gt;
&lt;li&gt;Working on an initial version of Imports (.py files mounted in QEMU)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main branch right now is &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/tree/port-files&#34;&gt;port-files&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;serial-input&#34;&gt;Serial Input&lt;/h2&gt;
&lt;p&gt;This was one of the first things I worked on. We launch the built &amp;ldquo;test_app&amp;rdquo; executable using:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;qemu-system-i386 \
    --cpu core2duo \
    -append &amp;#34;--console=/dev/com1&amp;#34; \
    -serial stdio \
    -kernel build/test_app.exe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem was that &lt;code&gt;fgets&lt;/code&gt; or &lt;code&gt;getc&lt;/code&gt; wouldn&amp;rsquo;t block. I looked in the the fileio sample (it takes user input after presenting a menu), and eventually found some &lt;code&gt;termios&lt;/code&gt; flags that are set when &lt;code&gt;rtems_shell_wait_for_input&lt;/code&gt; is called that set the terminal up for user input. The example application currently just has a call to this RTEMS shell function that properly sets up input for us:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;rtems_shell_wait_for_input&lt;/span&gt;(STDIN_FILENO, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, NULL, NULL);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I have identified the &lt;code&gt;termios&lt;/code&gt; flags that this function uses but I use this &amp;ldquo;hack&amp;rdquo; right now because of the reasons discussed below.&lt;/p&gt;
&lt;p&gt;Some more context on this is around the &lt;a href=&#34;https://docs.micropython.org/en/latest/reference/mpremote.html&#34;&gt;mpremote tool&lt;/a&gt;. The tool can be used to interface with MicroPython installations over serial or network. We tried it with the RTEMS Port by redirecting QEMU&amp;rsquo;s serial device to a new pseudoterminal using &lt;code&gt;-serial chardev:char0 -chardev pty,id=char0&lt;/code&gt; and observed that &lt;code&gt;mpremote&lt;/code&gt; sends &lt;code&gt;CTRL+A&lt;/code&gt; to make the default &amp;ldquo;friendly REPL&amp;rdquo; drop into a &amp;ldquo;raw REPL&amp;rdquo;. The CTRL+A (along with other codes) handling is present in MicroPython&amp;rsquo;s &lt;code&gt;pyexec_friendly_repl&lt;/code&gt; implementation that we use. I made some progress with this and identified two sets of &lt;code&gt;termios&lt;/code&gt; flags where each lets us use either the friendly REPL or the Raw REPL properly. The goal is to have a set of flags that allow us to easily use both, or just be able to switch to the Raw REPL immediately after sending &lt;code&gt;CTRL+A&lt;/code&gt; (which mpremote expects to happen) and the having some logic to change terminal settings. More info on the exact flags I tried can be found in my &lt;a href=&#34;https://lzrd.codeberg.page/blog/gsoc-project-updates-week-five.html&#34;&gt;Week 5 Blog Post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My mentors decided that getting &lt;code&gt;mpremote&lt;/code&gt; to work is not a priority for now so I&amp;rsquo;ll pick the work-in-progress code up later from the &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/commit/6a45afe32f93f558be257a63acdc6340db267d0a&#34;&gt;termios_experiments&lt;/a&gt; branch. When we have working code for this, I&amp;rsquo;ll replace the &amp;ldquo;hack&amp;rdquo; call to &lt;code&gt;rtems_shell_wait_for_input&lt;/code&gt; in the test application&amp;rsquo;s main function with &lt;code&gt;termios&lt;/code&gt; code.&lt;/p&gt;
&lt;h2 id=&#34;rsb-recipe&#34;&gt;RSB Recipe&lt;/h2&gt;
&lt;p&gt;As per the discussions with my mentors, I&amp;rsquo;m only responsible for half of this - a Makefile that can build the port as a library, &lt;code&gt;libmicropython.a&lt;/code&gt; and the test application &lt;code&gt;test_app.exe&lt;/code&gt; that demonstrates available features. This was decided because my mentors suggested that learning the RSB would take up too much time. Here are the currently defined make targets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;(default)&lt;/strong&gt;: builds libmicropython.a&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;build/pytest.tar&lt;/strong&gt;: archives &lt;code&gt;test/test.py&lt;/code&gt; into &lt;code&gt;build/pytest.tar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;build/pytest.c&lt;/strong&gt;: converts &lt;code&gt;build/pytest.tar&lt;/code&gt; to &lt;code&gt;build/pytest.c&lt;/code&gt; and &lt;code&gt;build/pytest.h&lt;/code&gt;, allowing the &lt;code&gt;test&lt;/code&gt; module to be imported at runtime using MicroPython&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;test_app&lt;/strong&gt;: builds &lt;code&gt;test_app.exe&lt;/code&gt; using &lt;code&gt;libmicropython.a&lt;/code&gt;, &lt;code&gt;test/init.c&lt;/code&gt; and &lt;code&gt;test/main.c&lt;/code&gt;&lt;br&gt;
I&amp;rsquo;m waiting for Chris, one of my mentors, to write an RSB Recipe using this, so we should have one soon. I talked about the build system progress in my &lt;a href=&#34;https://lzrd.codeberg.page/blog/gsoc-project-updates-week-four.html&#34;&gt;week 4&lt;/a&gt; and &lt;a href=&#34;https://lzrd.codeberg.page/blog/gsoc-project-updates-week-five.html&#34;&gt;week 5&lt;/a&gt; blog posts.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;time-random-and-machine-modules&#34;&gt;time, random and machine modules&lt;/h2&gt;
&lt;p&gt;I have been able to get all three modules listed in the last mid-term deliverable working. &lt;code&gt;time&lt;/code&gt; and &lt;code&gt;random&lt;/code&gt; are fully supported and I&amp;rsquo;m looking for feedback on their implementation. &lt;code&gt;machine&lt;/code&gt; has many classes like &lt;code&gt;Pin&lt;/code&gt;, &lt;code&gt;I2S&lt;/code&gt;, &lt;code&gt;PWM&lt;/code&gt;, etc. that I can&amp;rsquo;t enable right now because we are using the pc686 BSP with QEMU. So currently the only implemented &lt;code&gt;machine&lt;/code&gt; functions are &lt;code&gt;reset&lt;/code&gt; and &lt;code&gt;soft_reset&lt;/code&gt; (which was the goal) along with 8, 16 or 32 byte read/write access to memory, making up its basic functionality outside of those protocols and GPIO.&lt;/p&gt;
&lt;p&gt;Reference for MicroPython libraries can be found &lt;a href=&#34;https://docs.micropython.org/en/latest/library/index.html&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Implemented features for each module:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;random&lt;/code&gt;&lt;/strong&gt;: all functions available after simply enabling the module&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;time&lt;/code&gt;&lt;/strong&gt;: all functions implemented&lt;br&gt;
- &lt;code&gt;sleep(N)&lt;/code&gt;: sleep for &lt;code&gt;N&lt;/code&gt; seconds&lt;br&gt;
- &lt;code&gt;sleep_ms(N)&lt;/code&gt;: sleep for &lt;code&gt;N&lt;/code&gt; milliseconds&lt;br&gt;
- &lt;code&gt;sleep_us(N)&lt;/code&gt;: sleep for &lt;code&gt;N&lt;/code&gt; microseconds&lt;br&gt;
- &lt;code&gt;time()&lt;/code&gt;: Returns the number of seconds, as an integer, since the Epoch (defined by the port, boot time here)&lt;br&gt;
- all &lt;a href=&#34;https://docs.micropython.org/en/latest/library/time.html#time.ticks_ms&#34;&gt;&amp;ldquo;ticks&amp;rdquo;&lt;/a&gt; functions: &lt;code&gt;ticks_cpu()&lt;/code&gt;, &lt;code&gt;ticks_ms()&lt;/code&gt;, &lt;code&gt;ticks_us()&lt;/code&gt;, &lt;code&gt;ticks_add()&lt;/code&gt;, &lt;code&gt;ticks_diff()&lt;/code&gt;, with RTEMS MICROSECONDS_PER_TICK set to 1000&lt;br&gt;
- bug: &lt;code&gt;time_ns()&lt;/code&gt; leads to an &amp;ldquo;OverflowError: small int overflow&amp;rdquo;. Currently looking into this&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;machine&lt;/code&gt;&lt;/strong&gt;:&lt;br&gt;
- &lt;code&gt;mem8&lt;/code&gt;, &lt;code&gt;mem16&lt;/code&gt;, &lt;code&gt;mem32&lt;/code&gt;: allow direct memory access&lt;br&gt;
- &lt;code&gt;reset()&lt;/code&gt;: hard resets the machine using &lt;code&gt;bsp_reset()&lt;/code&gt;&lt;br&gt;
- &lt;code&gt;soft_reset()&lt;/code&gt;: breaks out of &lt;code&gt;pyexec_friendly_repl&lt;/code&gt; (or &lt;code&gt;pyexec_raw_repl&lt;/code&gt; in the future), cleans up all the heap objects and runs into a &lt;code&gt;goto&lt;/code&gt; that restarts everything&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;remaining in &lt;code&gt;machine&lt;/code&gt;:&lt;br&gt;
- &lt;code&gt;reset_cause()&lt;/code&gt;: returns the cause of reset. A list can be found &lt;a href=&#34;https://docs.micropython.org/en/latest/library/machine.html#machine.machine.PWRON_RESET&#34;&gt;here&lt;/a&gt;&lt;br&gt;
- &lt;code&gt;bootloader()&lt;/code&gt;: used to put the device in a state where it can be upgraded to a new firmware&lt;br&gt;
- &lt;a href=&#34;https://docs.micropython.org/en/latest/library/machine.html#interrupt-related-functions&#34;&gt;interrupt related&lt;/a&gt; and &lt;a href=&#34;https://docs.micropython.org/en/latest/library/machine.html#power-related-functions&#34;&gt;power related&lt;/a&gt; functions&lt;br&gt;
- classes for various peripherals like &lt;code&gt;machine.Pin&lt;/code&gt; for GPIO, &lt;code&gt;machine.I2C&lt;/code&gt;, &lt;code&gt;machine.I2S&lt;/code&gt;, etc. Potential candidates for implementation on the current pc686 BSP are &lt;code&gt;Timer&lt;/code&gt; and &lt;code&gt;WDT&lt;/code&gt; (watchdog timer).&lt;/p&gt;
&lt;p&gt;I had to implement the following functions to get these to work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mp_obj_t mp_time_time_get(void)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uint64_t mp_hal_time_ns(void)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void mp_hal_delay_ms(uint64_t delay)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;void mp_hal_delay_us(uint64_t delay)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uint64_t mp_hal_ticks_cpu(void)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uint64_t mp_hal_ticks_ms(void)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;uint64_t mp_hal_ticks_us(void)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I also recorded some demos using &lt;code&gt;asciinema&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://asciinema.org/a/9zPIQ6nqAY3hLwr6VYskpF9fk&#34;&gt;time module demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://asciinema.org/a/LLSlPhFSj2uHDy6SqE8La7Gse&#34;&gt;machine module demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I started this work in the &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/tree/modules&#34;&gt;modules&lt;/a&gt; branch and it has been merged into &lt;code&gt;port-files&lt;/code&gt; and there have been some rebases related to the time module.&lt;/p&gt;
&lt;h2 id=&#34;floating-point&#34;&gt;Floating Point&lt;/h2&gt;
&lt;p&gt;This turned out to be easier than expected. I only had to define &lt;code&gt;MICROPY_FLOAT_IMPL&lt;/code&gt; in &lt;code&gt;mpconfigport.h&lt;/code&gt; and enable floats on the BSP using &lt;code&gt;CONFIGURE_RTEMS_FLOATING_POINT&lt;/code&gt;. I learned that i386 doesn&amp;rsquo;t have floats by default and needs a separate &amp;ldquo;i387&amp;rdquo; chip for floating point functionality. I wrote about this in my &lt;a href=&#34;https://lzrd.codeberg.page/blog/gsoc-project-updates-week-five.html&#34;&gt;week 5&lt;/a&gt; blog post.&lt;/p&gt;
&lt;h2 id=&#34;an-initial-version-of-imports&#34;&gt;An Initial Version of Imports&lt;/h2&gt;
&lt;p&gt;We now also have an IMFS based imports system. The previously mentioned &lt;code&gt;pytest.c&lt;/code&gt;, &lt;code&gt;pytest.h&lt;/code&gt; are compiled along with the test application and &lt;code&gt;rtems_tarfs_load&lt;/code&gt; is used to load that at &amp;ldquo;/&amp;rdquo;. I implemented &lt;code&gt;mp_import_stat&lt;/code&gt; as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;mp_import_stat_t&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mp_import_stat&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;const&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;path) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; file_path[&lt;span style=&#34;color:#ae81ff&#34;&gt;256&lt;/span&gt;] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; { &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;sprintf&lt;/span&gt;(file_path, &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/%s&amp;#34;&lt;/span&gt;, path);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;struct&lt;/span&gt; stat file_info;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; ret &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;stat&lt;/span&gt;(file_path, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;file_info);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (ret &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; MP_IMPORT_STAT_NO_EXIST;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (file_info.st_mode &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; S_IFDIR) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; MP_IMPORT_STAT_DIR;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (file_info.st_mode &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt; S_IFREG) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; MP_IMPORT_STAT_FILE;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I recorded a demo for this too: &lt;a href=&#34;https://asciinema.org/a/CsFHVCaRNVbqIHb7CP0tdG37B&#34;&gt;imports demo&lt;/a&gt;. Here&amp;rsquo;s the related &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/commit/a842c904cb8419653bfb87947cb5b7241b72a499&#34;&gt;commit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Makefile could later be modified to make a tar archive of not just one file, but many in a &lt;code&gt;test/modules&lt;/code&gt; directory that we can then import at runtime.&lt;/p&gt;
&lt;p&gt;This completes all of the planned mid-term goals. I am currently working on the &lt;code&gt;time_ns()&lt;/code&gt; overflow bug and making changes as per my mentors&amp;rsquo; feedback, which has so far included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;moving the &lt;code&gt;mp_hal_delay_ms&lt;/code&gt; implementation away from &lt;code&gt;rtems_task_wake_after&lt;/code&gt;, to &lt;code&gt;nanosleep&lt;/code&gt; (by switching the example from classic RTEMS Tasks to POSIX)&lt;/li&gt;
&lt;li&gt;using &lt;code&gt;bsp_reset&lt;/code&gt; in &lt;code&gt;machine.reset&lt;/code&gt; instead of the call to &lt;code&gt;rtems_shutdown_executive&lt;/code&gt; I was using earlier&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will continue to work on these small changes this week and discuss next steps and the post-midterm plan with my mentors. GSoC has been an amazing experience so far and I&amp;rsquo;m excited for the second phase of this project.&lt;/p&gt;
&lt;p&gt;Thank you for your time!&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>GSoC Project Updates, Week Five</title>
      <link>https://blog.bkpt.party/posts/gsoc3/</link>
      <pubDate>Fri, 04 Jul 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc3/</guid>
      <description>&lt;p&gt;We finally have a Makefile that can generate object files for MicroPython core, along with &lt;code&gt;mphalport.c&lt;/code&gt; (the file that uses RTEMS APIs to actually &amp;ldquo;port&amp;rdquo; MicroPython). It can also generate an archive &lt;code&gt;libmicropython.a&lt;/code&gt; using the pre-defined &lt;code&gt;lib&lt;/code&gt; target.&lt;/p&gt;
&lt;p&gt;In this post I want to talk about the things I learned about Make (GNU Make specifically), ABIs and why using the correct CFLAGS and LDFLAGS is &lt;em&gt;very&lt;/em&gt; important. We also have a &lt;code&gt;test_app&lt;/code&gt; directory now in the port (along with a Make target, creatively named &amp;ldquo;test_app&amp;rdquo; to build it) to demonstrate linking an RTEMS application with libmicropython, the application in this case being a simple demo that outputs the so-called &amp;ldquo;friendly REPL&amp;rdquo;. I also want to cover what I&amp;rsquo;m currently doing now that we have a stable Makefile, which brings us very close to the completion of the second mid-term deliverable, i.e., an RSB Recipe.&lt;/p&gt;
&lt;h2 id=&#34;makefile&#34;&gt;Makefile&lt;/h2&gt;
&lt;p&gt;The build process earlier was something like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;use MicroPython&amp;rsquo;s Makefile based build system to build core platform-independent objects (based on enabled features in &lt;code&gt;mpconfigport.h&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;use RTEMS&amp;rsquo; Waf based build system to build &lt;code&gt;mphalport.c&lt;/code&gt; along with a test application (&lt;code&gt;init.c&lt;/code&gt;, &lt;code&gt;main.c&lt;/code&gt;) and link everything together.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We don&amp;rsquo;t really want to have any Waf stuff in MicroPython and the ideal way to build the &lt;em&gt;library&lt;/em&gt; should be using purely Makefiles. Enter, &lt;code&gt;pkgconf&lt;/code&gt; / &lt;code&gt;pkg-config&lt;/code&gt;. The Man page describes it as &amp;ldquo;a system for configuring build dependency information&amp;rdquo;, and RTEMS supports it. Package config allows RTEMS BSPs to create &lt;code&gt;.pc&lt;/code&gt; file in a set location that we can then use with the &lt;code&gt;pkg-config&lt;/code&gt; command like so:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;pkg-config --with-path=/path/to/rtems-workspace/rtems/7/lib/pkgconfig --cflags i386-rtems7-pc686
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This simply outputs the &lt;code&gt;Cflags&lt;/code&gt; described in the &lt;code&gt;i386-rtems7-pc686.pc&lt;/code&gt; file at the provided path. CFLAGS are simply additional switches that are supplied to a C compiler. Part of this information is &lt;code&gt;ABI_FLAGS=-mtune=pentiumpro -march=pentium&lt;/code&gt;. The ABI, or Application Binary Interface is a specification that sits directly on top of the ISA. It standardizes aspects like register usage and calling conventions. We need to ensure that we consistently use the correct ABI flags because mixing different ABIs can lead to undefined behavior.&lt;/p&gt;
&lt;p&gt;Similarly, we can pass &lt;code&gt;--libs&lt;/code&gt; to the above command to print the required linker flags. We can append these and the Cflags to the as &lt;code&gt;RTEMS_TARGET_CLFAGS&lt;/code&gt; and &lt;code&gt;RTEMS_TARGET_LDFLAGS&lt;/code&gt; to the already defined &lt;code&gt;CFLAGS&lt;/code&gt; and &lt;code&gt;LDFLAGS&lt;/code&gt; in the MicroPython Makefile.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s where the Makefile fun began. I have been using Makefiles in a limited manner for a long time now. I use one to generate this blog! It&amp;rsquo;s rather simple, with targets to fetch dependencies like the Tailwind compiler (this is a static site but I just prefer tailwind CSS). More about the blog Makefile some other time.&lt;/p&gt;
&lt;p&gt;We ended up just needing to pass three variables to the &lt;code&gt;make&lt;/code&gt; command to allow it to build &lt;code&gt;libmicropython.a&lt;/code&gt;, regardless of the BSP: &lt;code&gt;RTEMS_PREFIX&lt;/code&gt;, &lt;code&gt;RTEMS_VERSION&lt;/code&gt; and &lt;code&gt;RTEMS_BSP&lt;/code&gt;. We already know that pkgconfig files are present in &lt;code&gt;RTEMS_PREFIX/lib/pkgconfig&lt;/code&gt;. The format of &lt;code&gt;RTEMS_BSP&lt;/code&gt; is &amp;ldquo;arch/bsp&amp;rdquo;, so we use the &lt;code&gt;subst&lt;/code&gt; and &lt;code&gt;word&lt;/code&gt; commands provided by Make to extract &lt;code&gt;RTEMS_ARCH&lt;/code&gt; and &lt;code&gt;RTEMS_TARGET&lt;/code&gt; from this string. We use the &lt;code&gt;shell&lt;/code&gt; command to assign the output of the &lt;code&gt;pkg-config&lt;/code&gt; commands to &lt;code&gt;RTEMS_TARGET_CFLAGS&lt;/code&gt; and &lt;code&gt;RTEMS_TARGET_LDFLAGS&lt;/code&gt;. Here&amp;rsquo;s the relevant section from the Makefile:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-make&#34; data-lang=&#34;make&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_ARCH &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;word 1, &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;subst /, ,&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_BSP&lt;span style=&#34;color:#66d9ef&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_TARGET &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;word 2, &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;subst /, ,&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_BSP&lt;span style=&#34;color:#66d9ef&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_PKGCONFIG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_PREFIX&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;/lib/pkgconfig/
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_PKGCONFIG_PKG &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_ARCH&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;-rtems&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_VERSION&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;-&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_TARGET&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;CROSS_COMPILE &lt;span style=&#34;color:#f92672&#34;&gt;?=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_ARCH&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;-rtems&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_VERSION&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# ... skipped some lines ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_TARGET_CFLAGS &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;shell pkg-config --with-path&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_PKGCONFIG&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; --cflags &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_PKGCONFIG_PKG&lt;span style=&#34;color:#66d9ef&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RTEMS_TARGET_LDFLAGS &lt;span style=&#34;color:#f92672&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;shell pkg-config --with-path&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_PKGCONFIG&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; --libs &lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;RTEMS_PKGCONFIG_PKG&lt;span style=&#34;color:#66d9ef&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We also use the extracted &lt;code&gt;RTEMS_ARCH&lt;/code&gt; and &lt;code&gt;RTEMS_TARGET&lt;/code&gt; to create the tools prefix, &amp;ldquo;i386-rtems7-&amp;rdquo; in this case.&lt;br&gt;
Here&amp;rsquo;s a &lt;a href=&#34;https://makefiletutorial.com/&#34;&gt;resource&lt;/a&gt; I found very helpful in learning more about Makefiles.&lt;/p&gt;
&lt;p&gt;That is pretty much it. We can now run&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;RTEMS_PREFIX=~/rtems-workspace/rtems/7 RTEMS_VERSION=7 RTEMS_BSP=i386/pc686 make
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and it creates &lt;code&gt;build/libmicropython.a&lt;/code&gt; that we can link against. I also added a &lt;code&gt;test_app&lt;/code&gt; directory with an &lt;code&gt;init.c&lt;/code&gt; and &lt;code&gt;main.c&lt;/code&gt; with an example application demonstrating how we can use MicroPython. We can build it using the Make target &amp;ldquo;test_app&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;One of my mentors suggested that learning the RSB would take up a significant chunk of time and it would be better if I worked on getting a Makefile that builds a library, and then he could step in to write the final RSB Recipe that will allow applications to very easily build the library and use it. I think the current Makefile can be used for that and we should be able to reach that &lt;strong&gt;milestone&lt;/strong&gt; within the first half of next week whenever my mentor gets time to work on the Recipe.&lt;/p&gt;
&lt;h2 id=&#34;serial-input-fun&#34;&gt;Serial Input Fun&lt;/h2&gt;
&lt;p&gt;So we have serial input (first mid-term deliverable) working already, and the second one (RSB Recipe) should be done soon. My mentors suggested that we focus on the Makefile first because as I mentioned earlier, undefined behavior, and they highlighted that it is very much possible that we were having problems with serial input (before the hack) because of incorrect ABI flags. Now that we&amp;rsquo;re using them, I was able to confirm that the problem doesn&amp;rsquo;t go away with the new Makefile, so we were back to figuring out a cleaner way to set up input than calling some random function like &lt;code&gt;rtems_shell_wait_for_input&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So I looked into the implementation of this function and found the &lt;code&gt;termios&lt;/code&gt; flags responsible for properly setting up the terminal for user input &lt;a href=&#34;https://gitlab.rtems.org/rtems/rtos/rtems/-/blob/main/cpukit/libmisc/shell/shell-wait-for-input.c#L50-53&#34;&gt;here&lt;/a&gt;. We see these flags being set here:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_iflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;(IGNBRK &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; BRKINT &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; PARMRK &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ISTRIP &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; INLCR &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; IGNCR &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ICRNL &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; IXON);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_lflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;(ECHO &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ECHONL &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ICANON &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; ISIG &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; IEXTEN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_cflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;(CSIZE &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; PARENB);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_cflag &lt;span style=&#34;color:#f92672&#34;&gt;|=&lt;/span&gt; CS8;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_cc [VMIN] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;new_term.c_cc [VTIME] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;10&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rv &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;tcsetattr&lt;/span&gt;(fd, TCSANOW, &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;&lt;/span&gt;new_term);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can have a function in our test application (remember that for now this is just an application on i386 available over a serial console. On other BSPs this would be a UART or Network).&lt;/p&gt;
&lt;p&gt;We have been trying to get the &lt;a href=&#34;https://docs.micropython.org/en/latest/reference/mpremote.html&#34;&gt;mpremote&lt;/a&gt; tool to work with this port. We can expose the console over a pty by passing the relevant flags to Qemu:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;qemu-system-i386 --cpu core2duo -no-reboot -append &amp;#34;--console=/dev/com1&amp;#34; -serial chardev:char0 -chardev pty,id=char0,logfile=chardev.log -kernel build/test_app.exe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;and then we can use (pty number is assigned after running the above command)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mpremote connect /dev/pts/2 run ./hello_world.py
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to execute scripts on the port (exciting!), but this is what I&amp;rsquo;m currently facing problems with. Getting &lt;code&gt;mpremote&lt;/code&gt; to work is not a mid-term deliverable but my mentor mentioned during one of our meetings that it would be nice to have, so I tried to set it up today.&lt;/p&gt;
&lt;p&gt;I looked through the &lt;a href=&#34;https://www.man7.org/linux/man-pages/man3/termios.3.html&#34;&gt;termios Man page&lt;/a&gt; and saw what these flags did, tried various others, but currently it&amp;rsquo;s stuck here (with the above flags):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;MicroPython v1.26.0-preview.133.g4739a06d5.dirty on 2025-07-05; rtems-i386/pc686 with unknown-cpu
&amp;gt;&amp;gt;&amp;gt; 
&amp;gt;&amp;gt;&amp;gt; 
&amp;gt;&amp;gt;&amp;gt; ^A
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Ctrl-A is supposed to drop MicroPython into a &amp;ldquo;Raw REPL&amp;rdquo;. mpremote sends Ctrl-A and then has some logic that detects if we are indeed in a Raw REPL, sends the script as a string line-by-line, and then sends Ctrl-D to exit back into the normal REPL (the so-called &amp;ldquo;friendly&amp;rdquo; REPL). The Ctrl-A above is sent by mpremote, but with those termios flags, we have to add a newline for it to process Ctrl-A.&lt;/p&gt;
&lt;p&gt;I can disable &amp;ldquo;Canonical Mode&amp;rdquo; on the console to disable line buffering and also set the VTIME to 0 to instantly get the entered characters, but that leaves this in a state where the REPL switches to the Raw REPL the instant I press Ctrl-A, and back to the friendly REPL when I press Ctrl-B, but I cannot input text into either of them, and this is the behavior I see with mpremote as well. It sends Ctrl-A, probably sends the &amp;ldquo;print(&amp;lsquo;hello&amp;rsquo;)&amp;rdquo; inside &lt;code&gt;hello.py&lt;/code&gt;, sends Ctrl-D, but errors out because it doesn&amp;rsquo;t get any output, and I also don&amp;rsquo;t see anything in the log beyond the REPL switching to Raw mode and exiting it and printing &amp;ldquo;OK&amp;rdquo;. These are the flags that give me this behavior:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_iflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;(IGNBRK&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;BRKINT&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;PARMRK&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ISTRIP&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;INLCR&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;IGNCR&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ICRNL&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;IXON);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_oflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;OPOST;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_oflag &lt;span style=&#34;color:#f92672&#34;&gt;|=&lt;/span&gt; ONLCR; &lt;span style=&#34;color:#75715e&#34;&gt;/* But with cr+nl on output */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_lflag &lt;span style=&#34;color:#f92672&#34;&gt;&amp;amp;=&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;~&lt;/span&gt;(ECHO&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ECHONL&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ICANON&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;ISIG&lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt;IEXTEN);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_cflag &lt;span style=&#34;color:#f92672&#34;&gt;|=&lt;/span&gt; CLOCAL &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; CREAD;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_cc[VMIN]  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;term.c_cc[VTIME] &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;floating-point&#34;&gt;Floating Point&lt;/h2&gt;
&lt;p&gt;I also got the 4th deliverable done! This was expectedly very simple to do. MicroPython allows us to enable floats at build time by defining:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_FLOAT_IMPL                      (MICROPY_FLOAT_IMPL_FLOAT)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To build the &lt;code&gt;test_app&lt;/code&gt; we also need to link it with the math library by adding &lt;code&gt;-lm&lt;/code&gt; to our gcc command. This was giving me link-time errors regarding missing symbols &lt;code&gt;powf&lt;/code&gt;, &lt;code&gt;floorf&lt;/code&gt;, etc. (i.e., floating point versions of math library functions).&lt;/p&gt;
&lt;p&gt;I found out that the the i386 architecture (the Intel 80386 microprocessor) didn&amp;rsquo;t originally have an FPU (Floating-Point Unit), and that functionality existed as separate hardware in the form of the i387 chip. So I thought that this target in RTEMS didn&amp;rsquo;t have floats and I would have to use another BSP, which would not have been ideal as it would be nice to get everything working on one BSP first. I got some help on Discord regarding this, and turns out the only thing I was missing was a simple line of configuration in the test application&amp;rsquo;s &lt;code&gt;init.c&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define CONFIGURE_RTEMS_FLOATING_POINT
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The application built cleanly and I was able to use floating-point values in MicroPython.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;So Serial Input is done (&lt;code&gt;mpremote&lt;/code&gt; is still a work-in-progress but getting it to work is more of a configuration thing that can vary widely across BSPs), we are very close to an RSB Recipe for MicroPython, and I also got floating-point values working. The remaining mid-term deliverables are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementing &lt;code&gt;time&lt;/code&gt;, &lt;code&gt;random&lt;/code&gt; and &lt;code&gt;machine&lt;/code&gt; to be able to get uptime, reset the machine&lt;/li&gt;
&lt;li&gt;Working on an initial version of Imports (.py files mounted in QEMU)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am currently looking through the RTEMS Documentation to try and implement &lt;code&gt;time&lt;/code&gt; so we can have functionality like &lt;code&gt;sleep_ms&lt;/code&gt;, &lt;code&gt;uptime&lt;/code&gt;, etc. The idea behind implementing these modules, as I discussed with my mentors, was that these should be mostly BSP agnostic and will provide us some surface area to build the BSP-specific configuration upon, and I&amp;rsquo;m hoping this will help us with that.&lt;/p&gt;
&lt;p&gt;Imports were suggested by a mentor because this BSP has a nice feature where we can pass a directory to Qemu and there&amp;rsquo;s a driver that can be enabled that will create a virtual filesystem with the files in that directory. I have seen other ports&amp;rsquo; &lt;code&gt;mpconfigport.h&lt;/code&gt; files containing &lt;code&gt;MICROPY_VFS&lt;/code&gt; and seems like that is something they define a standard interface for just like with &lt;code&gt;mp_hal_stdout_tx_strn&lt;/code&gt; and &lt;code&gt;mp_hal_stdin_rx_chr&lt;/code&gt;. I will share more updates on this in the next blog post :)&lt;/p&gt;
&lt;p&gt;Thank you for your time!&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>GSoC Project Updates, Week Four</title>
      <link>https://blog.bkpt.party/posts/gsoc2/</link>
      <pubDate>Mon, 23 Jun 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc2/</guid>
      <description>&lt;p&gt;We are about to enter the 4th week of GSoC, and my project is definitely starting to take shape! I couldn&amp;rsquo;t post updates here because I had my third year end-term exams from May 29th to June 20th. Future GSoC contributors should note that this sort of thing is not a problem, given that you discuss this with your potential mentors during the Application Period and mention it in your proposal.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t stop completely, though. I continued to participate in the weekly Organization meeting to share progress and the one I&amp;rsquo;ve set up with my mentors for project discussions. Progress was slow, and this post documents everything (I think), but here are the highlights of work after the first blog post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fixed serial input for the MicroPython REPl&lt;/li&gt;
&lt;li&gt;finalized mid-term deliverables&lt;/li&gt;
&lt;li&gt;created a script to build the MicroPython library as a precursor to an RSB Recipe&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just to recap, during the application period I took the MicroPython &lt;code&gt;embed&lt;/code&gt; port that gives us the function &lt;code&gt;mp_embed_exec_str&lt;/code&gt; which can execute strings containing Python code. This is easy to use because the MicroPython implementation here is just a bunch of C source files without any external dependencies.&lt;/p&gt;
&lt;p&gt;However, it&amp;rsquo;s not very useful if we want to interact with the hardware RTEMS is running on. So, I moved away from the &lt;code&gt;embed&lt;/code&gt; port and followed MicroPython&amp;rsquo;s porting documentation that asks us to implement a few functions like &lt;code&gt;readline&lt;/code&gt; (yes I know, the signature here is &lt;code&gt;readline(vstr_t *vstr)&lt;/code&gt;, where &lt;code&gt;vstr_t&lt;/code&gt; is MicroPython&amp;rsquo;s variable-length string type), etc. and then we have a very minimal port.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what that looks like:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;MicroPython v1.26.0-preview.135.g5139cedab on 2025-06-23; rtems-i386/pc686 with unknown-cpu
&amp;gt;&amp;gt;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Initially my &lt;code&gt;readline&lt;/code&gt; (heh) implementation was broken so I wasn&amp;rsquo;t able to input anything, because of two reasons:&lt;/p&gt;
&lt;p&gt;First, I didn&amp;rsquo;t look at the function header closely and was trying to write the characters being read directly to the &lt;code&gt;vstr_t*&lt;/code&gt; pointer.&lt;/p&gt;
&lt;p&gt;Second. Interestingly, input functionality on the serial device (a console on QEMU in this case) was not being initialized, so my &lt;code&gt;fgets()&lt;/code&gt; calls wouldn&amp;rsquo;t block and I got an endless stream of &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;. I looked through the &lt;a href=&#34;https://gitlab.rtems.org/rtems/rtos/rtems/-/tree/main/testsuites/samples/fileio?ref_type=heads&#34;&gt;fileio sample&lt;/a&gt; and found:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;rtems_shell_wait_for_input&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    STDIN_FILENO,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    notification,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NULL
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  );
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For context, this sample has a little loop that presents a menu of actions to the user, and this function is called before that menu is first printed. I found that if I remove this call, I get similar behavior in the fileio sample, i.e., it just keeps printing the menu repeatedly and doesn&amp;rsquo;t block to read user input.&lt;/p&gt;
&lt;p&gt;I placed the call&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;rtems_shell_wait_for_input&lt;/span&gt;(STDIN_FILENO, &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;, NULL, NULL);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;in my example application, and got input to work! I was now able to write Python code:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;MicroPython v1.26.0-preview.135.g5139cedab on 2025-06-23; rtems-i386/pc686 with unknown-cpu
&amp;gt;&amp;gt;&amp;gt; def test(x, y):
...     return x + y
... 
&amp;gt;&amp;gt;&amp;gt; test(1, 2)
3
&amp;gt;&amp;gt;&amp;gt; import gc
&amp;gt;&amp;gt;&amp;gt; dir(gc)
[&amp;#39;__class__&amp;#39;, &amp;#39;__name__&amp;#39;, &amp;#39;__dict__&amp;#39;, &amp;#39;collect&amp;#39;, &amp;#39;disable&amp;#39;, &amp;#39;enable&amp;#39;, &amp;#39;isenabled&amp;#39;, &amp;#39;mem_alloc&amp;#39;, &amp;#39;mem_free&amp;#39;, &amp;#39;threshold&amp;#39;]
&amp;gt;&amp;gt;&amp;gt; gc.mem_free()
3024
&amp;gt;&amp;gt;&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This nice REPL is printed by the MicroPython function &lt;code&gt;pyexec_friendly_repl()&lt;/code&gt;, and it has a weird limitation where a single expression/statement (anything, including functions like &lt;code&gt;test&lt;/code&gt; above) should fit within 32 characters, not a lot!&lt;/p&gt;
&lt;p&gt;A limit made sense to me, but I wasn&amp;rsquo;t sure why this wasn&amp;rsquo;t configurable. One of my mentors pointed out the &lt;a href=&#34;https://docs.micropython.org/en/latest/reference/mpremote.html&#34;&gt;mpremote&lt;/a&gt; utility that is used to interact with MicroPython, so we tried to point it to the QEMU virtual console. Expectedly, it couldn&amp;rsquo;t connect to it, but we saw something interesting - the utility was trying to open something called a &amp;ldquo;Raw REPL&amp;rdquo; over the port. It would send &lt;code&gt;^A&lt;/code&gt; (Ctrl+A) and expect a Raw REPL to be available. After looking through the implementation of &lt;code&gt;pyexec_friendly_repl&lt;/code&gt; a bit more, I also expected it to connect because the function &lt;em&gt;does&lt;/em&gt; have code to handle codes like &lt;code&gt;^A&lt;/code&gt; (among others). Sending &lt;code&gt;^A&lt;/code&gt; to the function should make it execute &lt;code&gt;pyexec_raw_repl&lt;/code&gt;, but that wasn&amp;rsquo;t happening.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still trying to figure this out. It could something related to how we expose the console through QEMU. Unlikely (to me, because this is just an &lt;code&gt;fgets()&lt;/code&gt; call under the hood, and also, I see the actual characters &amp;ldquo;^A&amp;rdquo; appear on the REPL), but RTEMS could be consuming the input. Something I&amp;rsquo;m currently inspecting is the &lt;code&gt;termios&lt;/code&gt; flags used in &lt;code&gt;rtems_shell_wait_for_input&lt;/code&gt; to see if there&amp;rsquo;s any flags to enable Ctrl+key combinations that are missing. This is of interest to others, including the Organization Admin as well because these flags could be used globally so people don&amp;rsquo;t have to struggle to get input working.&lt;/p&gt;
&lt;h2 id=&#34;mid-term-deliverables&#34;&gt;Mid-Term Deliverables&lt;/h2&gt;
&lt;p&gt;I have set up weekly meetings with my mentors on Mondays. Last week we finalized &lt;a href=&#34;https://gitlab.rtems.org/groups/rtems/-/epics/22#note_124649&#34;&gt;these&lt;/a&gt; deliverables for the mid-term.&lt;/p&gt;
&lt;p&gt;This is similar to what I mentioned in my proposal: &amp;ldquo;Partial support for using RTEMS APIs through MicroPython&amp;rdquo;. In the previous post I talked about configuration across BSPs, but focusing on some support (that is general enough, like the &lt;code&gt;time&lt;/code&gt; module) first gives us some surface area to to figure out better ways of configuration other than &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/rtems/mpconfigport.h?ref_type=heads&#34;&gt;mpconfigport.h&lt;/a&gt; (if there are any).&lt;/p&gt;
&lt;h2 id=&#34;build-system&#34;&gt;Build System&lt;/h2&gt;
&lt;p&gt;There seems to be some confusion about it so I&amp;rsquo;ll document it here too - my current MicroPython &amp;ldquo;port&amp;rdquo; &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/tree/rtems/ports/rtems?ref_type=heads&#34;&gt;in my fork&lt;/a&gt; has an &lt;code&gt;init.c&lt;/code&gt; with some startup configuration and an &lt;code&gt;mpy.c&lt;/code&gt; with an &lt;code&gt;Init&lt;/code&gt; task. I am aware that these two files are found in &lt;em&gt;applications&lt;/em&gt;, not &lt;em&gt;libraries&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;During the Application Period I went through the Quickstart Guide in the RTEMS Documentation, that uses the Waf build system to build a &amp;ldquo;Hello, World!&amp;rdquo; application. So, when I set up my MicroPython port, I compiled the MicroPython objects using a Makefile (Micropython makes heavy use of &lt;code&gt;make&lt;/code&gt;), compiled &lt;code&gt;mphalport.c&lt;/code&gt;, a file that implements the input/output functions I mentioned above, using Waf, and then finally linked everything together with the application.&lt;/p&gt;
&lt;p&gt;To package MicroPython for RTEMS, we need an RSB (RTEMS Source Builder) Recipe, and I&amp;rsquo;ll be doing that with some help from one of my mentors. The first step here is to have a script that can build MicroPython, and we cannot use Waf.&lt;/p&gt;
&lt;p&gt;This is what I did today. Earlier I had a simple &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython-rsb-recipe/-/blob/main/setup_micropython_library.sh?ref_type=heads&#34;&gt;Bash script&lt;/a&gt; that used the old approach that kind of mixes the MicroPython &lt;code&gt;Makefile&lt;/code&gt; and RTEMS Application &lt;code&gt;wscript&lt;/code&gt; because of the port file, but now there is a &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/rtems/Makefile?ref_type=heads&#34;&gt;single Makefile&lt;/a&gt; that generates the whole &amp;ldquo;library&amp;rdquo; (all the required object files, including the one for &lt;code&gt;mphalport.c&lt;/code&gt;). An RTEMS application just need to link against these.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;Progress was slow during exams, but now I&amp;rsquo;ll be able to focus more on this project. I&amp;rsquo;m hoping to make progress with some of the modules this week.&lt;/p&gt;
&lt;p&gt;Other than the listed mid-term deliverables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Awaiting a mentor&amp;rsquo;s feedback on the integrated Makefile, which is the first step towards an RSB Recipe&lt;/li&gt;
&lt;li&gt;Trying to figure out the relevant &lt;code&gt;termios&lt;/code&gt; flags to get Ctrl+key combinations to work&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&amp;rsquo;ll try to post these more frequently now. Thank you for your time!&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>Introducing my GSoC Project!</title>
      <link>https://blog.bkpt.party/posts/gsoc1/</link>
      <pubDate>Wed, 04 Jun 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/gsoc1/</guid>
      <description>&lt;p&gt;I will be contributing to the &lt;a href=&#34;https://www.rtems.org/&#34;&gt;RTEMS Project&lt;/a&gt; under Google Summer of Code (GSoC) 2025!&lt;/p&gt;
&lt;p&gt;RTEMS is an open source Real-Time Operating System. It is used in space flight, medical, networking and many more embedded devices. RTEMS currently supports 18 processor architectures and approximately 200 Board support packages. You can learn more &lt;a href=&#34;https://www.rtems.org/&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My project is titled &amp;ldquo;Implementing MicroPython Support and Packaging It For RTEMS&amp;rdquo;. &lt;a href=&#34;https://micropython.org/&#34;&gt;MicroPython&lt;/a&gt; is a Python 3 implementation designed to run on microcontrollers and in other constrained environments. Being able to interact with an embedded device using Python is very cool, because you can just spin up an interpreter and start playing with the thing. No compilation and fiddling around with random vendor IDE parameters required.&lt;/p&gt;
&lt;p&gt;This is the first post of many that I will be writing throughout the program as I work with my mentors and the larger community to add this support to RTEMS. For this post, I want to share what I&amp;rsquo;ve done so far and give you an idea of what this will look like.&lt;/p&gt;
&lt;p&gt;During the Application Period, I created a simple proof-of-concept using a special MicroPython port which they call the &amp;ldquo;embed&amp;rdquo; port. As the name suggests, this is designed to make &amp;ldquo;embedding&amp;rdquo; MicroPython easier. The build output is a bunch of C source files with no other dependencies that you can directly include in your project and execute MicroPython code by passing it as a string to the the function &lt;code&gt;mp_embed_exec_str&lt;/code&gt;. There&amp;rsquo;s also some other housekeeping functions like &lt;code&gt;mp_embed_init&lt;/code&gt;, but the main functionality here is the ability to execute MicroPython code and get some output which you might decide to process further based on your application. This works for a small demo, and the fact that I was also able to bring this proof-of-concept up on actual STM32F4 hardware helped me learn more about using RTEMS with different BSPs as I had to tweak the Linker Script to get RTEMS to boot up on my board.&lt;/p&gt;
&lt;p&gt;This, however, is not enough. We need a higher level of integration between MicroPython and the &amp;ldquo;host&amp;rdquo; system (RTEMS in this case) to really call it a &amp;ldquo;port&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://docs.micropython.org/en/latest/develop/porting.html&#34;&gt;&amp;ldquo;Porting MicroPython&amp;rdquo;&lt;/a&gt; page in the MicroPython docs gives an example of a very basic port. We can follow this and the source code of the &lt;a href=&#34;https://github.com/micropython/micropython/tree/master/ports&#34;&gt;other available ports&lt;/a&gt; to get our RTEMS port going. Currently it has a &lt;code&gt;mphalport.c&lt;/code&gt; file that implements &lt;code&gt;mp_hal_stdin_rx_chr&lt;/code&gt;, &lt;code&gt;mp_hal_stdout_tx_strn&lt;/code&gt; and &lt;code&gt;readline&lt;/code&gt; that allow us to output a MicroPython shell over serial by calling &lt;code&gt;pyexec_friendly_repl()&lt;/code&gt; in our main code. We can&amp;rsquo;t yet enter things into the shell so that needs to be fixed.&lt;/p&gt;
&lt;p&gt;You can take a look at the current &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/rtems/mphalport.c?ref_type=heads&#34;&gt;mphalport.c&lt;/a&gt; and the main &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/rtems/mpy.c?ref_type=heads&#34;&gt;mpy.c&lt;/a&gt;. Additionally, &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/rtems/mpconfigport.h?ref_type=heads&#34;&gt;mpconfigport.h&lt;/a&gt; is used to enable and disable features like the &lt;code&gt;machine&lt;/code&gt; module at compile-time.&lt;/p&gt;
&lt;p&gt;Now here&amp;rsquo;s the problem - we need this to work across a lot of different boards (RTEMS BSPs or &amp;ldquo;Board Support Packages&amp;rdquo;). Taking a simple example like &lt;code&gt;machine.SPI&lt;/code&gt; in MicroPython, not all BSPs might have SPI support, and it&amp;rsquo;s not a good idea to compile all of this code and take up useful Flash space on a device that doesn&amp;rsquo;t have those features.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s my current mental model of what this could end up looking like:
&lt;img src=&#34;https://blog.bkpt.party/images/gsoc1_micropython_mental_model.svg&#34; alt=&#34;MicroPython Support for RTEMS (mental model)&#34;&gt;&lt;/p&gt;
&lt;p&gt;An ideal solution would really be one that simply doesn&amp;rsquo;t build features that aren&amp;rsquo;t available on the BSP being used. Let me quickly go through the ones discussed in the diagram:&lt;/p&gt;
&lt;h2 id=&#34;simply-using-mpconfigporth&#34;&gt;Simply using &lt;code&gt;mpconfigport.h&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;So we include the MicroPython library, and it will be a requirement for all applications that use this library to define this config file. If you&amp;rsquo;re wondering what this file looks like, here you go:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Python internal features.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_ENABLE_GC                       (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_HELPER_REPL                     (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_ERROR_REPORTING                 (MICROPY_ERROR_REPORTING_TERSE)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_READLINE_HISTORY_SIZE           (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Fine control over Python builtins, classes, modules, etc.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_ASYNC_AWAIT                  (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_BUILTINS_SET                 (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_ATTRTUPLE                    (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_COLLECTIONS                  (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_MATH                         (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_IO                           (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_STRUCT                       (0)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Type definitions for the specific machine.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;intptr_t&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;mp_int_t&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// must be pointer size
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;uintptr_t&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;mp_uint_t&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// must be pointer size
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;typedef&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;long&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;mp_off_t&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// We need to provide a declaration/definition of alloca().
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;alloca.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;// Define the port&amp;#39;s name and hardware.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_HW_BOARD_NAME &amp;#34;rtems-i386/pc686&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_HW_MCU_NAME   &amp;#34;unknown-cpu&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MP_STATE_PORT MP_STATE_VM
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can see that we have a lot of control over Python builtins like set, collections, etc.
We can also choose to define things like &lt;code&gt;MICROPY_PY_MACHINE&lt;/code&gt; to build the &lt;code&gt;machine&lt;/code&gt; module that further gives us access to &lt;code&gt;machine.I2C&lt;/code&gt;, &lt;code&gt;machine.SPI&lt;/code&gt; and friends. If you look at how the &lt;a href=&#34;https://gitlab.rtems.org/l1zard/micropython/-/blob/rtems/ports/zephyr/mpconfigport.h?ref_type=heads&#34;&gt;Zephyr Port&lt;/a&gt; does it, you&amp;rsquo;ll notice some interesting definitions:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_MACHINE          (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_MACHINE_INCLUDEFILE &amp;#34;ports/zephyr/modmachine.c&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_MACHINE_I2C      (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#define MICROPY_PY_MACHINE_SPI      (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;namely &lt;code&gt;MICROPY_PY_MACHINE_I2C&lt;/code&gt; and &lt;code&gt;MICROPY_PY_MACHINE_SPI&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;These are used to conditionally compile I2C and SPI support in &lt;code&gt;machine_i2c.c&lt;/code&gt; and &lt;code&gt;machine_spi.c&lt;/code&gt;. I think this is probably going to be how we specify the features we want to include. So based on the BSP being used and our requirements, we create a config file to enable the relevant MicroPython internal features and modules.&lt;/p&gt;
&lt;p&gt;There will of course be examples config files and documentation for the supported &amp;ldquo;flags&amp;rdquo; here.&lt;/p&gt;
&lt;h2 id=&#34;higher-level-configuration&#34;&gt;Higher Level Configuration&lt;/h2&gt;
&lt;p&gt;This is still a bit vague, but it would be neat if there was a way to enable/disable support without leaving the Python environment / using a high level config file (not sure what that would look like yet) / automatically selecting features based on the BSP being used.&lt;/p&gt;
&lt;p&gt;This post was supposed to come out sooner (last week) but here we are, in week 1 of GSoC 2025! I am currently looking into the RTEMS Source Builder (RSB) and create a &amp;ldquo;recipe&amp;rdquo; so my &amp;ldquo;port&amp;rdquo;, which is right now more of a test &lt;em&gt;application&lt;/em&gt; can be used as a &lt;em&gt;library&lt;/em&gt;. So basically I will remove &lt;code&gt;mpy.c&lt;/code&gt; (contains the actual &amp;ldquo;program&amp;rdquo; entry point) and &lt;code&gt;mpconfigport.h&lt;/code&gt; out of the &amp;ldquo;port&amp;rdquo;, write an RSB Recipe so that I can include it in an RTEMS Application where I will have the main code along with the config.&lt;/p&gt;
&lt;p&gt;Thank you for your time.&lt;/p&gt;
</description>
    </item>
    
    
    
    <item>
      <title>Baby&#39;s First UART on FPGA</title>
      <link>https://blog.bkpt.party/posts/babys_first_uart_on_fpga/</link>
      <pubDate>Sun, 23 Feb 2025 00:00:00 +0000</pubDate>
      
      <guid>https://blog.bkpt.party/posts/babys_first_uart_on_fpga/</guid>
      <description>&lt;p&gt;So I got this &lt;a href=&#34;https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-9K/Nano-9K.html&#34;&gt;Sipeed Tang Nano 9K&lt;/a&gt; FPGA development board recently (last year), and I wanted to write a bit about what I did as one of my first little projects, just to get this blog started.&lt;/p&gt;
&lt;p&gt;As the title suggests, I implemented a UART controller. I started by making a &lt;code&gt;tx&lt;/code&gt; module that would print an &amp;ldquo;S&amp;rdquo; over the serial console when I pressed a button. Then I implemented an &lt;code&gt;rx&lt;/code&gt; that received a byte and displayed it using the onboard LEDs.&lt;/p&gt;
&lt;p&gt;I will write about the &lt;code&gt;tx&lt;/code&gt; (Sender) part because I think people would find that more interesting. Before I explain the Verilog logic, let me tell you about a &lt;em&gt;UART Frame&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what a UART frame looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://blog.bkpt.party/images/uartframe.svg&#34; alt=&#34;UART frame&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;start bit&lt;/strong&gt;: UART wires (&lt;code&gt;rx&lt;/code&gt; and &lt;code&gt;tx&lt;/code&gt;) are pulled high (in state 1) by default. UART works in a master-slave configuration so there is always a sender and receiver. To begin a transmission, the sender pulls its &lt;code&gt;tx&lt;/code&gt; low. This is called the &amp;ldquo;start bit&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;d0..d7&lt;/strong&gt;: This is the byte being transmitted, LSB first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pb&lt;/strong&gt;: Parity Bit. UART devices agree on Even, Odd or No parity. I went with Even parity.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;stop bit&lt;/strong&gt;: similar to the start bit, the sender sends the line high again to end the frame. UART doesn&amp;rsquo;t specify a frame length, but the typical UART frame has 1 start bit, 8 data bits, an optional parity bit and 1 stop bit.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;UART operates on a &amp;ldquo;baudrate&amp;rdquo; concept, in contrast with other serial protocols like I2C and SPI that need separate &lt;code&gt;clock&lt;/code&gt; lines to synchronize the data between sender and receiver. UART sender and receiver agree on a baudrate, basically listening for and sending data after the same time intervals, eliminating the need for a separate clock wire. Baudrate here is &lt;code&gt;115200&lt;/code&gt; and it is specified using the &lt;code&gt;CLK_PER_BIT&lt;/code&gt; parameter, calculated based on the FPGA&amp;rsquo;s clock frequency. (27 MHz)&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the module (Verilog):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-v&#34; data-lang=&#34;v&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;module&lt;/span&gt; uart_tx &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    parameter &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;234&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input       clk,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input       start,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input [&lt;span style=&#34;color:#a6e22e&#34;&gt;7&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] data,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    output reg  tx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;assign start_tx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; start;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;BTN_PRESS_TIMEOUT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;27000000&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0000;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_START_BIT  = 4&amp;#39;&lt;/span&gt;b0001;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0010;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_PARITY_BIT = 4&amp;#39;&lt;/span&gt;b0011;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_STOP_BIT&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0100;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_DELAY      = 4&amp;#39;&lt;/span&gt;b0101;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;3&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] state &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;7&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] data_reg &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg data_parity_reg &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// even parity
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;31&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] counter &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;4&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] bit_index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;initial tx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;always &lt;span style=&#34;color:#f92672&#34;&gt;@&lt;/span&gt;(posedge clk) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    case (state)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;: begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (start_tx) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                data_reg &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; data;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                data_parity_reg &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_START_BIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;S_START_BIT&lt;/span&gt;: begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tx &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (counter &amp;lt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; counter &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_START_BIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;: begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tx &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; data_reg[bit_index];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (counter &amp;lt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; counter &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (bit_index &amp;lt; &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    bit_index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; bit_index &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    bit_index &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_PARITY_BIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;S_PARITY_BIT&lt;/span&gt;: begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tx &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; data_parity_reg;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (counter &amp;lt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; counter &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_PARITY_BIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt; begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_STOP_BIT&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;S_STOP_BIT&lt;/span&gt;: begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            tx &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b1;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            if (counter &amp;lt; CLK_PER_BIT-1) begin
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                counter &amp;lt;= counter + 1;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                state &amp;lt;= S_STOP_BIT;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            else begin
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                counter &amp;lt;= 0;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;                state &amp;lt;= S_IDLE;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;            end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;        end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;    endcase
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;endmodule
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I know this is shit code and kind of naive because state transitions should be handled separately in a clocked &lt;code&gt;always&lt;/code&gt; block, and the corresponding logic for each state should be handled in a combinational logic block. Just trying to record how I did it as a noob.&lt;/p&gt;
&lt;p&gt;Let me explain how this works, piece by piece:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-v&#34; data-lang=&#34;v&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;module&lt;/span&gt; uart_tx &lt;span style=&#34;color:#f92672&#34;&gt;#&lt;/span&gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    parameter &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;234&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input       clk,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input       start,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    input [&lt;span style=&#34;color:#a6e22e&#34;&gt;7&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] data,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    output reg  tx
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the module declaration. It is the &amp;ldquo;function header&amp;rdquo; or the &amp;ldquo;interface&amp;rdquo; which usually follows this kind of structure - the module name followed by &lt;em&gt;parameters&lt;/em&gt;, followed by port specification (&lt;code&gt;clk&lt;/code&gt; here is a 1-bit input, &lt;code&gt;data&lt;/code&gt; is a 7-bit input, etc.). Parameters are constant values that can be passed into the module when it&amp;rsquo;s instantiated. We can use parameters for many things, from controlling bus widths to conditional compilation using ifdefs.&lt;/p&gt;
&lt;p&gt;Scrolling down, we see a bunch of &lt;code&gt;localparam&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-v&#34; data-lang=&#34;v&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;       &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0000;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_START_BIT  = 4&amp;#39;&lt;/span&gt;b0001;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0010;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_PARITY_BIT = 4&amp;#39;&lt;/span&gt;b0011;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;localparam &lt;span style=&#34;color:#a6e22e&#34;&gt;S_STOP_BIT&lt;/span&gt;   &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;b0100;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;localparam S_DELAY      = 4&amp;#39;&lt;/span&gt;b0101;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These are the states for the finite state machine that generates the actual UART output.&lt;/p&gt;
&lt;p&gt;Numbers are specified in Verilog in the format: &lt;code&gt;&amp;lt;width&amp;gt;&#39;&amp;lt;format&amp;gt;&amp;lt;value&amp;gt;&lt;/code&gt;. Widths of all assignments to the localparams here are 4, the format we&amp;rsquo;re using is binary (b) and then the values have been specified using that format. We could also do &lt;code&gt;4d0&lt;/code&gt;, &lt;code&gt;4d1&lt;/code&gt;, &lt;code&gt;4d2&lt;/code&gt;&amp;hellip;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-v&#34; data-lang=&#34;v&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;3&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] state &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_IDLE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;7&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] data_reg &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg data_parity_reg &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;; &lt;span style=&#34;color:#75715e&#34;&gt;// even parity
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;31&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] counter &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;reg [&lt;span style=&#34;color:#a6e22e&#34;&gt;4&lt;/span&gt;:&lt;span style=&#34;color:#e6db74&#34;&gt;0&lt;/span&gt;] bit_index &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;initial tx &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;reg&lt;/code&gt; stands for &amp;ldquo;register&amp;rdquo;. These are basically mutable variables from a language PoV. &lt;code&gt;state&lt;/code&gt; stores the current state, and I have set it up to have the &lt;em&gt;initial&lt;/em&gt; value of &lt;code&gt;S_IDLE&lt;/code&gt; (0). &lt;code&gt;data_reg&lt;/code&gt; stores the actual byte to be transmitted. &lt;code&gt;data_parity_reg&lt;/code&gt; stores the parity bit. The byte being transmitted here is the ASCII value of &amp;lsquo;S&amp;rsquo;, i.e. 83 (1010011), which has an even number of 1s. Since we are going with an &lt;em&gt;even parity&lt;/em&gt; setup, we hardcode the parity as 1.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;counter&lt;/code&gt; is used to maintain the baudrate using this bit of redundant code in every state (by counting up to &lt;code&gt;CLK_PER_BIT&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-v&#34; data-lang=&#34;v&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (counter &amp;lt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CLK_PER_BIT&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;) begin
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    counter &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; counter &lt;span style=&#34;color:#f92672&#34;&gt;+&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    state &lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;S_SEND_BYTE&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#75715e&#34;&gt;// state logic, transitions
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;bit_index&lt;/code&gt; is the bit position in the byte being sent, starting from LSB.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;tx&lt;/code&gt; has already been declared as &lt;code&gt;reg&lt;/code&gt; in the module declaration, so we just set it to have the initial value of 1.&lt;/p&gt;
&lt;p&gt;When control moves into the &lt;code&gt;else&lt;/code&gt; block, the actual operation(s) related to that state can be performed, like sending the start bit, data bits, parity bit and stop bit.&lt;/p&gt;
&lt;p&gt;With this, the UART tx was done. I went on to make an &lt;code&gt;rx&lt;/code&gt; (receiver) core that, well, does the opposite of this and samples at the baudrate instead of transmitting, and I was able to display the data I sent using Python &lt;code&gt;pyserial&lt;/code&gt; on my laptop using the 6 LEDs on my FPGA board. I further connected the two cores to make an &amp;ldquo;echo&amp;rdquo;, where I would send some character using Python and receive that character back. I will write about the &lt;code&gt;rx&lt;/code&gt; and &lt;code&gt;echo&lt;/code&gt; bits in the future after some refining. Instead of supporting only single characters, I would like to use a small buffer with it so I can echo back any number of characters.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it for the first blog post! Thank you for your time.&lt;/p&gt;
</description>
    </item>
    
    
  </channel>
</rss>
