<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Teivaz]]></title><description><![CDATA[Software & Hardware development]]></description><link>https://teivaz.com/</link><image><url>https://teivaz.com/favicon.png</url><title>Teivaz</title><link>https://teivaz.com/</link></image><generator>Ghost 4.48</generator><lastBuildDate>Wed, 24 Sep 2025 18:03:33 GMT</lastBuildDate><atom:link href="https://teivaz.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1]]></title><description><![CDATA[Manipulator Part 1]]></description><link>https://teivaz.com/mechanical-manipulator-part-1/</link><guid isPermaLink="false">68d21bf690534e0001bf2af7</guid><category><![CDATA[mechanics]]></category><category><![CDATA[robot]]></category><dc:creator><![CDATA[Teivaz]]></dc:creator><pubDate>Tue, 23 Sep 2025 04:07:22 GMT</pubDate><media:content url="https://teivaz.com/content/images/2025/09/Screenshot-2025-09-22-at-21.11.43.png" medium="image"/><content:encoded><![CDATA[<img src="https://teivaz.com/content/images/2025/09/Screenshot-2025-09-22-at-21.11.43.png" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1"><p>I am designing a mechanical manipulator as a &quot;helping hand&quot; for the workbench. And instead of classical motor operated robot manipulators I have decided to follow the actual human arm anatomy principles. The result will be a stationary mechanical hand-like manipulator operated by artificial muscles that can perform various tasks at the workbench. This is a first from the series of summaries of the process I went through while designing this manipulator.</p><h2 id="intro-arm-bone-structure">Intro: Arm Bone Structure</h2><p>The elbow part of an arm contains 3 bones: humerus, ulna, and radius. But these 3 bones have 4 joints most of which of different kind. Let&#x2019;s go through each joint one by one.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/elbow-joint.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="1260" height="642" srcset="https://teivaz.com/content/images/size/w600/2025/09/elbow-joint.jpg 600w, https://teivaz.com/content/images/size/w1000/2025/09/elbow-joint.jpg 1000w, https://teivaz.com/content/images/2025/09/elbow-joint.jpg 1260w" sizes="(min-width: 720px) 720px"><figcaption>Figure 1. Bones of the elbow joint</figcaption></figure><h2 id="joint-1-humerus-and-ulna">Joint 1. Humerus and Ulna</h2><p>Anatomical terminology defines this type of joint as a hinge joint. This has only one degree of freedom. When ulna is collinear with humerus the forearm is fully extended. Opposite extremum, when is when ulna is parallel to humerus is called fully flexed. Motions towards corresponding positions is called extension and flexion correspondingly.</p><p>In its basic form the hinge joint is just a cylinder with a pipe sector sliding around it.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-joint.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="413" height="348"><figcaption>Figure 2. Simplified hinge joint</figcaption></figure><p>However in such configuration the outer joint would slide along the rotation axis. To eliminate this movement we need to add 2 edges that would prevent sliding in both directions. The easiest is to add a v-groove and make the corresponding feature on the outer part of the joint.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-joint-groove.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="413" height="324"><figcaption>Figure 3. Simplified hinge joint with v-groove</figcaption></figure><p>This gives us one part of geometry of a joint between humerus and ulna. Now let&#x2019;s look at the movement range and how the rest of the bone connects to the joint. Full range of motion of this joint is slightly less than 180&#x2DA;. The more the outer part wraps the joint the greater is the stability of the joint. But wrapping the outer part fully around the joint, like it is done on a common door hinges, is excessive and would make it harder to assemble. Even wrapping angle over 180&#x2DA; would rely on the flexion of the part for assembly, so let&#x2019;s set the limit of how much the outer part can wrap around the joint to 180&#x2DA;. On top of that the point of bone connection also influences the wrapping angle (fig. 4).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-overlap.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="395" height="298"><figcaption>Figure 4. Hinge maximal range</figcaption></figure><p>However this is only a problem in 2-dimentional space, in 3d we have more freedom. The effective wrapping angle is between the furthest points around the axis and if we combine angles less than 180&#x2DA; in such way that they extreme points we can get the desired wrapping angle.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-overlap-planes.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="354" height="340"><figcaption>Figure 5. Hinge multiple overlaps</figcaption></figure><p>So if we instead design the bone attachment with this in mind we will can get such design</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-overlap-solved.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="384" height="307"><figcaption>Figure 6. Extra hinge overlap</figcaption></figure><p>So the final outer hinge would contain a protruding end from one side and a dip on the other end of the shape</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2025/09/hinge-outer.jpg" class="kg-image" alt="Building an Elbow Joint for a Mechanical Arm-like Manipulator. Part 1" loading="lazy" width="347" height="363"><figcaption>Figure 7. Hinge outer part</figcaption></figure><figure class="kg-card kg-video-card kg-width-full"><div class="kg-video-container"><video src="https://teivaz.com/content/media/2025/09/elbow-1.mp4" poster="https://img.spacergif.org/v1/1024x768/0a/spacer.png" width="1024" height="768" loop autoplay muted playsinline preload="metadata" style="background: transparent url(&apos;https://teivaz.com/content/images/2025/09/media-thumbnail-ember449.jpg&apos;) 50% 50% / cover no-repeat;"></video><div class="kg-video-overlay"><button class="kg-video-large-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button></div><div class="kg-video-player-container kg-video-hide"><div class="kg-video-player"><button class="kg-video-play-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M23.14 10.608 2.253.164A1.559 1.559 0 0 0 0 1.557v20.887a1.558 1.558 0 0 0 2.253 1.392L23.14 13.393a1.557 1.557 0 0 0 0-2.785Z"/></svg></button><button class="kg-video-pause-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><rect x="3" y="1" width="7" height="22" rx="1.5" ry="1.5"/><rect x="14" y="1" width="7" height="22" rx="1.5" ry="1.5"/></svg></button><span class="kg-video-current-time">0:00</span><div class="kg-video-time">/<span class="kg-video-duration"></span></div><input type="range" class="kg-video-seek-slider" max="100" value="0"><button class="kg-video-playback-rate">1&#xD7;</button><button class="kg-video-unmute-icon"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M15.189 2.021a9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h1.794a.249.249 0 0 1 .221.133 9.73 9.73 0 0 0 7.924 4.85h.06a1 1 0 0 0 1-1V3.02a1 1 0 0 0-1.06-.998Z"/></svg></button><button class="kg-video-mute-icon kg-video-hide"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 24 24"><path d="M16.177 4.3a.248.248 0 0 0 .073-.176v-1.1a1 1 0 0 0-1.061-1 9.728 9.728 0 0 0-7.924 4.85.249.249 0 0 1-.221.133H5.25a3 3 0 0 0-3 3v2a3 3 0 0 0 3 3h.114a.251.251 0 0 0 .177-.073ZM23.707 1.706A1 1 0 0 0 22.293.292l-22 22a1 1 0 0 0 0 1.414l.009.009a1 1 0 0 0 1.405-.009l6.63-6.631A.251.251 0 0 1 8.515 17a.245.245 0 0 1 .177.075 10.081 10.081 0 0 0 6.5 2.92 1 1 0 0 0 1.061-1V9.266a.247.247 0 0 1 .073-.176Z"/></svg></button><input type="range" class="kg-video-volume-slider" max="100" value="100"></div></div></div></figure>]]></content:encoded></item><item><title><![CDATA[Naming in Programming]]></title><description><![CDATA[Naming is hard, even for the developers of programming languages]]></description><link>https://teivaz.com/naming-in-programming-languages/</link><guid isPermaLink="false">6389db9f90534e0001bf290e</guid><category><![CDATA[Python]]></category><category><![CDATA[Rust]]></category><category><![CDATA[C++]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[CocoaPods]]></category><category><![CDATA[naming]]></category><dc:creator><![CDATA[Teivaz]]></dc:creator><pubDate>Sat, 17 Dec 2022 12:03:11 GMT</pubDate><media:content url="https://teivaz.com/content/images/2022/12/IMG_1406-6.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://teivaz.com/content/images/2022/12/IMG_1406-6.jpg" alt="Naming in Programming"><p>Is hard.</p><h2 id="thick-javascript">Thick JavaScript</h2><p>The following combination of symbols <code>-&gt;</code> is known in many languages as an &quot;arrow&quot; operator. Javascript is not one of those languages however it has a similarly looking operator <code>=&gt;</code> which by many is called &quot;<em>fat arrow</em>&quot;.</p><h2 id="comparison-in-c">Comparison in C++</h2><p>C++ is known to be a rather verbose language. And one of the problems arises when one creates a custom types that need to be comparable. For example you have your class <code>Dog</code> and want to compare</p><pre><code class="language-C++">bool operator &gt; (const Dog&amp; a, const Dog&amp; b) {
	return a.awsomeness &gt; b.awesomeness;
}</code></pre><p>so you want to find which is the best dog out there. But C++ has more than just one comparison operator, it has 6 of them: <code>==</code>, <code>&gt;</code>, <code>&lt;</code>, <code>&gt;=</code>, <code>&lt;=</code>, <code>!=</code>. So in order to support comparison you need to define all of them, not just one. To somehow solve &#xA0;this problem of too many operators C++ has introduced yet another operator! Its official name is &quot;three way comparison&quot; <code>&lt;=&gt;</code>. But most people call it the &quot;<em>spaceship operator&quot;</em>.</p><h2 id="optimism-of-cocoapods">Optimism of CocoaPods</h2><p>The package manager CocoaPods has a number of operators that are used to specify certain ranges of versions of the packages. Among them is an operator <code>~&gt;</code> which tells package manager to install the specified version, or any patched versions after the specified, hoping for a more stable package. To reflect this hope the operator was actually called the &quot;<em>optimistic operator</em>&quot;. Not that often you would find explicit optimism in the code, most of the times it is revealed as hope of a programmer that its code would not fail.</p><h2 id="disambiguation-of-rust">Disambiguation of Rust</h2><p>In the strictly typed programming language Rust many types are inferred by the compiler and rarely you need to write single type more than once (at least within a given context). However there exist some cases when Rust is not sure what it needs to do because it has too many options. In these cases Rust requires an explicit syntax <code>::&lt;SomeType&gt;</code> to disambiguate the behaviour. Which is known as &quot;<em>turbofish</em>&quot;.</p><h2 id="low-level-in-python">Low Level in Python</h2><p>Anyone who has had a chance to work with Python have seen some functions that start and end with two <code>_</code> symbols. Mostly this is <code>__init__</code> method that is called when an object of a given class is created. But Python has much more of these functions and all of them are used to convey a lower level functionality of data types. They are considered lower level because normally they are not directly used in programs, but instead are picked up by the language when performing other operations with the objects. For example to find the number of elements in a list one would call function <code>len(my_list)</code>. But if you define the method <code>__len__(self)</code> in your class then you can use the very same function <code>len(my_obj)</code> as if it was an array. And Python has dozens of these double-underscored-functions (and identifiers in general) that let your code mimic the behaviour of basic data types. The official name for them is the &quot;data model&quot; functions, but people ignore that name and usually call them &quot;<em>dunder</em>&quot; functions (because saying &quot;double-underscore-function&quot; is a bit of a mouthful).</p>]]></content:encoded></item><item><title><![CDATA[The Microcontroller and How to Program It Without an IDE]]></title><description><![CDATA[Compiling C code for microcontrollers from scratch]]></description><link>https://teivaz.com/the-microcontroller-and-how-to-program-it-without-an-ide/</link><guid isPermaLink="false">61323ef84b103200010d3ff4</guid><category><![CDATA[MCU]]></category><category><![CDATA[C]]></category><category><![CDATA[stm32]]></category><category><![CDATA[CMake]]></category><category><![CDATA[ARM]]></category><category><![CDATA[macOS]]></category><category><![CDATA[linker script]]></category><dc:creator><![CDATA[Teivaz]]></dc:creator><pubDate>Thu, 13 Feb 2020 15:22:44 GMT</pubDate><media:content url="https://teivaz.com/content/images/2020/02/photo_2020-02-13-16.50.06.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://teivaz.com/content/images/2020/02/photo_2020-02-13-16.50.06.jpeg" alt="The Microcontroller and How to Program It Without an IDE"><p>I found myself in an unplanned vacation and decided to get back to my radio engineering hobby. Bought STLINK and a couple of ST&apos;s latest chips. And then it happened again. The lack of proper usable tools. I was hoping that the embedded world would have that figured by now. I was wrong.</p><p>I got myself the STM Cube IDE thingy. Assembled circuit. Created a basic program. Attached wires. Tried to connect. Fixed wiring. Finally connected.</p><p>I have to say that the configurator they have there is a really nice tool, but the code it generates is a pure nightmare.</p><p>That day everything worked. Then as my setup went more complex the functionality started falling apart. The first thing that broke - debugging. Ever since that day I was not able to attach the debugger to my MCUs. The next thing that broke - STM Cube Programmer.</p><p>So there I was, struggling with ST&apos;s IDE from hell. Day by day it was sucking all the happiness out of me. Then I found some information like this <a href="https://geokon-gh.github.io/bluepill/" rel="nofollow">guide</a> and it helped me immensely. So I got it sorted out. Which brings me here, to the point where I want to share this knowledge with other poor souls who can find themselves lost in attempt to get going and understand how programming &#xA0;microcontrollers work.</p><p>Oh, and I&apos;ll be using macOS.</p><h2 id="the-overview">The Overview</h2><p>The goal here is to create software, convert it to machine code and upload it to the microcontroller. Bonus points for in-circuit debugging.</p><h3 id="the-language">The Language</h3><p>I have some experience with C++ therefore I&apos;ll be using <strong>C</strong>. It&apos;s also a typical language (assembly?) to write embedded software which means there would be plenty of materials and tools on the internet.</p><h3 id="the-compiler">The Compiler</h3><p>There are not so many options for this setup. You can use gcc. Not just <strong>gcc</strong>, but use a specific build of it that is able to generate code for the used processor </p><h3 id="the-build-system">The Build System</h3><p><strong>CMake</strong>. Many people hate it. It can be hideous. But if you know how to do it properly it is a very nice tool and currently there are no alternatives. On one end we have <em>make</em>, on the other end are tools like <em>Bazel</em>, <em>Buck</em>, and such. Make is way too antique for my taste. And from my recent experience with <em>Bazel</em> I can say that it&apos;s too immature. But I hope one day it will show us the way.</p><h3 id="the-hardware">The Hardware</h3><p>I have bought the microcontroller <code><a href="https://www.st.com/en/microcontrollers-microprocessors/stm32l011f4.html">STM32L011F4</a></code> with 32 bit ARM Cortex-M0+ processor. Oh and they are often referred to as <em>microcontrollers</em> or <em>MCU</em>s (microcontroller units). They are not called <em>microprocessors</em> or <em>processors</em> because processor is only a part of it. The other parts being memory (RAM, flash, EEPROM, etc), peripheral devices (timers/counters, communication interfaces, etc.), clock generators.</p><p>To connect this microcontroller to the computer I bought the latest <a href="https://www.st.com/en/development-tools/stlink-v3set.html">STLINK-V3SET</a> which is a debugger/programmer.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2020/02/New-Project-1.png" class="kg-image" alt="The Microcontroller and How to Program It Without an IDE" loading="lazy"><figcaption>STLINK-V3SET</figcaption></figure><p>I would not recommend buying standalone microchips because it requires a whole lot of setup and experience in soldering tiny chips the size of a pencil tip.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2020/02/photo_2020-02-13-16.04.04.jpeg" class="kg-image" alt="The Microcontroller and How to Program It Without an IDE" loading="lazy"><figcaption>TSSOP20 package</figcaption></figure><p>Luckily there is a huge variety of evaluation boards that have almost everything you might need. Like this NUCLEO-F303RE which already comes with ST-LINK debugger/programmer. The best part is that you can buy a decent board for only 16 euros.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2020/02/image-4.png" class="kg-image" alt="The Microcontroller and How to Program It Without an IDE" loading="lazy"><figcaption>NUCLEO-F303RE</figcaption></figure><p>And even if this guide won&apos;t help you figure out the bare C programming of microchips you can always switch this board to Arduino Uno mode.</p><hr><h2 id="writing-the-program">Writing the Program</h2><p>I&apos;ll start with the most simple C program for a microcontroller. I&apos;ll get back to the programming part but for now, it&apos;s not the most important part. I need to configure the whole pipeline first.</p><figure class="kg-card kg-code-card"><pre><code class="language-c">int main(void) {
	while(1);
}</code></pre><figcaption>main.c</figcaption></figure><p>The infinite loop is essential here as a microcontroller should never stop while it&apos;s on.</p><hr><h2 id="compiling">Compiling</h2><p>The compiler needs to match the processor type. My MCU has an ARM processor. Therefore I&apos;ll be using <code>arm-none-eabi-gcc</code> (if you&apos;re wondering where these words come from google &quot;target triplet&quot;). For some time I was confused where to get the compiler from. It turns out that there is really only one place - the <em>ARM</em> itself. With the help of the community they develop the toolchain for ARM processors which includes the compiler I need.</p><p>For macOS I installed it with this formulae:</p><pre><code class="language-bash">brew tap ArmMbed/homebrew-formulae
brew install arm-none-eabi-gcc</code></pre><p>Because I&apos;m cross-compiling I need to set up the toolchain file. There&apos;s not much to it - just general information for CMake on how you build for your platform.</p><figure class="kg-card kg-code-card"><pre><code class="language-cmake"># Cross compiling. &quot;Generic&quot; is used for embedded platforms
set(CMAKE_SYSTEM_NAME &quot;Generic&quot;)

