Mastering LED Control on Raspberry Pi: From Concept to Execution
Written on
Chapter 1: Introduction to Bare Metal Programming
In the previous installment of this series, titled "From Brick to Blink," we explored the board we'll be working with and outlined two essential components for our project: the electronic schematic and the microcontroller's manual.
Note: Throughout this series, terms like "Microcontroller," "SoC" (System on Chip), "CPU," and "Chip" may be used interchangeably. While they are technically distinct, I trust you'll understand.
Now, let's dive into the tools necessary to achieve our goal of making an LED blink. If you're not fluent in "machine language," you'll require a compiler.
Surprisingly, CPUs execute instructions fetched from memory. What kind of instructions? Those defined by the CPU's manufacturer.
In our case, the CPU embedded in the nRF52840 SoC is an ARM Cortex-M4F.
Note: Nordic Semiconductor, the SoC manufacturer, has integrated an ARM CPU into its design. ARM itself does not produce chips; rather, it designs them and licenses these designs to various semiconductor manufacturers.
You might be curious: If ARM CPUs are ubiquitous in mobile phones and other devices, who actually manufactures them? The answer is straightforward: ARM designs CPUs and charges a licensing fee to chip makers, like Nordic Semiconductor, to use their designs.
Now, back to our focus. Since our CPU is ARM-based, the executable instructions will be determined by ARM's specifications. You can find the instructions for the ARM Cortex-M4F HERE.
If you checked the link, you may find it a bit daunting. Don't worry; I'm here to clarify.
To program a CPU, you can take one of three approaches:
- Write in Machine Code: Technically possible, but akin to "watching The Matrix" as you'd need to manually input binary codes into a file—let's skip this option!
- Use Assembler: This language is more human-readable (though still challenging). However, to convert assembly code to machine code, a translator (like the GNU Assembler) is necessary.
- Write in a High-Level Language: Languages such as C/C++ or Rust are user-friendly. However, a compiler is also needed to translate this code into machine-readable format.
Now, let’s address the crucial question: Which compiler should we select?
To make this choice, we must consider two factors:
- The target CPU: ARM Cortex-M4F
- The target system: We have two options, either a Bare-Metal (without an OS) or an OS-based system (typically GNU-Linux or others). Since we want a direct connection to the hardware, Bare-Metal is our choice.
Visiting ARM's toolchain page, we can see two options. Naturally, we need the one that fits our requirements.
Chapter 2: Flashing Code to the Board
Now that we have our toolchain for compiling our code (once it's ready), how do we transfer this binary to the board's flash memory?
Your first option is to use a debugger connected via the JTAG port to upload the application. However, if you lack this hardware, don't worry—there's a second option: using the board's USB port.
Important Note: For USB flashing to work, the board must contain a "bootloader" in its flash memory.
You may be wondering, what exactly is a bootloader? It's a small program in the flash memory that runs before your application.
The bootloader serves two main purposes:
- It listens for "application update" requests via the USB port. If it receives any, it processes the data and updates the application.
- If there are no update requests, it simply executes the application stored in the flash memory.
I will hold off on some technical details regarding the nRF52840's bootloader for now, but don't worry—upcoming posts will delve deeper into this topic.
Summary:
In the prior post, we identified the crucial documents needed to achieve our goal: the board schematics and the SoC reference manual. This post discussed the compiler selection process and how to flash our application onto the board.
In the Next Post:
We will explore the microcontroller SDK, discuss how to support our board using the schematic and reference manual, and cover additional topics that are yet to be determined.
Don't forget, a click on FOLLOW encourages me to continue writing, and perhaps one day I'll produce articles of high quality.
In this video, we demonstrate how to blink an LED using bare-metal assembly on the Raspberry Pi Pico.
This video shows the process of blinking an LED on the Raspberry Pi Zero 2 using bare-metal assembly techniques.