Bare-Metal Embedded C Programming - Israel Gbati - E-Book

Bare-Metal Embedded C Programming E-Book

Israel Gbati

0,0
29,99 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Bare-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.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 521

Veröffentlichungsjahr: 2024

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Bare-Metal Embedded C Programming

Develop high-performance embedded systems with C for Arm microcontrollers

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.

Software/hardware covered in the book

Operating system requirements

STM32CubeIDE

Windows

GNU Arm Embedded Toolchain

NUCLEO-411 Development Board

10k Potentiometer

OpenOCD

Notepad++

RealTerm

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 purchaseThat’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 microcontrollersThe development boardDatasheets and manuals – unraveling the detailsNavigating the STM32CubeIDE

Technical requirements

The following are the prerequisites for the chapter:

STM32CubeIDE: https://www.st.com/en/development-tools/stm32cubeide.htmlGNU Arm Embedded Toolchain (gcc-arm-none-eabi-10.3-2021.10-win32.exe): https://developer.arm.com/downloads/-/gnu-rmOpenOCD: https://github.com/xpack-dev-tools/openocd-xpack/releasesNotepad++: 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.pdfSTM32F411 datasheet: https://www.st.com/resource/en/reference_manual/rm0383-stm32f411xce-advanced-armbased-32bit-mcus-stmicroelectronics.pdfNUCLEO-F411 user manual: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdfCortex-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 HoldingsSTM32CubeIDE: Developed by STMicroelectronicsIAR 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.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 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 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 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 option

Click Finish to finalize the setup.

Setting up OpenOCD

For firmware development with the GNU Arm Toolchain, OpenOCD plays an integral role, facilitating both the downloading of firmware into our microcontroller and the debugging of code in real time.

Let’s set up OpenOCD:

Launch your web browser and navigate to https://openocd.org/pages/getting-openocd.html.Scroll to the section titled Unofficial binary packages.Click on the link for multiplatform binaries.

Figure 1.6: The Unofficial binary packages section

Identify the latest version compatible with your operating system. For an exhaustive list, click on Show all 14 assets.

Figure 1.7: The OpenOCD packages

For Windows users, download the win32-x64.zip version. For Linux or macOS users, download the corresponding .tar file for your operating system.Once downloaded, unzip the package.Navigate to the extracted folder, and then the bin subfolder. Here, you’ll find the openocd.exe application. This is the application we shall call in the command prompt together with the specific script of our chosen microcontroller, in order to debug or download code onto the microcontroller.

Within the xpack-openocd-0.12.0-2 | openocd | scripts directory structure, you’ll find scripts tailored for various microcontrollers and development boards.

Next, we need to add OpenOCD to our environment variables:

Begin by relocating the entire openocd folder to your Program Files directory.

Figure 1.8: OpenOCD moved to Program Files, showing the path to the bin folder

Copy the path to the openocd bin folder.Right-click on This PC, and then choose Properties.Search for and select Edit the system environment variables.

Figure 1.9: The This PC properties page

Click the Environment Variables button in the System Propertiespop-up window.

Figure 1.10: The System Properties pop-up window

Under the User variables section of the Environment Variables popup, double-click the Path entry.

Figure 1.11: The Environment Variables popup

In the Edit environment variable popup, click on New to create a row for a new path entry.Paste the previously copied OpenOCD path into this new row.Confirm your changes by clicking OK on the various pop-up windows.

Figure 1.12: The Edit environment variable popup

Finally, we have successfully completed the setup process. We have configured two essential, standalone tools to develop firmware for STM32 microcontrollers – the STM32CubeIDE for an IDE, and the GNU Arm Embedded Toolchain, complemented by OpenOCD, to develop and debug our firmware without an IDE.

Next, we will turn our attention to our development board.

The development board

In this segment of the chapter, we will delve into the specifications and features of the development board selected for this book.

Understanding the role of a development board

Firstly, let’s clarify the concept of a development board. It’s essential to note that a development board is not synonymous with a microcontroller. While a development board might derive part of its name from the microcontroller mounted on it, it would be a misnomer to refer to the board itself as the microcontroller. A development board allows us to validate our firmware on the exact microcontroller variant we aim to deploy in our final product. Consequently, the firmware tested on our development board is assured to operate identically on the microcontroller in the end product. This is why companies such as STMicroelectronics offer a diverse range of development boards, tailored to each microcontroller in their portfolio.