# Compilers
set(CMAKE_C_COMPILER &quot;arm-none-eabi-gcc&quot;)

# Tells CMake not to try to link executables during its interal checks
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)</code></pre><figcaption>toolchain.cmake</figcaption></figure><p>And create a <code>CMakeLists.txt</code> file.</p><figure class="kg-card kg-code-card"><pre><code class="language-cmake"># Always start with version requirement - it&apos;s a requirement
cmake_minimum_required(VERSION 3.12)

# Tell CMake to use our toolchain file
set(CMAKE_TOOLCHAIN_FILE &quot;${CMAKE_CURRENT_LIST_DIR}/toolchain.cmake&quot;)

# And start a project
project(&quot;cmake-stm32&quot;)

set(CMAKE_C_STANDARD &quot;11&quot;) # C11

add_executable(&quot;${PROJECT_NAME}&quot; &quot;main.c&quot;)
# Produce a file &apos;program.elf&apos; that can be uploaded to the MCU
set_target_properties(&quot;${PROJECT_NAME}&quot; PROPERTIES OUTPUT_NAME &quot;program.elf&quot;)


# Compile options and definitions that should be set globally
# For local to the project use `target_compile_definitions`
add_compile_options(
	# CPU specific
	&quot;-mcpu=cortex-m0plus&quot;
	&quot;-mfloat-abi=soft&quot;
	&quot;-mthumb&quot;
	# Non-CPU specific
	&quot;--specs=nano.specs&quot;
	&quot;-ffunction-sections&quot;
	&quot;-fdata-sections&quot;
	&quot;-fstack-usage&quot;
	# Other options
	&quot;-g3&quot;
	&quot;-c&quot;
	&quot;-Os&quot;
	&quot;-Wall&quot;
)

