
Bare-Metal Embedded C Programming
Description
Alles über E-Books | Antworten auf Fragen rund um E-Books, Kopierschutz und Dateiformate finden Sie in unserem Info- & Hilfebereich.
- Understand hardware intricacies to minimize your dependency on third-party libraries
- Navigate microcontroller manuals with ease and learn to write optimized code
- Purchase of the print or Kindle book includes a free PDF eBook
Book DescriptionBare-Metal Embedded C Programming takes you on an unparalleled journey to equip you with the skills and knowledge to excel in the world of embedded systems. The author, with over a decade of hands-on experience in engineering, takes a unique, practical approach to teach you how to decode microcontroller datasheets so that you're able to extract vital information for precise firmware development. Register manipulation will become second nature to you as you learn to craft optimized code from scratch. The book provides in-depth insights into the hardware intricacies of microcontrollers. You'll navigate user manuals and documentation with ease, ensuring a profound understanding of the underlying technology. The true uniqueness of this book lies in its commitment to fostering independent expertise. Instead of simply copy pasting, you'll develop the capability to create firmware with confidence, paving the way for professional-grade mastery. By the end of this book, you'll have honed your skills in reading datasheets, performing register manipulations, and crafting optimized code, as well as gained the confidence needed to navigate hardware intricacies and write optimized firmware independently, making you a proficient and self-reliant embedded systems developer.What you will learn - Decode microcontroller datasheets, enabling precise firmware development
- Master register manipulations for optimized Arm-based microcontroller firmware creation
- Discover how to navigate hardware intricacies confidently
- Find out how to write optimized firmware without any assistance
- Work on exercises to create bare-metal drivers for GPIO, timers, ADC, UART, SPI, I2C, DMA, and more
- Design energy-efficient embedded systems with power management techniques
Who this book is forWhether you're an experienced engineer seeking in-depth expertise in decoding datasheets, precise register manipulations, and creating firmware from scratch, or a software developer transitioning to the embedded systems domain, this book is your comprehensive guide. It equips you with the practical skills needed for confident, independent firmware development, making it an essential resource for professionals and enthusiasts in the field.
All prices
More details
Other editions
Additional editions

Persons
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.
Content
- Intro
- Preface
- Cover
- Title Page
- Copyright and credits
- Foreword
- Contributors
- Table of Contents
- Preface
- Chapter 1: Setting Up the Tools of the Trade
- Getting the most out of this book - get to know your free benefits
- 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 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
- Chapter 19: Unlock Your Book's Exclusive Benefits
- How to unlock these benefits in three easy steps
- 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...
System requirements
File format: ePUB
Copy protection: Adobe-DRM (Digital Rights Management)
System requirements:
- Computer (Windows; MacOS X; Linux): Install the free reader Adobe Digital Editions prior to download (see eBook Help).
- Tablet/smartphone (Android; iOS): Install the free app Adobe Digital Editions or the app PocketBook before downloading (see eBook Help).
- E-reader: Bookeen, Kobo, Pocketbook, Sony, Tolino and many more (not Kindle).
The file format ePub works well for novels and non-fiction books – i.e., „flowing” text without complex layout. On an e-reader or smartphone, line and page breaks automatically adjust to fit the small displays.
This eBook uses Adobe-DRM, a „hard” copy protection. If the necessary requirements are not met, unfortunately you will not be able to open the eBook. You will therefore need to prepare your reading hardware before downloading.
Please note: We strongly recommend that you authorise using your personal Adobe ID after installation of any reading software.
For more information, see our ebook Help page.
File format: ePUB
Copy protection: without DRM (Digital Rights Management)
System requirements:
- Computer (Windows; MacOS X; Linux): Use a reader that can handle the file format ePUB, such as Adobe Digital Editions or FBReader – both free (see eBook Help).
- Tablet/Smartphone (Android; iOS): Install the free app Adobe Digital Editions or the app PocketBook (see eBook Help).
- E-reader: Bookeen, Kobo, Pocketbook, Sony, Tolino and many more (not Kindle).
The file format ePUB works well for novels and non-fiction books – i.e., 'flowing' text without complex layout. On an e-reader or smartphone, line and page breaks automatically adjust to fit the small displays.
This eBook does not use copy protection or Digital Rights Management
For more information, see our eBook Help page.