It’s also essential to contrast the role of a development board with prototyping boards, such as Arduino. While prototyping boards (which might not house the microcontrollers intended for the final product) serve as preliminary testing platforms, development boards elevate this process. They enable us to rigorously test concepts and the performance evaluation of our firmware on the designated microcontroller meant for bulk product manufacturing. For the purposes of this book, our focus will be on the NUCLEO-F411 development board.

An overview of the NUCLEO-F411 Development Board

The NUCLEO-F411 development board is equipped with an STM32F411RE microcontroller, capable of a peak operating frequency of 100MHz. It comes with a generous 512 Kbytes of flash memory and 128 Kbytes of SRAM. Furthermore, the board is equipped with several columns of berg pins, allowing us to effortlessly make connections using jumper wires to interface with a variety of modules and components – from sensors and motors to LEDs. For quick and straightforward input/output firmware tests, the board also features a built-in user button and LED, eliminating the immediate need for external components.

Figure 1.13: The NUCLEO-F411 development board

Now that we’re familiar with the development board, let’s delve into the various types of documentation that are essential for a comprehensive understanding and programming of thedevelopment board.

Datasheets and manuals – unraveling the details

Our main objective in this book is to write firmware code that interacts directly with the registers of our microcontroller. This means there’s no abstraction or intermediary library between our code and the target microcontroller. To achieve this, it’s important to grasp the internal architecture of the microcontroller, understand the addresses of each register we interact with, and know the functions of relevant bits within those registers. This is where datasheets and manuals come in. Manufacturers provide these documents for users to understand their products, which in our case refers to the microcontroller core architecture, the microcontroller, and the development board.

Two distinct companies play roles in the making of our development board. The first is ARM Holdings, which licenses processor and microcontroller core architecture designs to semiconductor manufacturing firms such as STMicroelectronics, Texas Instruments, and Renesas. These manufacturers then produce the physical microcontroller or processor based on the licensed designs from ARM, often with their custom additions. This explains why two different microcontrollers from separate manufacturers might share the same microcontroller core. For instance, both the TM4C123 from Texas Instruments and STM32F4 from STMicroelectronics are based on the ARM Cortex-M4 core.

Since our chosen development board, the NUCLEO-F411 from STMicroelectronics, is based on the ARM Cortex-M4 microcontroller core, in the following sections, we’ll delve into the documentation for the board, its integrated microcontroller, and the underlying core.

Understanding STMicroelectronics’ documentation

A significant reason for the popularity of STM32 microcontrollers is STMicroelectronics’ continued commitment to providing comprehensive support. This includes well-organized documentation and various firmware development resources.

STMicroelectronics has a range of documents, each following a specific naming convention. Let’s discuss those relevant to our work:

Reference Manual (RM): All RMs start with the letters RM, followed by a number. For instance, the RM for our microcontroller is RM0383. This document details every register in our microcontroller, clarifying each bit’s role and providing insights on register configurations.Datasheet: The datasheet is named after the microcontroller, so for the STM32F411 microcontroller, the datasheet is simply called STM32F411. This document provides a functional overview of the microcontroller, a complete memory map, a block diagram showcasing the microcontroller’s peripherals and connecting buses, as well as the pinout and electrical characteristics of the microcontroller.UM (User Manual): Starting with the letters UM and followed by a number, such as UM1724 for our NUCLEO-F411, this document focuses on the development board. It describes how components on our board, such as LEDs and buttons, are connected to specific ports and pins of the microcontroller.

The generic user guide by ARM

ARM provides documents for every microcontroller and processor core they design. Important to our discussion is the generic user guide for our microcontroller core. As we’re using the STM32F411, which is based on the ARM Cortex-M4 core, we’ll refer to the Cortex-M4 generic user guide.

This means that if we were using an STM32F7 microcontroller, which is based on the ARM Cortex-M7 core, then we would need to get the Cortex-M7 generic user guide. The naming convention of this document is simply the name of the microcontroller core + the phrase generic user guide.

