<p><P>Concurrency theory, software architecture, system modeling and verification, and dependability and performance evaluation may seem unrelated disciplines, but in reality they are deeply intertwined and should be part of an integrated view in order to successfully manage the increasing complexit
Embedded Software Design: A Practical Approach to Architecture, Processes, and Coding Techniques
✍ Scribed by Jacob Beningo
- Publisher
- Apress
- Year
- 2022
- Tongue
- English
- Leaves
- 474
- Edition
- 1st ed.
- Category
- Library
No coin nor oath required. For personal study only.
✦ Synopsis
Design higher-quality embedded software from concept through production. This book assumes basic C and microcontroller programming knowledge and is organized into three critical areas: Software Architecture and Design; Agile, DevOps, and Processes; and Development and Coding Skills.
You'll start with a basic introduction to embedded software architecture and the considerations for a successful design. The book then breaks down how to architect an RTOS-based application and explore common design patterns and building blocks. Next, you'll review embedded software design processes such as TDD, CI/CD, modeling, and simulation that can be used to accelerate development. Finally, the book will examine how to select a microcontroller, write configurable code, coding strategies, techniques, and tools developers can’t live without.
Embedded systems are typically designed using microcontrollers to build electronic systems with a dedicated function and real-time responses. Modern systems need to carefully balance a complex set of features, manage security, and even run machine learning inferences while maintaining reasonable costs, scalability, and robustness. By the end of this book, you will have a defined development process, understand modern software architecture, and be equipped to start building embedded systems. What You'll Learn
- Understand what sound embedded system design is and how to employ it
- Explore modern development processes for quality systems
- Know where the bits hit the silicon: how to select a microcontroller
- Master techniques to write configurable, automated code
✦ Table of Contents
Table of Contents
About the Author
About the Technical Reviewer
Acknowledgments
Preface
Part I: Software Architecture and Design
Chapter 1: Embedded Software Design Philosophy
Challenges Facing Embedded Developers
7 Modern Design Philosophy Principles
Principle #1 – Data Dictates Design
Principle #2 – There Is No Hardware (Only Data)
Principle #3 – KISS the Software
Principle #4 – Practical, Not Perfect
Principle #5 – Scalable and Configurable
Principle #6 – Design Quality in from the Start
Principle #7 – Security Is King
Harnessing the Design Yin-Yang
Traditional Embedded Software Development
Modern Embedded Software Development
The Age of Modeling, Simulation, and Off-Chip Development
Final Thoughts
Chapter 2: Embedded Software Architecture Design
A Tale of Two Architectures
Approaches to Architecture Design
Characteristics of a Good Architecture
Architectural Coupling
Architectural Cohesion
Architectural Design Patterns in Embedded Software
The Unstructured Monolithic Architecture
Layered Monolithic Architectures
Event-Driven Architectures
Microservice Architectures
Application Domain Decomposition
The Privilege Domain
The Security Domain
The Execution Domain
The Cloud Domain
Final Thoughts
Chapter 3: Secure Application Design
Platform Security Architecture (PSA)
PSA Stage 1 – Analyzing a System for Threats and Vulnerabilities
TMSA Step #1 – Identifying Assets
TMSA Step #2 – Identifying Adversaries and Threats
TMSA Step #3 – Defining Security Objectives
TMSA Step #4 – Security Requirements
TMSA Step #5 – Summary
PSA Stage 2 – Architect
Security Through Isolation
Isolation Level #1 – Processing Environments
Isolation Level #2 – Root-of-Trust and Trusted Services
Isolation Level #3 – Trusted Applications
Architecting a Secure Application
PSA Stage 3 – Implementation
Multicore Processors
Single-Core Processors with TrustZone
The Secure Boot Process
PSA Stage 4 – Certify
Final Thoughts
Chapter 4: RTOS Application Design
Tasks, Threads, and Processes
Task Decomposition Techniques
Feature-Based Decomposition
The Outside-In Approach to Task Decomposition
The Seven-Step Process
Decomposing an IoT Thermostat
Step #1 – Identify the Major Components
Step #2 – Draw a High-Level Block Diagram
Step #3 – Label the Inputs
Step #4 – Label the Outputs
Step #5 – Identify First-Tier Tasks
Step #6 – Determine Concurrencies, Dependencies, and Data Flow
Step #7 – Identify Second-Tier Tasks
Setting Task Priorities
Task Scheduling Algorithms14
Verifying CPU Utilization Using Rate Monotonic Analysis (RMA)
Measuring Execution Time
Measuring Task Execution Time Manually
Measuring Task Execution Time Using Trace Tools
Final Thoughts
Chapter 5: Design Patterns
Managing Peripheral Data
Peripheral Polling
Peripheral Interrupts
Interrupt Design Patterns
Linear Data Store Design Pattern
Ping-Pong Buffer Design Pattern
Circular Buffer Design Pattern
Circular Buffer with Notification Design Pattern
Message Queue Design Pattern
Direct Memory Access (DMA)
RTOS Application Design Patterns
Resource Synchronization
Interrupt Locking
Preemption Lock
Mutex Lock
Activity Synchronization
Unilateral Rendezvous (Task to Task)
Unilateral Rendezvous (Interrupt to Task)
Bilateral Rendezvous
Synchronizing Multiple Tasks
Publish and Subscribe Models
Low-Power Application Design Patterns
Leveraging Multicore Microcontrollers
AI and Real-Time Control
Real-Time Control
Security Solutions
A Plethora of Use Cases
Final Thoughts
Part II: Agile, DevOps, and Processes
Chapter 6: Software Quality, Metrics, and Processes
Defining Software Quality
Structural Software Quality
Architectural Quality
Code Quality
Coding Standards
Software Metrics
McCabe Cyclomatic Complexity
Code Analysis (Static vs. Dynamic)
Achieving 100% Branch Coverage
Code Reviews
Case Study – Capstone Propulsion Controller
Final Thoughts
Chapter 7: Embedded DevOps
A DevOps Overview
DevOps Principles in Action
Embedded DevOps Delivery Pipeline
CI/CD for Embedded Systems
Designing a CI/CD Pipeline
Creating Your First CI/CD Pipeline
Is DevOps Right for You?
Final Thoughts
Chapter 8: Testing, Verification, and Test-Driven Development
Embedded Software Testing Types
Testing Your Way to Success
What Makes a Great Test?
Regression Tests to the Rescue
How to Qualify Testing
Introduction to Test-Driven Development
Setting Up a Unit Test Harness for TDD
Installing CppUTest
Leveraging the Docker Container
Test Driving CppUTest
Final Thoughts
Chapter 9: Application Modeling, Simulation, and Deployment
The Role of Modeling and Simulation
Embedded Software Modeling
Software Modeling with Stand-Alone UML Tools
Software Modeling with Code Generation
Software Modeling with Matlab
Embedded Software Simulation
Simulation Using Matlab
Software Modeling in Python
Additional Thoughts on Simulation
Deploying Software
Stand-Alone Flash Tools for Manufacturing
CI/CD Pipeline Jobs for HIL Testing and FOTA
Final Thoughts
Chapter 10: Jump-Starting Software Development to Minimize Defects
A Hard Look at Bugs, Errors, and Defects
The Defect Minimization Process
Phase 1 – Project Setup
Phase 2 – Build System and DevOps Setup
Phase 3 – Test Harness Configuration
Phase 4 – Documentation Facility Setup
Phase 5 – Static Code Analysis
Phase 6 – Dynamic Code Analysis
Phase 7 – Debug Messages and Trace
When the Jump-Start Process Fails
Final Thoughts
Part III: Development and Coding Skills
Chapter 11: Selecting Microcontrollers
The Microcontroller Selection Process
Step #1 – Create a Hardware Block Diagram
Step #2 – Identify All the System Data Assets
Step #3 – Perform a TMSA
Step #4 – Review the Software Model and Architecture
Step #5 – Research Microcontroller Ecosystems
Step #6 – Evaluate Development Boards
Step #7 – Make the Final MCU Selection
The MCU Selection KT Matrix
Identifying Decision Categories and Criterions
Building the KT Matrix
Choosing the Microcontroller
Overlooked Best Practices
Final Thoughts
Chapter 12: Interfaces, Contracts, and Assertions
Interface Design
Design-by-Contract
Utilizing Design-by-Contract in C Applications
Assertions
Defining Assertions
When and Where to Use Assertions
Does Assert Make a Difference?
Setting Up and Using Assertions
Examining the Assert Macro Definition
Implementing assert_failed
Verifying Assertions Work
Three Instances Where Assertions Are Dangerous
Instance #1 – Initialization
Instance #2 – Microcontroller Drivers
Instance #3 – Real-Time Hardware Components
Getting Started with Real-Time Assertions
Real-Time Assertion Tip #1 – Use a Visual Aid
Real-Time Assertion Tip #2 – Create an Assertion Log
Real-Time Assertion Tip #3 – Notify the Application
Real-Time Assertion Tip #4 – Conditionally Configure Assertions
A Few Concluding Thoughts
Chapter 13: Configurable Firmware Techniques
Leveraging Configuration Tables
An Extensible Task Initialization Pattern
Defining a Task Configuration Structure
Defining a Task Configuration Table
Initializing Tasks in a Task_CreateAll Function
Autogenerating Task Configuration
YAML Configuration Files
Creating Source File Templates
Generating Code Using Python
Final Thoughts
Chapter 14: Comms, Command Processing, and Telemetry Techniques
Designing a Lightweight Communication Protocol
Defining a Packet Protocol’s Fields
A Plethora of Applications
Implementing an Efficient Packet Parser
The Packet Parsing Architecture
Receiving Data to Process
Packet Decoding As a State Machine
Validating the Packet
Command Processing and Execution
Traditional Command Parsers
An Introduction to Command Tables
Executing a Command from a Command Table
Managing System Telemetry
Telemetry As a “Global” Variable
Telemetry As a Service
Final Thoughts
Chapter 15: The Right Tools for the Job
The Types of Value Tools Provide
Calculating the Value of a Tool
The ROI of a Professional Debugging Tool
Embedded Software Tools
Architectural Tools
Requirements Solicitation and Management
Storyboarding
UML Diagramming and Modeling
Process Tools
Revision Control
Software Development Life Cycle
Testing
Continuous Integration/Continuous Deployment
Implementation Tools
IDEs and Compilers
Programmers
Code Generators
Analyzers
Open Source vs. Commercial Tools
Final Thoughts
Part IV: Next Steps and Appendixes
Afterword: Next Steps
Where Are We Now?
Defining Your Next Steps
Choosing How You Grow
Final Thoughts
Appendix A: Security Terminology Definitions
Definitions
Appendix B: 12 Agile Software Principles
12 Agile Software Principles0
Appendix C: Hands-On – CI/CD Using GitLab
An Overview
Building STM32 Microcontroller Code in Docker
Installing GCC-arm-none-eabi in a Docker Container
Creating and Running the Arm GCC Docker Image
Creating an STM32 Test Project
Compiling the STM32 Makefile Project
Configuring the Build CI/CD Job in GitLab
Creating the Pipeline
Connecting Our Code to the Build Job
Build System Final Thoughts
Leveraging the Docker Container
Test-Driving CppUTest
Integrating CppUTest into a CI/CD Pipeline
Adding CppUTest to the Docker Image
Creating a Makefile for CppUTest
Configuring GitLab to Run Tests
Unit Testing Final Thoughts
Adding J-Link to Docker
Adding a Makefile Recipe
Deploying Through GitLab
Deployment Final Thoughts
Appendix D: Hands-On TDD
The Heater Module Requirements
Designing the Heater Module
Defining Our Tests
Writing Our First Test
Test Case – Setting to HEATER_ON
Heater Module Production Code
Heater Module Test Cases
Do We Have Enough Tests?
TDD Final Thoughts
Index
📜 SIMILAR VOLUMES
<p><P>Concurrency theory, software architecture, system modeling and verification, and dependability and performance evaluation may seem unrelated disciplines, but in reality they are deeply intertwined and should be part of an integrated view in order to successfully manage the increasing complexit
<p><P>Concurrency theory, software architecture, system modeling and verification, and dependability and performance evaluation may seem unrelated disciplines, but in reality they are deeply intertwined and should be part of an integrated view in order to successfully manage the increasing complexit
<p><P>Concurrency theory, software architecture, system modeling and verification, and dependability and performance evaluation may seem unrelated disciplines, but in reality they are deeply intertwined and should be part of an integrated view in order to successfully manage the increasing complexit
<p style="margin:0px;"> <b> <i>Designing Software Architectures</i> </b> will teach you how to design any software architecture in a systematic, predictable, repeatable, and cost-effective way.</p> <p style="margin:0px;"> <br> </p> <p style="margin:0px;">This book introduces a practical methodology
"Designing Software Architectures" will teach you how to design any software architecture in a systematic, predictable, repeatable, and cost-effective way. This book introduces a practical methodology for architecture design that any professional software engineer can use, provides structured method