Hands-On RTOS with Microcontrollers

Book description

Build a strong foundation in designing and implementing real-time systems with the help of practical examples

Key Features

  • Get up and running with the fundamentals of RTOS and apply them on STM32
  • Enhance your programming skills to design and build real-world embedded systems
  • Get to grips with advanced techniques for implementing embedded systems

Book Description

A real-time operating system (RTOS) is used to develop systems that respond to events within strict timelines. Real-time embedded systems have applications in various industries, from automotive and aerospace through to laboratory test equipment and consumer electronics. These systems provide consistent and reliable timing and are designed to run without intervention for years.

This microcontrollers book starts by introducing you to the concept of RTOS and compares some other alternative methods for achieving real-time performance. Once you've understood the fundamentals, such as tasks, queues, mutexes, and semaphores, you'll learn what to look for when selecting a microcontroller and development environment. By working through examples that use an STM32F7 Nucleo board, the STM32CubeIDE, and SEGGER debug tools, including SEGGER J-Link, Ozone, and SystemView, you'll gain an understanding of preemptive scheduling policies and task communication. The book will then help you develop highly efficient low-level drivers and analyze their real-time performance and CPU utilization. Finally, you'll cover tips for troubleshooting and be able to take your new-found skills to the next level.

By the end of this book, you'll have built on your embedded system skills and will be able to create real-time systems using microcontrollers and FreeRTOS.

What you will learn

  • Understand when to use an RTOS for a project
  • Explore RTOS concepts such as tasks, mutexes, semaphores, and queues
  • Discover different microcontroller units (MCUs) and choose the best one for your project
  • Evaluate and select the best IDE and middleware stack for your project
  • Use professional-grade tools for analyzing and debugging your application
  • Get FreeRTOS-based applications up and running on an STM32 board

Who this book is for

This book is for embedded engineers, students, or anyone interested in learning the complete RTOS feature set with embedded devices. A basic understanding of the C programming language and embedded systems or microcontrollers will be helpful.

Publisher resources

Download Example Code