# Set the linker flags
# Unfortunately this is the best way to set the linker flags in CMake
set_target_properties(&quot;${PROJECT_NAME}&quot; PROPERTIES LINK_FLAGS
	&quot;-mcpu=cortex-m0plus \
	-mthumb \
	-mfloat-abi=soft \
	-T\&quot;${CMAKE_CURRENT_LIST_DIR}/stm32l011f4.ld\&quot; \
	-Wl,-Map=\&quot;${PROJECT_NAME}.map\&quot; \
	-Wl,--gc-sections \
	-static \
	--specs=nano.specs \
	-Wl,--start-group -lc -lm -Wl,--end-group&quot;
)
</code></pre><figcaption>CMakeLists.txt</figcaption></figure><p>The compiler options have three parts ordered by their importance:</p><ol><li>CPU specific options</li><li>Non-CPU specific options</li><li>Other options</li></ol><h3 id="cpu-specific-compiler-options">CPU Specific Compiler Options</h3><p>These options need to match your processor.</p><p>1. For my CPU I need <code>-mcpu=cortex-m0plus</code>. If you&apos;re using the STM32F303RE development board you need this to be <code>-mcpu=cortex-m4</code> because the processor there is ARM Cortex-M4. By this point, you might be wondering where do I get this whole information from, the answer is documentation. In the form of datasheets mainly. Once you get an MCU the very next thing you need to get is its datasheet. It contains all the required data about your MCU.</p><p>2. My CPU has no hardware support for floating-point, therefore, I need to tell the compiler to emulate it in software with <code>-mfloat-abi=soft</code>. The <a href="https://developer.arm.com/ip-products/processors/cortex-m/cortex-m0-plus">ARM site</a> has it all written for you. Here&apos;s a fragment of that table:</p><!--kg-card-begin: html--><table>
<tbody>
<tr>
<td><strong>Feature</strong></td>
<td><strong>Cortex-M0</strong></td>
<td><strong>Cortex-M0+</strong></td>
<td><strong>Cortex-M1</strong></td>
<td><strong>Cortex-M23</strong></td>
<td><strong>Cortex-M3</strong></td>
<td><strong>Cortex-M4</strong></td>
</tr>
<tr>
<td rowspan="2"><strong>Instruction Set Architecture</strong></td>
<td>Armv6-M</td>
<td>Armv6-M</td>
<td>Armv6-M</td>
<td>Armv8-M Baseline</td>
<td>Armv7-M</td>
<td>Armv7-M</td>
</tr>
<tr>
<td>Thumb, Thumb-2</td>
<td>Thumb, Thumb-2</td>
<td>Thumb, Thumb-2</td>
<td>Thumb, Thumb-2</td>
<td>Thumb, Thumb-2</td>
<td>Thumb, Thumb-2</td>
</tr>
<tr>
<td><strong>Floating Point Hardware</strong></td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes (scalar SP)</td>
</tr>
<tr>
<td><strong>Hardware Divide</strong></td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td><strong>Single Cycle Multiply</strong></td>
<td>Yes (option)</td>
<td>Yes (option)</td>
<td>No</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td><strong>Digital Signal Processing (DSP) extension</strong></td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>Yes (option)</td>
</tr>
</tbody>
</table><!--kg-card-end: html--><p>So if you have STM32F303RE with Cortex-M4 you want this option to be <code>-mfloat-abi=hard</code>. And also <code>-mfpu=fpv4-sp-d16</code> because of the DSP unit. More about floating points: <a href="https://embeddedartistry.com/blog/2017/10/11/demystifying-arm-floating-point-compiler-options/"><em>Demystifying ARM Floating Point Compiler Options</em>.</a></p><p>3. And finally <code>-mthumb</code> option enables the <em>thumb</em> instruction set supported by all Cortex processors. Thumb a is mixed 32/16 bit instruction set that can fit 2 16-bit instructions in a 32-bit word. This generally would yield a smaller binary size.<br>You can read more about it on Stack Overflow: <em><a href="https://stackoverflow.com/q/11062936/3344612">GCC -mthumb against -marm</a></em>.</p><h3 id="non-cpu-specific">Non-CPU Specific</h3><p>The option <code>--specs=nano.specs</code> tells the compiler about the C library. The C library, in this case, is a part of the <code>arm-none-eabi</code> toolchain (that is why it is called toolchain - it has a compiler and all other necessary tools).</p><p>Then come helpful options for embedded development in general: <code>-ffunction-sections</code>, <code>-fdata-sections</code>, <code>-fstack-usage</code>. Feel free to experiment with them.</p><h3 id="other-options">Other Options</h3><ul><li><code>-g3</code> - generates debug information.</li><li><code>-c</code> - compiles source files but does not link. The output file we need is effectively a static library so we do not need to invoke a linker.</li><li><code>-Os</code> - optimise by size. My MCU has very little flash memory and this is the only way to fit everything I need without rewriting it in a more low-level fashion.</li><li><code>-Wall</code> - enable warnings. Runtime errors are the last thing you want in the MCU so enable all warnings and fix them.</li></ul><h3 id="the-cpu-specific-linker-flags">The CPU Specific Linker Flags</h3><ul><li><code>-mcpu=cortex-m0plus</code> - same as for the compiler.</li><li><code>-mfloat-abi=soft</code> - same as for the compiler.</li><li><code>-T&quot;${CMAKE_CURRENT_LIST_DIR}/stm32l011f4.ld&quot;</code> - linker file. The linker file is the glue between the compiled C code and the microcontroller&apos;s memory. I&apos;ll explain it further in detail. For now I can say there are 2 ways to obtain it: either by writing it yourself from the datasheet, or from any library package for your MCU (like one from ST&apos;s site or <a href="https://github.com/libopencm3/libopencm3/tree/master/lib/stm32">opencm3</a>).</li><li><code>--specs=nano.specs</code></li></ul><h3 id="the-rest-of-linker-flags">The Rest Of Linker Flags</h3><ul><li><code>-Wl,-Map=&quot;${PROJECT_NAME}.map&quot;</code> - generate a .map file. A very useful file for finding crashes and alternative debugging.</li><li><code>-Wl,--gc-sections</code> - remove unused data.</li><li><code>-static</code></li><li><code>-Wl,--start-group -lc -lm -Wl,--end-group</code> - link <code>lib</code> and <code>libm</code></li></ul><hr><h2 id="the-almighty-datasheet">The Almighty Datasheet</h2><p>Before I proceed with the linker file and the boot file let me emphasise how important it is to read the datasheet. Get your datasheet (just google &quot;stm32l011f4 datasheet pdf&quot; and the very second link will present you the desired <a href="https://www.st.com/resource/en/datasheet/stm32l011d4.pdf">document</a>). Get familiar with it. You don&apos;t have to read it whole now - only the general description and the table of contents.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2020/02/New-Project--1-.png" class="kg-image" alt="The Microcontroller and How to Program It Without an IDE" loading="lazy"><figcaption>Behold a datasheet</figcaption></figure><h2 id="the-linker-file">The Linker File</h2><p>The linker file has instructions for the linker where to put certain parts of the compiled code. There is a handful of predefined sections of program memory, the main ones being:</p><ul><li><strong>Text</strong> where all executable code goes</li><li><strong>Data</strong> where all initialised global and static variables go</li><li><strong>BSS</strong> where all uninitialised globals and static variables go</li><li><strong>Stack</strong> where reside runtime dynamic variables</li><li><strong>Heap</strong> where dynamically allocated data is kept</li></ul><p>The very first thing that linker file normally defines is the representation of the memory model (it is described in the datasheet). My MCU has this memory layout:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://teivaz.com/content/images/2020/02/Screenshot-2020-02-13-at-00.08.10.png" class="kg-image" alt="The Microcontroller and How to Program It Without an IDE" loading="lazy"><figcaption>Memory map</figcaption></figure><p>The RAM starts at the address <code>0x2000 0000</code> and according to the other paragraph of the datasheet it is 2KB long. RAM can be read, written, and executed, which is translated to the linker file syntax as:</p><pre><code class="language-ld">MEMORY
{
	ram (xrw) : ORIGIN = 0x20000000, LENGTH = 2K
}</code></pre><p>Next up is the flash memory which should be 16KB and starts at the address <code>0x0800 0000</code>. This memory can not be written under normal conditions so it has only <code>r</code> and <code>x</code> attributes.</p><pre><code class="language-ld">MEMORY
{
	ram (xrw) : ORIGIN = 0x20000000, LENGTH = 2K
	flash (rx) : ORIGIN = 0x08000000, LENGTH = 16K
}</code></pre><p>It also has EEPROM but I will skip it for now.</p><p>Stack: the processor needs to know where the stack begins. Point it to the very end of the RAM memory. The stack grows downwards so the end of the available RAM is the very first address that can be used. Another caveat here is that the linker script can not set the stack pointer. What it can do instead is to provide the address of the stack so it can be set in run time from code.</p><pre><code class="language-ld">PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
</code></pre><p>The code above provides a variable <code>_stack</code> located at the very last address of the RAM.</p><p>All is left now is to define the memory sections and assign them to the right segments of the memory (flash or RAM).</p><pre><code class="language-ld">SECTIONS
{
	.text : {
		*(.vectors)
		*(.text*)
		. = ALIGN(4);
	} &gt; flash
}
</code></pre><p>When I first saw the linker script I had so many questions. It took me several sleepless nights to understand it on the level where it is clear for me. Like the part above which is a bit more complicated than the code we saw before.</p><ul><li>Why is there two <code>.text</code>?</li><li>Why are there so many asterisks?</li><li>What&apos;s up with that <code>ALIGN</code>?</li><li>What is <code>.vectors</code>?</li></ul><p>I found all the answers. Let me explain.</p><p>The command <code>.text : { } &gt; flash</code> declares a memory block called <em>.text</em> and places it in the flash memory. It is not the same as <code>.text</code> section from the program memory I wrote about before; it is a different entity, like a variable name nothing more.</p><p>The command <code>*(<em>section</em>)</code> inside a memory block is a way to allocate all of the corresponding program <em>section</em> content.<br>The second asterisk in <code>*(.text*)</code> is just a wildcard symbol. All segments that start with <code>.text</code> will be allocated there.</p><p>The line <code>. = ALIGN(4);</code> asks linker to add padding memory after the previous segment so the next segment starts with the address which is multiple of 4. This is necessary for efficient and correct addressing of the memory in 32 bit CPUs. Because every consecutive section starts right after the the end of previous section in given memory segment.</p><p>The <code>*(.vectors)</code> is a segment of memory that I will create in the code. This segment will go to the very beginning of the memory because it serves a very important function - the startup sequence of the MCU.</p><h2 id="the-boot-file">The Boot File</h2><p>Which brings us to the boot file. According to the datasheet the boot sequence of the processor is following:</p><blockquote>... the CPU fetches the top-of-stack value from address <code>0x0000 0000</code>, then starts code execution from the boot memory at <code>0x0000 0004</code>.</blockquote><p>My CPU has several boot modes that define what memory will be mapped to the address of <code>0x0000 0000</code>. In the normal boot mode this would be the beginning of the flash memory (<code>0x0800 0000</code>). So I have placed a special section called <code>.vectors</code> in this part of the memory. </p><figure class="kg-card kg-code-card"><pre><code class="language-c">extern unsigned int _stack; // Provided by the linker file
extern int main(void);