As the name implies, this document provides information generic to the specific microcontroller core. This means that the information provided in the Cortex-M4 generic user guide applies to all microcontrollers based on the Cortex-M4 core, irrespective of the manufacturers of those microcontrollers. In contrast, the information provided in the STMicroelectronics documentation applies to only STMicroelectronics’ microcontrollers.

Figure 1.14: The relationship between the development board, microcontroller, and microcontroller core

Why do we need the generic user guide?

The generic user guide provides information on the core peripherals of the processor core. As the term suggests, these core peripherals are consistent across all microcontrollers, based on a specific core. The Cortex-M4 core has five core peripherals – the System Timer, Floating-Point Unit, System Control Block, Memory Protection Unit, and the Nested Vectored Interrupt Controller. When developing bare-metal drivers for these peripherals, the generic user guide is the definitive source for the essential details.

Additionally, the guide provides information on the microcontroller core’s Instruction Set, as well as the Programmer’s Model, Exception Model, fault handling, and power management.

Getting the documents

To obtain the aforementioned documents, you can use the following search phrases on Google:

RM: Either STM32F11 Reference Manualor RM0383.Datasheet: STM32F411 Datasheet.UM: Nucleo-F11 User Manualor UM1724.Generic user guide: Cortex-M4 Generic User Guide

Direct links to these documents are also available, in the Technical requirements section of this chapter.

Before analyzing the key areas of the various documents to program our development board, let’s first take a closer look at the STM32CubeIDE we installed earlier. We will familiarize ourselves with its features and functionalities in the next section.

Navigating the STM32CubeIDE

When you launch STM32CubeIDE for the first time, you’ll see the Information Center. This center offers quick access to a number of valuable resources for STM32 firmware development.

To exit the Information Center, simply click the X on its tab. If you wish to revisit it later, simply navigate to Help | Information Center.

Figure 1.15: Information Center

The STM32CubeIDE is based on the Eclipse framework, and therefore, the layout and elements are similar to those of other Eclipse-based IDEs.

Let’s go through the process of creating a new project:

Either click Create a New STM32 project in the empty Project Explorer pane or select File | New | STM32 Project.

Figure 1.16: A workspace showing an empty Project Explorer pane

You will be presented with the Target Selection window to select the microcontroller or development board for your project.Click the Board Selector tab.Enter NUCLEO-F411 into the Commercial Part Number field.

Figure 1.17: The Target Selection window

From the displayed board list, select NUCLEO-F11RE, and then click Next.

Figure 1.18: The board list with NUCLEO-F411 selected

Give the project a name.For Targeted Project Type, select Empty.

Figure 1.19: The Setup STM32 project window

Click Finish to create the project.

You will see the new project, containing all the necessary startup files and linker scripts, in the Project Explorer pane.

Figure 1.20: The Project Explorer pane showing a new project

Understanding the control icons

The most frequently used control icons are the New, Build, and Debug icons.

Figure 1.21: The control icons

Let’s look closely at the functions of these icons:

The New icon: This icon allows us to create various files, including source code, header files, projects, libraries, and more. This function is also accessible via File | New.The Build icon: Used for building projects. This functionality can also be accessed by right-clicking on a project and selecting Build Project.The Debug icon: This launches a debug configuration to facilitate project debugging. This functionality is also available by right-clicking a project and selecting Debug Project.

These control icons provide quick access to essential functions, significantly enhancing productivity and streamlining the development process.

Summary

In this chapter, we set out to create a robust environment for embedded firmware development, focusing on the careful selection and setup of essential tools. Each tool we selected plays a crucial role in the efficient development of firmware for microcontrollers. We explored the installation processes of STM32CubeIDE, the GNU Arm Embedded Toolchain, and OpenOCD, laying a solid groundwork for our development activities.

We then introduced the NUCLEO-F411 development board, equipped with an STM32F411RE microcontroller, as our experimental platform, and we spent time identifying some of the components on the board.

We also emphasized the importance of knowing the different types of datasheets and reference manuals, equipping us with the ability to quickly access detailed information about a microcontroller’s architecture and functionalities.

Moving on to the next chapter, we will leap into developing our first bare-metal firmware, using only the documentation we have compiled as our guide.