Table of contents

  1. Title Page
  2. Copyright and Credits
    1. Hands-On RTOS with Microcontrollers
  3. About Packt
    1. Why subscribe?
  4. Contributors
    1. About the author
    2. About the reviewer
    3. Packt is searching for authors like you
  5. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
      1. Download the example code files
      2. Download the color images
      3. Conventions used
    4. Get in touch
      1. Reviews
  6. Section 1: Introduction and RTOS Concepts
  7. Introducing Real-Time Systems
    1. Technical requirements
    2. What is real-time anyway? 
      1. The ranges of timing requirements
      2. The ways of guaranteeing real-time behavior
        1. Types of real-time systems
          1. Hardware
          2. Bare-metal firmware
          3. RTOS-based firmware
          4. RTOS-based software
          5. Carefully crafted OS software
    3. Defining RTOS
      1. Hard real-time systems
      2. Firm real-time systems
      3. Soft real-time systems
      4. The range of RTOSes
      5. The RTOS used in this book
    4. Deciding when to use an RTOS
    5. Summary
    6. Questions
  8. Understanding RTOS Tasks
    1. Technical requirements
    2. Introducing super loop programming
      1. The basic super loop
      2. Super loops in real-time systems
    3. Achieving parallel operations with super loops
      1. Introducing interrupts 
      2. Interrupts and super loops
      3. Introducing DMA 
      4. Scaling a super loop
    4. Comparing RTOS tasks to super loops
    5. Achieving parallel operations with RTOS tasks
      1. Theoretical task programming model
      2. Round-robin scheduling
      3. Preemptive-based scheduling
    6. RTOS tasks versus super loops – pros and cons
    7. Summary
    8. Questions 
    9. Further reading
  9. Task Signaling and Communication Mechanisms
    1. Technical requirements
    2. RTOS queues
      1. Simple queue send
      2. Simple queue receive
      3. Full queue send
      4. Empty queue receive
      5. Queues for inter-task communication
    3. RTOS semaphores
      1. Counting semaphores
      2. Binary semaphores
    4. RTOS mutexes
      1. Priority inversion
      2. Mutexes minimize priority inversion
    5. Summary
    6. Questions 
  10. Section 2: Toolchain Setup
  11. Selecting the Right MCU
    1. Technical requirements
    2. The importance of MCU selection
    3. MCU considerations 
      1. Core considerations
        1. Physical size
        2. ROM
        3. RAM
        4. The CPU clock rate
        5. Interrupt processing
        6. Price
        7. Availability
      2. Hardware peripherals
        1. Connectivity
        2. Memory protection units
        3. Hardware floating-point units
        4. Digital signal processing functions
        5. Direct memory access channels
        6. Communication interfaces
        7. Hardware crypto engines
        8. Timing hardware
        9. Integrated analog
        10. Dedicated touch interfaces
        11. Display interfaces
        12. External memory support
        13. Real-time clock
        14. Audio support
      3. Power consumption
        1. Power efficiency  
        2. Low-power modes
        3. Wake-up time
        4. Power supply voltage
      4. Migrating MCUs mid-project
        1. Importance of pin compatibility
        2. Peripheral similarity
        3. The concept of an MCU family
    4. Development board considerations
      1. What a development platform is and why it matters
      2. Evaluation kits
      3. Low-cost demonstration boards
    5. Introducing the STM32 product line
      1. Mainstream
      2. High performance 
      3. The heterogeneous multi-core approach
      4. Low power
      5. Wireless
    6. How our development board was selected
      1. Requirements
      2. Requirements justification
      3. Choosing the dev board
    7. Summary
    8. Questions
    9. Further reading
  12. Selecting an IDE
    1. Technical requirements
    2. The IDE selection criteria
    3. Free MCU vendor IDEs and hardware-centric IDEs
      1. STM32CubeIDE
    4. Platform-abstracted IDEs
      1. ARM Mbed Studio 
      2. Arduino IDE
    5. Open source/free IDEs
      1. AC6 System Workbench for STM32 (S4STM32)
      2. Eclipse CDT and GCC
      3. Microsoft Visual Studio Code
    6. Proprietary IDEs
      1. ARM/Keil uVision
      2. IAR Embedded Workbench
      3. Rowley CrossWorks
      4. SEGGER Embedded Studio
      5. SysProgs Visual GDB
    7. Selecting the IDE used in this book
    8. Considering STM32Cube
      1. Device selection
      2. Hardware bring-up
      3. Middleware setup
      4. Code generation trade-offs
    9. Setting up our IDE
      1. Installing STM32CubeIDE
      2. Importing the source tree into STM32CubeIDE
    10. Summary
    11. Questions
    12. Further reading
  13. Debugging Tools for Real-Time Systems
    1. Technical requirements
    2. The importance of excellent debugging tools
      1. RTOS-aware debugging
      2. RTOS visualization
    3. Using SEGGER J-Link
      1. Hardware options
        1. Segger J-Trace
        2. SEGGER J-Link
        3. SEGGER J-Link on-board
      2. Installing J-Link
        1. Converting ST-Link to J-Link
    4. Using SEGGER Ozone
      1. File types used in the examples
      2. Installing SEGGER Ozone
      3. Creating Ozone projects
      4. Attaching Ozone to the MCU
      5. Viewing tasks
        1. Task-based stack analysis
    5. Using SEGGER SystemView
      1. Installing SystemView
        1. SystemView installation
        2. Source code configuration
      2. Using SystemView
    6. Other great tools
      1. Test-driven development 
      2. Static analysis
      3. Percepio Tracealyzer
      4. Traditional testing equipment
    7. Summary
    8. Questions
    9. Further reading
  14. Section 3: RTOS Application Examples
  15. The FreeRTOS Scheduler
    1. Technical requirements
    2. Creating tasks and starting the scheduler
      1. Hardware initialization
      2. Defining task functions
      3. Creating tasks
        1. Checking the return value
      4. Starting the scheduler
    3. Deleting tasks
      1. The task deletes itself
      2. Deleting a task from another task
    4. Trying out the code
    5. Task memory allocation
      1. Heap allocated tasks
      2. Statically allocated tasks
      3. Memory protected task creation
      4. Task creation roundup
    6. Understanding FreeRTOS task states
      1. Understanding different task states
        1. Running
        2. Ready
        3. Blocked
        4. Suspended
      2. Optimizing task states
        1. Optimizing to reduce CPU time
        2. Optimizing to increase performance
        3. Optimizing to minimize power consumption
    7. Troubleshooting startup problems
      1. None of my tasks are running!
        1. Task creation failed
        2. Scheduler returns unexpectedly
      2. Important notes
    8. Summary
    9. Questions
    10. Further reading
  16. Protecting Data and Synchronizing Tasks
    1. Technical requirements
    2. Using semaphores
      1. Synchronization via semaphores
        1. Setting up the code
        2. Understanding the behavior
      2. Wasting cycles – synchronization by polling
        1. Setting up the code
        2. Understanding the behavior
      3. Time-bound semaphores
        1. Setting up the code 
        2. Understanding the behavior
      4. Counting semaphores
      5. Priority inversion (how not to use semaphores)
        1. Setting up the code
          1. Task A (highest priority)
          2. Task B (medium priority)
          3. Task C (low priority)
        2. Understanding the behavior
    3. Using mutexes
      1. Fixing priority inversion
        1. Setting up the code
        2. Understanding the behavior
      2. Avoiding mutex acquisition failure
    4. Avoiding race conditions
      1. Failed shared resource example
    5. Using software timers
      1. Setting up the code
        1. Oneshot timers
        2. Repeat timers
      2. Understanding the behavior
      3. Software timer guidelines
        1. Example use cases
        2. Considerations
        3. Limitations
    6. Summary
    7. Questions
    8. Further reading
  17. Intertask Communication
    1. Technical requirements
    2. Passing data through queues by value
      1. Passing one byte by value
      2. Passing a composite data type by value
      3. Understanding how queues affect execution
      4. Important notes on the examples 
    3. Passing data through queues by reference
      1. When to pass by reference
      2. Important notes
    4. Direct task notifications
      1. Passing simple data using task notifications
      2. Other options for task notifications
      3. Comparing direct task notifications  to queues
    5. Summary
    6. Questions
    7. Further reading
  18. Section 4: Advanced RTOS Techniques
  19. Drivers and ISRs
    1. Technical requirements
    2. Introducing the UART
      1. Setting up the UART
    3. Creating a polled UART driver
      1. Analyzing the performance
      2. Pros and cons of a polled driver
      3. Usage of polled drivers
    4. Differentiating between tasks and ISRs
      1. Using the FreeRTOS API from interrupts
    5. Creating ISR-based drivers
      1. Queue-based driver
        1. uartPrintOutTask 
        2. startReceiveInt
        3. USART2_IRQHandler
        4. Tips for linking ISRs
        5. startUart4Traffic
        6. Performance analysis
      2. A buffer-based driver
        1. startReceiveInt
        2. uartPrintOutTask
        3. USART2_IRQHandler
        4. startUart4Traffic
        5. Performance analysis
    6. Creating DMA-based drivers 
      1. Configuring DMA peripherals
      2. A buffer-based driver with DMA 
        1. Performance analysis
    7. Stream buffers (FreeRTOS 10+)
      1. Using the stream buffer API
      2. Setting up double-buffered DMA
      3. Populating the stream buffer
      4. Improving the stream buffer
      5. Analyzing the performance
    8. Choosing a driver model
      1. How is the calling code designed?
      2. How much delay is acceptable?
      3. How fast is data moving?
      4. What type of device are you interfacing?
      5. When to use queue-based drivers
      6. When to use buffer-based drivers
      7. When to use stream buffers
    9. Using third-party libraries (STM HAL)
    10. Summary
    11. Questions
    12. Further reading
  20. Sharing Hardware Peripherals across Tasks
    1. Technical requirements
    2. Understanding shared peripherals
      1. Defining the peripheral driver
    3. Introducing the STM USB driver stack
      1. Using the stock CDC drivers
    4. Developing a StreamBuffer USB virtual COM port
      1. Public functions
      2. Private functions
      3. Putting it all together
    5. Using mutexes for access control
      1. Extending VirtualCommDriver
      2. Guaranteeing atomic transactions
    6. Summary
    7. Questions
  21. Tips for Creating a Well-Abstracted Architecture
    1. Technical requirements
    2. Understanding abstraction
      1. Grasping an abstraction is fast
        1. An example with abstraction
        2. An example without abstraction
      2. Abstractions provide flexibility
      3. Why abstraction is important
      4. Recognizing opportunities to reuse code
      5. Avoiding the copy-paste-modify trap
    3. Writing reusable code
      1. Writing reusable drivers 
      2. Developing an LED interface
      3. Reusing code containing tasks
      4. Testing flexible code
    4. Organizing source code
      1. Choosing locations for source files
      2. Dealing with changes
    5. Summary
    6. Questions
    7. Further reading
  22. Creating Loose Coupling with Queues
    1. Technical requirements
    2. Understanding queues as interfaces
      1. Queues make excellent interface definitions
      2. Queues increase flexibility 
      3. Queues make testing easier
    3. Creating a command queue
      1. Deciding on queue contents
      2. Defining the architecture
        1. ledCmdExecutor
        2. Frame decoding
        3. The USB virtual comm driver
      3. Using the code
    4. Reusing a queue definition for a new target
      1. The queue interface
      2. The iPWM interface
    5. Summary
    6. Questions
  23. Choosing an RTOS API
    1. Technical requirements
    2. Understanding generic RTOS APIs
      1. Advantages of generic APIs
      2. Disadvantages of generic APIs
    3. Comparing FreeRTOS and CMSIS-RTOS
      1. Considerations during migration
      2. Cross-referencing CMIS-RTOS and FreeRTOS functions
        1. Delay functions
        2. EventFlags
        3. Kernel control and information
        4. Message queues
        5. Mutexes and semaphores
        6. Semaphores 
        7. Thread flags
        8. Thread control/information
        9. Timers
        10. Memory pools
      3. Creating a simple CMSIS-RTOS v2 application
    4. FreeRTOS and POSIX
      1. Creating a simple FreeRTOS POSIX application
      2. Pros and cons to using the POSIX API
    5. Deciding which API to use
      1. When to use the native FreeRTOS API
      2. When to use the CMSIS-RTOS API
      3. When to use the POSIX API
    6. Summary
    7. Questions
    8. Further reading
  24. FreeRTOS Memory Management
    1. Technical requirements
    2. Understanding memory allocation
      1. Static memory
      2. Stack memory
      3. Heap memory
        1. Heap fragmentation
    3. Static and dynamic allocation of FreeRTOS primitives
      1. Dynamic allocation examples
        1. Creating a task
        2. Creating a queue
      2. Static allocation examples
        1. Creating a task
        2. Creating a queue
      3. Eliminating all dynamic allocation
    4. Comparing FreeRTOS heap implementations
      1. Choosing your RTOS heap implementation
    5. Replacing malloc and free
    6. Implementing FreeRTOS memory hooks
      1. Keeping an eye on stack space
      2. Keeping an eye on heap space
    7. Using a memory protection unit (MPU)
    8. Summary
    9. Questions
    10. Further reading
  25. Multi-Processor and Multi-Core Systems
    1. Technical requirements
    2. Introducing multi-core and multi-processor systems 
    3. Exploring multi-core systems
      1. Heterogeneous multi-core systems
        1. Inter-core communication
        2. Legacy application extension
        3. High-demand hard real-time systems
      2. Homogeneous multi-core systems
    4. Exploring multi-processor systems
      1. Distributed systems
      2. Parallel development
      3. Design reuse
      4. High-reliability systems
    5. Exploring inter-processor communication
      1. Choosing the right communication medium
        1. Communication standards
          1. Controller area network
          2. Ethernet
          3. Inter-integrated communication bus
          4. Local interconnect network
          5. Modbus
          6. Serial peripheral interface
          7. USB as an inter-processor communication bus
    6. Choosing between multi-core and multi-processor systems
      1. When to use multi-core MCUs
      2. When to use multi-processor systems
    7. Summary
    8. Questions
    9. Further reading
  26. Troubleshooting Tips and Next Steps
    1. Technical requirements
    2. Useful tips
      1. Using tools to analyze threads
      2. Keeping an eye on memory usage
      3. Stack overflow checking
      4. Fixing SystemView dropped data
    3. Using assertions
      1. configAssert
      2. Debugging a hung system with configAssert()
        1. Collecting the data
        2. Digging deeper – SystemView data breakpoints
    4. Next steps
    5. Summary
    6. Questions
  27. Assessments
    1. Chapter 1
    2. Chapter 2
    3. Chapter 3
    4. Chapter 4
    5. Chapter 5
    6. Chapter 6
    7. Chapter 7
    8. Chapter 8
    9. Chapter 9
    10. Chapter 10
    11. Chapter 11
    12. Chapter 12
    13. Chapter 13
    14. Chapter 14
    15. Chapter 15
    16. Chapter 16
    17. Chapter 17
  28. Other Books You May Enjoy
    1. Leave a review - let other readers know what you think

Product information

  • Title: Hands-On RTOS with Microcontrollers
  • Author(s): Brian Amos
  • Release date: May 2020
  • Publisher(s): Packt Publishing
  • ISBN: 9781838826734