// Let compiler know what section this code belongs to
__attribute__ ((section(&quot;.vectors&quot;)))
struct {
	unsigned int* initial_stack_pointer;
	void (*reset)(void);
} vector_table = {
	initial_stack_pointer = &amp;_stack,
	reset = main,
};</code></pre><figcaption>boot.c</figcaption></figure><p>The code above uses the variable <code>_stack</code> that I created in the linker script and a function <code>int main(void)</code> which comes from the code I wrote in the very beginning. Then places the pointers to the top of the stack and the entry point in the right place in the memory.</p><p>But there&apos;s more. Right after address <code>0x0000 0000</code> and <code>0x0000 0004</code> comes <code>0x0000 0008</code> and this address is also a part of the internal functionality of the MCU. The datasheet should have section <em>Interrupt and exception vectors</em> with the detailed description of what should go there.</p><p>Here&apos;s a fragment of the table <em>List of Vectors</em> from the datasheet on STM32L011F4</p><!--kg-card-begin: html--><table class="tableizer-table">
	<thead><tr class="tableizer-firstrow"><th>Acronym</th><th>Description</th><th>Address</th></tr></thead><tbody>
    <tr><td>-</td><td>Reserved</td><td><tt>0x0000 0000</tt></td></tr>
 <tr><td>Reset</td><td>Reset</td><td><tt>0x0000 0004</tt></td></tr>
 <tr><td>NMI_Handler</td><td>Non maskable interrupt.<br>The RCC Clock Security System (CSS)<br>is linked to the NMI vector.</td><td><tt>0x0000 0008</tt></td></tr>
 <tr><td>HardFault_Handler</td><td>All class of fault</td><td><tt>0x0000 000C</tt></td></tr>
 <tr><td>-</td><td>Reserved</td><td><tt>0x0000 0010</tt> - <tt>0x0000 002B</tt></td></tr>
 <tr><td>SVC_Handler</td><td>System service call via SWI instruction</td><td><tt>0x0000 002C</tt></td></tr>
 <tr><td>-</td><td>Reserved</td><td><tt>0x0000 0030</tt> - <tt>0x0000 0037</tt></td></tr>
 <tr><td>PendSV_Handler</td><td>Pendable request for system service</td><td><tt>0x0000 0038</tt></td></tr>
 <tr><td>SysTick_Handler</td><td>System tick timer</td><td><tt>0x0000 003C</tt></td></tr>
