Bare-Metal Embedded C Programming: Develop high-performance embedded systems with C for Arm microcontrollers
()
Related to Bare-Metal Embedded C Programming
Related ebooks
Mastering Embedded C: The Ultimate Guide to Building Efficient Systems Rating: 0 out of 5 stars0 ratingsEmbedded Rust Programming: Building Safe and Efficient Systems Rating: 0 out of 5 stars0 ratingsEmbedded Systems Programming with C++: Real-World Techniques Rating: 0 out of 5 stars0 ratingsRust for Embedded Systems Rating: 0 out of 5 stars0 ratingsArduino: Building Intelligent Systems with Microcontroller Programming Rating: 0 out of 5 stars0 ratingsThe FPGA Programming Handbook: An essential guide to FPGA design for transforming ideas into hardware using SystemVerilog and VHDL Rating: 0 out of 5 stars0 ratingsComputerised Systems Architecture: An embedded systems approach Rating: 0 out of 5 stars0 ratingsESP32 Programming for the Internet of Things: JavaScript, AJAX, MQTT and WebSockets Solutions Rating: 5 out of 5 stars5/5Simulation-Driven Electronics Design: The easy way to design your own electronics projects (English Edition) Rating: 0 out of 5 stars0 ratingsArduino Projects with Tinkercad: Designing and programming Arduino-based electronics projects using Tinkercad Rating: 0 out of 5 stars0 ratingsProgramming Arduino with LabVIEW Rating: 3 out of 5 stars3/5Embedded Systems Programming with C: Writing Code for Microcontrollers Rating: 0 out of 5 stars0 ratingsBackpropagation: Fundamentals and Applications for Preparing Data for Training in Deep Learning Rating: 0 out of 5 stars0 ratingsMulticore DSP: From Algorithms to Real-time Implementation on the TMS320C66x SoC Rating: 0 out of 5 stars0 ratingsLearning BeagleBone Rating: 0 out of 5 stars0 ratingsEmbedded Expert's Guide to C Rating: 0 out of 5 stars0 ratingsLabVIEW – More LCOD Rating: 0 out of 5 stars0 ratingsLearn Digital and Microprocessor Techniques On Your Smartphone: Portable Learning, Reference and Revision Tools. Rating: 0 out of 5 stars0 ratingsWow! What a Ride!: A Quick Trip Through Early Semiconductor and Personal Computer Development Rating: 0 out of 5 stars0 ratingsLogic synthesis Standard Requirements Rating: 0 out of 5 stars0 ratingsPython AI Programming Rating: 0 out of 5 stars0 ratingsProfessional Embedded ARM Development Rating: 0 out of 5 stars0 ratingsArduino for the Cloud:: Arduino Yun and Dragino Yun Shield Rating: 0 out of 5 stars0 ratingsProjects With Microcontrollers And PICC Rating: 5 out of 5 stars5/5Finite-state machine A Complete Guide Rating: 0 out of 5 stars0 ratingsThe official Raspberry Pi Camera Module guide Rating: 0 out of 5 stars0 ratingsFundamentals of IoT: Get familiar with the building blocks of IoT (English Edition) Rating: 0 out of 5 stars0 ratingsArduino meets MATLAB: Interfacing, Programs and Simulink Rating: 0 out of 5 stars0 ratings
Programming For You
SQL QuickStart Guide: The Simplified Beginner's Guide to Managing, Analyzing, and Manipulating Data With SQL Rating: 4 out of 5 stars4/5Python: Learn Python in 24 Hours Rating: 4 out of 5 stars4/5Coding All-in-One For Dummies Rating: 4 out of 5 stars4/5JavaScript All-in-One For Dummies Rating: 5 out of 5 stars5/5Excel : The Ultimate Comprehensive Step-By-Step Guide to the Basics of Excel Programming: 1 Rating: 5 out of 5 stars5/5Python Programming : How to Code Python Fast In Just 24 Hours With 7 Simple Steps Rating: 4 out of 5 stars4/5SQL All-in-One For Dummies Rating: 3 out of 5 stars3/5PYTHON: Practical Python Programming For Beginners & Experts With Hands-on Project Rating: 5 out of 5 stars5/5PYTHON PROGRAMMING Rating: 4 out of 5 stars4/5Learn to Code. Get a Job. The Ultimate Guide to Learning and Getting Hired as a Developer. Rating: 5 out of 5 stars5/5Microsoft Azure For Dummies Rating: 0 out of 5 stars0 ratingsAlgorithms For Dummies Rating: 4 out of 5 stars4/5Linux: Learn in 24 Hours Rating: 5 out of 5 stars5/5Learn SQL in 24 Hours Rating: 5 out of 5 stars5/5Python for Data Science For Dummies Rating: 0 out of 5 stars0 ratingsBeginning Programming with C++ For Dummies Rating: 4 out of 5 stars4/5Python Games from Zero to Proficiency (Beginner): Python Games From Zero to Proficiency, #1 Rating: 0 out of 5 stars0 ratings
Reviews for Bare-Metal Embedded C Programming
0 ratings0 reviews
Book preview
Bare-Metal Embedded C Programming - Israel Gbati
Bare-Metal Embedded C Programming
Copyright © 2024 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.
Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.
Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
Group Product Manager: Kunal Sawant
Publishing Product Manager: Akash Sharma
Book Project Manager: Prajakta Naik
Senior Editor: Nithya Sadanandan
Technical Editor: Vidhisha Patidar
Copy Editor: Safis Editing
Proofreader: Nithya Sadanandan
Indexer: Tejal Soni
Production Designer: Vijay Kamble
Senior DevRel Marketing Executive: Shrinidhi Manoharan
Business Development Executive: Kriti Sharma
First published: September 2024
Production reference: 1130924
Published by Packt Publishing Ltd.
Grosvenor House
11 St Paul’s Square
Birmingham
B3 1RB, UK.
ISBN 978-1-83546-081-8
www.packtpub.com
To my dearest sister, Salome Gbati — a beacon of unwavering strength and grace. Your resilience is a quiet, unshakable force, reminding me that even in the face of life’s greatest challenges, we rise, we endure, and we thrive.
- Israel Gbati
Foreword
Around the time Israel and I first began working together, we were preparing to showcase our non-contact gesture trackpad at the British Invention Show. With only two weeks to get ready, most of our time was spent soldering components and assembling mechanical systems for the presentation. The firmware, however, was left until the final stretch. With just one day remaining, we braced for an all-nighter, taking turns debugging the code with the persistence of parents tending to a restless child. In the final hours, with our eyes half-closing, Israel made a critical breakthrough, pulling everything together just in time. Though we arrived late to the event, we walked away with the Platinum Award.
I’ve had the privilege of working alongside Israel for nearly a decade, acting as his tag team partner in this fascinating world of hardware, where electronics and mechanical design harmoniously blend with firmware and software to create technology at the cutting edge of innovation.
Israel truly practices what he preaches. The teachings in this book are actively tested and applied in the field to advance technology aimed at improving the quality of life for individuals facing various health challenges. There is nothing more relevant today than an engineering text written by an active practitioner, especially in the midst of the most fast-paced and dynamic engineering environment in human history. What you hold in your hands is the culmination of years of dedicated effort, driven by both knowledge and real-world applications that extend far beyond theory into the practical challenges of technological entrepreneurship.
I hope this book serves as a valuable resource and inspiration for all who seek to push the boundaries of engineering and technology.
Georgios Papanikolaou
Chief Operating Officer and Head of Hardware Engineering, BiostealthAI
Contributors
About the author
Israel Gbati is a distinguished firmware engineer boasting over a decade of hands-on experience in the field. Throughout his career, he has shared his profound knowledge to more than 100,000 professionals, helping to shape the next generation of experts. In addition to his engineering expertise, Israel is an entrepreneur and an award-winning inventor, recognized for his exceptional inventions. He holds a Bachelor’s degree in Mechanical Engineering and Automation, complemented by a double Masters degree in Global Innovation Design from Imperial College London and the Royal College of Arts. Israel is the founder of EmbeddedExpertIO and the cofounder of BiostealthAI, further demonstrating his leadership and commitment to advancing technological innovation.
To my incredible colleagues at BiostealthAI and EmbeddedExpertIO, thank you for embodying the true spirit of professionalism and for your unwavering dedication to our shared mission. Your commitment has not only made our work rewarding but has also created an environment where collaboration and innovation thrive for the greater good.
A special note of gratitude to Mohamed Alezzabi, Olivier Tsiakaka, Ph.D., Georgios Papanikolaou, Desmond Boakye Tanoh, M.D., Husamuldeen Al-Daffaie, and Muhammad Sohan Mollah. Your expertise, support, and camaraderie have been the cornerstone of this journey. Together, we continue to push the boundaries of what’s possible.
About the reviewer
Akshay Phadke started his journey as a Software Engineer after graduating with a Master of Science in Electrical and Computer Engineering from the Georgia Institute of Technology in 2016. He has developed data-intensive applications and experiences across different industries, including Networking and Telecommunications, Enterprise Software, and Finance. His expertise encompasses multiple areas of Software Development such as Big Data, Data and Platform Engineering, CI/CD and DevOps, Developer Productivity and Tooling, Infrastructure and Observability, and Full Stack Web Development. Akshay’s professional interests include Open Source Software, Distributed Systems, and Building and Scaling Products in a Startup Environment.
Table of Contents
Preface
1
Setting Up the Tools of the Trade
Technical requirements
Essential development tools for microcontrollers
Setting up the STM32CubeIDE
Setting up the GNU Arm Embedded Toolchain
Setting up OpenOCD
The development board
Understanding the role of a development board
An overview of the NUCLEO-F411 Development Board
Datasheets and manuals – unraveling the details
Understanding STMicroelectronics’ documentation
The generic user guide by ARM
Getting the documents
Navigating the STM32CubeIDE
Understanding the control icons
Summary
2
Constructing Peripheral Registers from Memory Addresses
Technical requirements
The different types of firmware development
HAL
LL
Bare-Metal C
Assembly language
Locating and understanding the development board’s components
Locating the LED connection
Locating the User Push button
Locating the berg pins and Arduino-compatible headers
Defining and creating registers through documentation insights
Locating GPIO PORTA
Clock gating
The AHB1 ER
Setting and clearing bits in registers
The GPIO port mode register (GPIOx_MODER)
GPIO Port Output Data Register (GPIOx_ODR)
Register manipulation – from configuration to running your first firmware
Register Definitions
The UL suffix
Main Function
Summary
3
Understanding the Build Process and Exploring the GNU Toolchain
Technical requirements
The foundations – understanding the embedded build process
The pre-processing stage
The compilation stage
The assembly stage
The linking stage
The locating stage
A tour of GNU binary tools for embedded systems
arm-none-eabi-gcc
Some common compiler flags
Some architecture-specific flags
Other commands in the GNU Toolchain for Arm
From IDE to the command line – watching the build process unfold
Observing the build process from the IDE’s perspective
Compilation of assembly and C files
Working with the GNU bin tools
Uploading firmware to the microcontroller using OpenOCD
Summary
4
Developing the Linker Script and Startup File
Technical requirements
Understanding the STM32 memory model
Flash memory
SRAM
Peripheral memory
The linker script
Understanding the linking process
Key components of the linker script
Linker script directives
Understanding constants in linker scripts
Linker script symbols
Writing the linker script and startup file
Understanding the load memory of different sections
Interrupts and the vector table
Writing the linker script
Writing the startup file
Testing our linker script and startup file
Summary
5
The Make
Build System
Technical requirements
An introduction to build systems
Make
Maven
The Make build system
The basics of Make
Installing and configuring Make
Writing Makefiles for firmware projects
Testing our Makefile
Applying special and user-defined variables
Summary
6
The Common Microcontroller Software Interface Standard (CMSIS)
Technical requirements
Defining peripheral registers with C structures
Getting the base address and offsets of registers
Implementing the peripheral structures
Evaluating the structure-based register access method
Understanding CMSIS
What is CMSIS?
Key components of CMSIS
The CMSIS coding rules
The CMSIS-Core files
Setting up the required CMSIS files
Getting the right header files
Working with CMSIS files
Summary
7
The General-Purpose Input/Output (GPIO) Peripheral
Technical requirements
Understanding the GPIO peripheral
The STM32 GPIO registers
The GPIO mode register (GPIOx_MODER)
The GPIO output data register (GPIOx_ODR) and the GPIO input data register (GPIOx_IDR)
The GPIO bit-set/reset register (GPIOx_BSRR)
The GPIO alternate function registers (GPIOx_AFRL and GPIOx_AFRH)
Developing input and output drivers
The GPIO output driver using the BSRR
The GPIO input driver
Summary
8
System Tick (SysTick) Timer
Technical requirements
Introduction to the SysTick timer
Overview of the SysTick timer
SysTick timer registers
Developing a driver for the SysTick timer
Summary
9
General-Purpose Timers (TIM)
Technical requirements
Introduction to timers and their uses
Common use cases of timers
Time interval measurement
Delay generation
Event trigger
STM32 timers
Introduction to general-purpose timers and advanced timers
How STM32 timers work
Developing the timer driver
Summary
10
The Universal Asynchronous Receiver/Transmitter Protocol
Technical requirements
Introduction to communication protocols
What are communication protocols?
Comparing UART, SPI, and I2C
Common use cases for the UART, SPI, and I2C protocols
Overview of the UART protocol
What is UART?
The interface
How UART works
The STM32F4 UART peripheral
Developing the UART driver
Summary
11
Analog-to-Digital Converter (ADC)
Technical requirements
Overview of analog-to-digital conversion
What is analog-to-digital conversion?
Key specifications of the ADC – resolution, step size, and VREF
The STM32F4 ADC peripheral
The ADC channels
Understanding regular channels versus injected channels in STM32F411 ADC
The key ADC registers and flags
ADC Control Register 1 (ADC_CR1)
ADC Control Register 2 (ADC_CR2)
ADC Regular Sequence Register (ADC_SQRx)
ADC Data Register (ADC_DR)
ADC Status Register (ADC_SR)
The key ADC flags
Developing the ADC driver
Summary
12
Serial Peripheral Interface (SPI)
Technical requirements
Overview of the SPI protocol
What is SPI?
Key features of SPI
The SPI interface
How SPI works
CPHA and CPOL
Data modes
SPI speed
The STM32F4 SPI peripherals
Key features
Key SPI registers
Developing the SPI driver
Defined macros
GPIO initialization for SPI
SPI1 configuration
Transmitting data with SPI
SPI data reception
CS management
The header file
Getting to know the ADXL345 accelerometer
Understanding key concepts – static acceleration of gravity, tilt-sensing, and dynamic acceleration
Developing the ADXL345 driver
Summary
13
Inter-Integrated Circuit (I2C)
Technical requirements
An overview of the I2C protocol
What is I2C?
The STM32F4 I2C peripherals
The key I2C registers
Developing the I2C driver
Summary
14
External Interrupts and Events (EXTI)
Technical requirements
Interrupts and their role in firmware
What are interrupts?
How do interrupts work?
Importance of interrupts in firmware
Interrupts versus exceptions
Comparative analysis—interrupt-driven solutions versus polling-based solutions
The STM32 EXTI controller
Key features of the EXTI
External interrupt/event line mapping
Developing the EXTI driver
EXTI_IMR
EXTI_RTSR
EXTI_FTSR
Pending Register (EXTI_PR)
The EXTI driver
Summary
15
The Real-Time Clock (RTC)
Technical requirements
Understanding RTCs
How do RTCs work?
Common use cases for RTCs
The STM32 RTC module
The main features of the STM32F4 RTC module
The key components of the STM32F4 RTC module
Some key RTC registers
RTC Time Register (RTC_TR)
RTC Date Register (RTC_DR)
RTC Control Register (RTC_CR)
RTC Initialization and Status Register (RTC_ISR)
RTC Prescaler Register (RTC_PRER)
RTC Alarm Registers (RTC_ALRMAR and RTC_ALRMBR)
RTC Wakeup Timer Register (RTC_WUTR)
Developing the RTC driver
The RTC implementation file
Understanding BCD format
The header file
The main file
Summary
16
Independent Watchdog (IWDG)
Technical requirements
Understanding WDTs
What are WDTs?
How WDTs work
Common use cases
Types of WDTs
The STM32 IWDG
Key features of the IWDG
How the IWDG works
IWDG registers
Developing the IWDG driver
The IWDG implementation file
The main file
Testing the project
Summary
17
Direct Memory Access (DMA)
Technical requirements
Understanding Direct Memory Access (DMA)
How DMA works
Key features
Common use cases
The DMA modules of the STM32F4 microcontroller
The key features of the STM32F4 DMA controller
Transfer modes
DMA data modes
The STM32F4 DMA block diagram
The key STM32 DMA registers
Developing the ADC DMA driver
The ADC DMA driver
Developing the UART DMA driver
Developing the DMA memory-to-memory driver
Summary
18
Power Management and Energy Efficiency in Embedded Systems
Technical requirements
An overview of power management techniques
Dynamic Voltage and Frequency Scaling (DVFS)
Clock gating
Power gating
Low-power modes
Case study 1 – an energy-efficient smartwatch
Case study 2 – a solar-powered environmental monitor
Low-power modes in STM32F4
Wake-up sources and triggers from low-power modes in STM32F4
Understanding wake-up sources
Practical considerations
Developing a driver to enter standby mode and wake up
Summary
Index
Other Books You May Enjoy
Preface
In a tech-driven world where embedded systems power nearly every modern device and innovation, the ability to develop efficient and reliable firmware is a prized skill. The journey from writing basic code to mastering low-level firmware development can be daunting, but the rewards are substantial. Whether it’s a home appliance, an industrial control system, or a sophisticated IoT device, embedded systems serve as the silent, hardworking engines behind modern technology.
This book, Bare-Metal Embedded C Programming, was born out of a desire to help you not only write functional firmware but also to deeply understand the underlying mechanisms that govern how microcontrollers work at their core. My goal is to take you on an in-depth, technical journey into the heart of ARM-based microcontroller firmware development, specifically focusing on the STM32 family. This is not a book for the faint of heart, nor is it one for those looking for quick shortcuts. Instead, it is designed for individuals who are ready to step away from the comforts of pre-built libraries and tools to develop the skills necessary for writing efficient, bare-metal code from scratch.
So, what exactly is bare-metal programming? Simply put, it’s the art of writing firmware that interacts directly with the hardware—without the abstraction layers provided by third-party libraries. This approach requires precision, a deep understanding of microcontroller architecture, and the ability to read and manipulate registers to achieve the exact behavior you want from your hardware.
Why I Wrote This Book
As someone with years of experience in embedded systems development, I’ve often noticed a gap in the way firmware development is taught. Many texts and courses focus on high-level development, promoting the use of pre-built libraries that abstract away the complexities of hardware interaction. While this approach is undoubtedly convenient and practical in many cases, it leaves a void for those who truly wish to understand how things work at the lowest level. I believe that understanding the bare-metal
aspect of embedded systems development is essential for becoming a truly skilled firmware engineer.
This book is my effort to fill that gap. Through step-by-step guidance, I’ll show you how to build your own drivers, manipulate registers, and write code that takes full control of the microcontroller. This is not just about learning a new skill—it’s about achieving mastery.
Who this book is for
If you’re a developer, engineer, or a student eager to dive deep into the world of microcontroller firmware development, this book is for you. You’ll find it especially valuable if you’re the kind of person who prefers to understand what’s happening under the hood, rather than relying on copy-paste solutions from online forums. Whether you’re transitioning from other platforms or seeking to build a strong foundation in bare-metal development, this book will give you the hands-on experience you need.
What This Book Covers
Chapter 1
, Setting Up the Tools of the Trade
This chapter introduces the essential tools you’ll need for development. From navigating datasheets to setting up your Integrated Development Environment (IDE), this chapter lays the groundwork for everything that follows.
Chapter 2
, Constructing Peripheral Registers from Memory Addresses
In this chapter, we dive into the core of bare-metal programming. You’ll learn how to define and access peripheral registers directly from memory addresses, using the official microcontroller documentation as your guide.
Chapter 3
, Understanding the Build Process and Exploring the GNU Toolchain
In this chapter, we take a closer look at the embedded C build process. You’ll explore how to compile and link code manually using the GNU Toolchain, gaining complete control over how your firmware is created.
Chapter 4
, Developing the Linker Script and Startup File
In this chapter, you will learn how to write a custom linker script to define how your firmware is placed in the microcontroller’s memory, including allocating sections like code, data, and stack. Additionally, you’ll develop a startup file that configures the microcontroller’s initial state, sets up the stack, initializes memory, and jumps to your main code.
Chapter 5
, The Make
Build System
Automating the build process is a critical part of embedded development. This chapter teaches you how to use the Make build system to streamline your workflow by creating custom Makefiles that automate repetitive tasks.
Chapter 6
, The Common Microcontroller Software Interface Standard (CMSIS)
CMSIS simplifies development on ARM Cortex microcontrollers. In this chapter, you’ll learn how to leverage CMSIS to write efficient code that takes advantage of the microcontroller’s features while maintaining simplicity.
Chapter 7
, The General-Purpose Input/Output (GPIO) Peripheral
GPIO allows your microcontroller to interact with external devices. This chapter guides you through developing both input and output drivers for GPIO, one of the most frequently used peripherals in embedded systems.
Chapter 8
, System Tick (SysTick) Timer
Timing is essential in embedded systems, and the SysTick timer provides an easy way to generate precise time delays and system ticks. This chapter walks you through developing SysTick drivers for use in your embedded applications.
Chapter 9
, General-Purpose Timers (TIM)
This chapter introduces you to the general-purpose timers (TIM) in STM32 microcontrollers, teaching you how to develop timer drivers for tasks that require precise timing.
Chapter 10
, The Universal Asynchronous Receiver/Transmitter Protocol
Communication is a key aspect of embedded systems. This chapter focuses on the UART protocol, one of the most widely used communication protocols. You’ll learn how to develop UART drivers, enabling your microcontroller to send and receive data from external devices.
Chapter 11
, Analog-to-Digital Converter (ADC)
Many embedded applications require converting analog signals into digital data that your microcontroller can process. This chapter covers how to configure the ADC peripheral, allowing you to read and convert analog inputs into meaningful digital values.
Chapter 12
, Serial Peripheral Interface (SPI)
SPI is a high-speed communication protocol commonly used in embedded systems. This chapter guides you through developing SPI drivers, enabling efficient communication between your microcontroller and other peripherals, such as sensors or memory devices.
Chapter 13
, Inter-Integrated Circuit (I2C)
I2C is another popular communication protocol for connecting devices, it is often used for short-distance communication in embedded systems. This chapter covers the development of I2C drivers, allowing your microcontroller to communicate with multiple devices over a shared bus.
Chapter 14
, External Interrupts and Events (EXTI)
Responsiveness is critical in embedded systems, and external interrupts allow your system to react to changes in its environment. This chapter covers how to configure and manage external interrupts and events (EXTI) for timely and efficient responses to external stimuli.
Chapter 15
, The Real-Time Clock (RTC)
For systems that require accurate timekeeping, the RTC peripheral is indispensable. In this chapter, you’ll learn how to set up and use the RTC to track time in low-power systems, even when the microcontroller is in sleep mode.
Chapter 16
, Independent Watchdog (IWDG)
Stability is crucial for embedded systems, and the Independent Watchdog Timer (IWDG) ensures that your system can recover from unexpected malfunctions. This chapter teaches you how to configure the IWDG to automatically reset your microcontroller if it stops responding, ensuring reliable operation.
Chapter 17
, Direct Memory Access (DMA)
Direct Memory Access (DMA) allows data transfers to occur independently of the CPU, significantly improving system efficiency. This chapter covers how to configure and use DMA for memory-to-memory transfers, as well as for peripherals like ADC and UART, offloading the work from the CPU.
Chapter 18
, Power Management and Energy Efficiency in Embedded Systems
Power management is essential for energy-efficient systems, especially in battery-powered devices. In this final chapter, you’ll learn techniques for reducing power consumption, including how to use sleep modes, wake-up sources, and optimize firmware to achieve the best balance between performance and energy efficiency.
To get the most out of this book
To fully benefit from this book, it’s important to have a general familiarity with the C programming language. While we’ll cover the specifics of embedded systems programming in detail, having a basic understanding of how code operates will make the material easier to follow. Familiarity with microcontrollers is certainly helpful but not a strict requirement. Everything you need will be introduced as we progress. Whether you’re a beginner or an experienced developer, this book will guide you step-by-step through the fascinating world of bare-metal embedded programming.
If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book’s GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.
Download the example code files
You can download the example code files for this book from GitHub at https://github.com/PacktPublishing/Bare-Metal-Embedded-C-Programming
. If there’s an update to the code, it will be updated in the GitHub repository.
We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/
. Check them out!
Conventions used
There are a number of text conventions used throughout this book.
Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: Copy the path to the openocd bin folder.
A block of code is set as follows:
// 22: Set PA5(LED_PIN) high
GPIOA_OD_R |= LED_PIN;
When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:
// 1: Define base address for peripherals
#define
PERIPH_BASE (0x40000000UL)
// 2: Offset for AHB1 peripheral bus
Any command-line input or output is written as follows:
monitor flash write_image erase 4_makefile_project.elf
Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold. Here is an example: Right-click on This PC, and then choose Properties.
Tips or important notes
Appear like this.
Get in touch
Feedback from our readers is always welcome.
General feedback: If you have questions about any aspect of this book, email us at [email protected]
and mention the book title in the subject of your message.
Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata
and fill in the form.
Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected]
with a link to the material.
If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com
.
Share Your Thoughts
Once you’ve read Bare-Metal Embedded C Programming, we’d love to hear your thoughts! Please click here to go straight to the Amazon review page
for this book and share your feedback.
Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content.
Download a free PDF copy of this book
Thanks for purchasing this book!
Do you like to read on the go but are unable to carry your print books everywhere?
Is your eBook purchase not compatible with the device of your choice?
Don’t worry, now with every Packt book you get a DRM-free PDF version of that book at no cost.
Read anywhere, any place, on any device. Search, copy, and paste code from your favorite technical books directly into your application.
The perks don’t stop there, you can get exclusive access to discounts, newsletters, and great free content in your inbox daily
Follow these simple steps to get the benefits:
Scan the QR code or visit the link below
https://packt.link/free-ebook/9781835460818
Submit your proof of purchase
That’s it! We’ll send your free PDF and other benefits to your email directly
1
Setting Up the Tools of the Trade
In the world of embedded systems, crafting efficient firmware begins with a clear comprehension of the tools available. This chapter will guide you in establishing a robust development environment, ensuring that you are equipped with all the necessary tools for a comprehensive firmware development experience.
Central to our discussion is the concept of datasheets. Consider these as the detailed blueprints for any microcontroller, encompassing its capabilities, specifications, and intricate details. However, the challenge often isn’t merely understanding a datasheet but also sourcing the correct datasheets tailored to your specific microcontroller. To address this, I will assist you in pinpointing and understanding both datasheets and user manuals important to our chosen microcontroller.
As we progress, we’ll delve into the intricacies of setting up our Integrated Development Environment (IDE) and acknowledging its critical function within the development life cycle. Furthermore, you’ll gain insights into configuring the GNU Arm Embedded Toolchain and OpenOCD. These tools will later empower us to craft our firmware, bypassing the need for an IDE altogether.
In this chapter, we will explore the following main topics:
Essential development tools for microcontrollers
The development board
Datasheets and manuals – unraveling the details
Navigating the STM32CubeIDE
Technical requirements
The following are the prerequisites for the chapter:
STM32CubeIDE: https://www.st.com/en/development-tools/stm32cubeide.html
GNU Arm Embedded Toolchain (gcc-arm-none-eabi-10.3-2021.10-win32.exe): https://developer.arm.com/downloads/-/gnu-rm
OpenOCD: https://github.com/xpack-dev-tools/openocd-xpack/releases
Notepad++: https://notepad-plus-plus.org/downloads/v8.5.8/
STM32F11 reference manual: https://www.st.com/resource/en/reference_manual/rm0383-stm32f411xce-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
STM32F411 datasheet: https://www.st.com/resource/en/reference_manual/rm0383-stm32f411xce-advanced-armbased-32bit-mcus-stmicroelectronics.pdf
NUCLEO-F411 user manual: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
Cortex-M4 generic user guide: https://developer.arm.com/documentation/dui0553/latest/
Essential development tools for microcontrollers
In this section, we will explore the essential tools that form the backbone of our development process. Understanding these tools is important, as they will be our companions in transforming ideas into functioning firmware.
When selecting tools for firmware development, we have two primary options.
IDEs: An IDE is a unified software application offering a Graphical User Interface (GUI) tailored to crafting software – in our context, firmware. Popular IDEs for microcontroller firmware development include the following:
Keil uVision (also known as Keil MDK): Developed by ARM Holdings
STM32CubeIDE: Developed by STMicroelectronics
IAR Embedded Workbench: Developed by IAR Systems
These IDEs boast a GUI-centric design, enabling users to conveniently create new files, build, compile, and step through code lines interactively. For the demonstrations and exercises in this book, we’ll use the STM32CubeIDE. It has all the requisite features and is generously available for free, without any code size constraints.
Toolchains: At its core, a toolchain is a cohesive set of development tools, sequenced in distinct stages, to produce the final firmware build for the target microcontroller. This approach bypasses the comfort of a GUI. Instead, firmware is written using basic text editors such as Notepad or Notepad++, with the command line used to execute the various phases of the build process –commands such as assemble, compile, and link are often used. In this book, we’ll use the open source GNU Arm Embedded Toolchain. Based on the renowned open source GNU Compiler Collection (GCC), this integrates a GCC compiler tailored for ARM, the GNU Debugger (GDB) debugger, and several other invaluable utilities.
In the following section, we will carefully go through the process of setting up our preferred IDE, the STM32CubeIDE.
Setting up the STM32CubeIDE
Throughout this book, we’ll use both the STM32CubeIDE and the GNU Arm Embedded Toolchain to develop our firmware. Leveraging an IDE such as STM32CubeIDE enables us to easily analyze and compare the linker script and startup files, autogenerated by the IDE, against those we’ll construct from the ground up.
Let’s start by downloading and installing STM32CubeIDE:
Launch your web browser and navigate to st.com
.
Click on STM32 Developer Zone, and then select STM32CubeIDE.
Figure 1.1: The home page of st.comFigure 1.1: The home page of st.com
Scroll down to the All software versions section of the page and click on Download Software. You’ll need to log into your ST account before proceeding with the download.
Figure 1.2: The All software versions section of the stm32cubeide pageFigure 1.2: The All software versions section of the stm32cubeide page
If you don’t have an account, click on Login/Register to sign up. If you already have one, simply log in.
Complete the registration form with your first name, last name, and email address.
Click on Download to start the download process. A .zip file will be downloaded into your Downloads folder.
Let’s install the STM32CubeIDE:
Unzip the downloaded package.
Double-click the st-stm32cubeide file to initiate the installer.
Retain default settings by clicking Next throughout the setup process.
On the Choose Components page, ensure that both SEGGER J-Link drivers and ST-LINK drivers are selected. Then, click Install.
Figure 1.3: The installer showing the Choose Components pageFigure 1.3: The installer showing the Choose Components page
Having successfully installed STM32CubeIDE on our computer, we will now proceed to configure our alternate development tool, the GNU Arm Embedded Toolchain.
Setting up the GNU Arm Embedded Toolchain
In this section, we will go through the process of setting up the GNU Arm Embedded Toolchain – an important tool for developing firmware for ARM-based microcontrollers:
Launch your web browser and navigate to https://developer.arm.com/downloads/-/gnu-rm
.
Scroll down the page to find the download link appropriate for your operating system. For those of you using Windows, like myself, opt for the .exe version. For Linux or macOS users, choose the corresponding .tar file for your operating system.
After the download completes, double-click the installer to begin the installation process.
Read through the license agreement. Then, choose to install in the default folder location by clicking Install.
Figure 1.4: The GNU Arm Embedded Toolch ain installerFigure 1.4: The GNU Arm Embedded Toolchain installer
When the installation is complete, ensure that you check the Add path to environment variable option.
Figure 1.5: The installer showing the Add path to environment variable optionFigure 1.5: The installer showing the Add path to environment variable option
Click Finish to finalize