</tbody></table><!--kg-card-end: html--><p>The complete boot file for my controller looks like this. Creating this file is a purely mechanical process once you get the idea. Simply look at the table and write the corresponding code.</p><figure class="kg-card kg-code-card"><pre><code class="language-c">extern int main(void);
extern unsigned int _stack;

void blocking_handler(void) { while (1); }
void null_handler(void) {}

__attribute__ ((section(&quot;.vectors&quot;)))
struct {
	unsigned int* initial_stack_pointer; // 0x00
	void (*reset)(void);                 // 0x04
	void (*nmi)(void);                   // 0x08
	void (*hard_fault)(void);            // 0x0C
	void (*reserved_0x0010[7])(void);    // 0x10
	void (*sv_call)(void);               // 0x2C
	void (*reserved_0x0030[2])(void);    // 0x30
	void (*pend_sv)(void);               // 0x38
	void (*systick)(void);               // 0x3C
	void (*irq[32])(void);               // 0x40
} vector_table = {
	.initial_stack_pointer = &amp;_stack,
	.reset = main,
	.nmi = null_handler,
	.hard_fault = blocking_handler,
	.sv_call = null_handler,
	.pend_sv = null_handler,
	.systick = null_handler,
	.irq = {
		null_handler, //Window WatchDog
		null_handler, //PVD through EXTI Line detection
		null_handler, //RTC through the EXTI line
		null_handler, //FLASH
		null_handler, //RCC
		null_handler, //EXTI Line 0 and 1
		null_handler, //EXTI Line 2 and 3
		null_handler, //EXTI Line 4 to 15
		null_handler, //Reserved
		null_handler, //DMA1 Channel 1
		null_handler, //DMA1 Channel 2 and Channel 3
		null_handler, //DMA1 Channel 4 and Channel 5
		null_handler, //ADC1, COMP1 and COMP2
		null_handler, //LPTIM1
		null_handler, //Reserved
		null_handler, //TIM2
		null_handler, //Reserved
		null_handler, //Reserved
		null_handler, //Reserved
		null_handler, //Reserved
		null_handler, //TIM21
		null_handler, //Reserved
		null_handler, //Reserved
		null_handler, //I2C1
		null_handler, //Reserved
		null_handler, //SPI1
		null_handler, //Reserved
		null_handler, //Reserved
		null_handler, //USART2
		null_handler, //LPUART1
		null_handler, //Reserved
		null_handler, //Reserved
	}
};</code></pre><figcaption>boot.c</figcaption></figure><p>Now all is left is to add this file to the CMakeLists.txt, compile, and upload the <code>program.elf</code> to the MCU.</p><h2 id="conclusion">Conclusion</h2><p>This concludes the setup (oof) for writing code for MCU&apos;s without relying on any IDE. This setup is not a complete one, for a full-scale usage of the MCU it needs to be expanded. Also, it is missing other important bits of setup required for other features of the C language. I might cover that in other articles.</p><h2 id="links">Links</h2><ul><li>Github repo with the code I have written - <a href="https://github.com/Teivaz/cmake-stm32">https://github.com/Teivaz/cmake-stm32</a></li><li>The article that inspired me and helped get going - <a href="https://geokon-gh.github.io/bluepill/">https://geokon-gh.github.io/bluepill/</a></li><li>The online store where I buy my parts and development boards - <a href="https://eu.mouser.com/STMicroelectronics/Embedded-Solutions/Engineering-Tools/Embedded-Processor-Development-Kits/Development-Boards-Kits-ARM/_/N-cxd2t?P=1z0zpefZ1z0yx1g&amp;Ns=Pricing%7c0">https://eu.mouser.com/</a></li><li>The linker scripts documentation <a href="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/scripts.html">https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/4/html/Using_ld_the_GNU_Linker/scripts.html</a></li></ul>]]></content:encoded></item></channel></rss>