Embedded Software Development
eBook - ePub

Embedded Software Development

The Open-Source Approach

Ivan Cibrario Bertolotti, Tingting Hu

Share book
  1. 526 pages
  2. English
  3. ePUB (mobile friendly)
  4. Available on iOS & Android
eBook - ePub

Embedded Software Development

The Open-Source Approach

Ivan Cibrario Bertolotti, Tingting Hu

Book details
Book preview
Table of contents
Citations

About This Book

Embedded Software Development: The Open-Source Approach delivers a practical introduction to embedded software development, with a focus on open-source components. This programmer-centric book is written in a way that enables even novice practitioners to grasp the development process as a whole.

Incorporating real code fragments and explicit, real-world open-source operating system references (in particular, FreeRTOS) throughout, the text:

  • Defines the role and purpose of embedded systems, describing their internal structure and interfacing with software development tools
  • Examines the inner workings of the GNU compiler collection (GCC)-based software development system or, in other words, toolchain
  • Presents software execution models that can be adopted profitably to model and express concurrency
  • Addresses the basic nomenclature, models, and concepts related to task-based scheduling algorithms
  • Shows how an open-source protocol stack can be integrated in an embedded system and interfaced with other software components
  • Analyzes the main components of the FreeRTOS Application Programming Interface (API), detailing the implementation of key operating system concepts
  • Discusses advanced topics such as formal verification, model checking, runtime checks, memory corruption, security, and dependability

Embedded Software Development: The Open-Source Approach capitalizes on the authors' extensive research on real-time operating systems and communications used in embedded applications, often carried out in strict cooperation with industry. Thus, the book serves as a springboard for further research.

Frequently asked questions

How do I cancel my subscription?
Simply head over to the account section in settings and click on “Cancel Subscription” - it’s as simple as that. After you cancel, your membership will stay active for the remainder of the time you’ve paid for. Learn more here.
Can/how do I download books?
At the moment all of our mobile-responsive ePub books are available to download via the app. Most of our PDFs are also available to download and we're working on making the final remaining ones downloadable now. Learn more here.
What is the difference between the pricing plans?
Both plans give you full access to the library and all of Perlego’s features. The only differences are the price and subscription period: With the annual plan you’ll save around 30% compared to 12 months on the monthly plan.
What is Perlego?
We are an online textbook subscription service, where you can get access to an entire online library for less than the price of a single book per month. With over 1 million books across 1000+ topics, we’ve got you covered! Learn more here.
Do you support text-to-speech?
Look out for the read-aloud symbol on your next book to see if you can listen to it. The read-aloud tool reads text aloud for you, highlighting the text as it is being read. You can pause it, speed it up and slow it down. Learn more here.
Is Embedded Software Development an online PDF/ePUB?
Yes, you can access Embedded Software Development by Ivan Cibrario Bertolotti, Tingting Hu in PDF and/or ePUB format, as well as other popular books in Informatique & Développement de logiciels. We have over one million books available in our catalogue for you to explore.

Information

Publisher
CRC Press
Year
2017
ISBN
9781351831499

1 Introduction

The goal of this book is to introduce readers to embedded software development. This is a very broad subject and encompasses several important topics in computer science and engineering—for instance, operating systems, concurrent programming, compilers, code optimization, hardware interfaces, testing, and verification.
Each topic is quite complex by itself and very well deserves one whole textbook, or probably more, to be thoroughly discussed. Unfortunately, since most of those textbooks concentrate on one specific topic, their styles of writing are usually far away from each other.
For instance, concurrent programming is often presented using a formal approach based on an abstract mathematical model for describing a computer system and the concurrent activities it must execute, along with their data dependencies and synchronization constraints.
Such an approach is perfectly fine, provided that the reader has enough available time to fully grasp the model and enough experience to realize how a real system and its requirements fit into the model itself.
On the opposite side, standalone descriptions of how embedded hardware devices interface with a microcontroller are usually compiled by hardware engineers. As a consequence, although they are perfectly correct for what concerns the content, their point of view may easily be quite far away from what a programmer expects.
As a consequence, readers are left with the hard task of mixing and matching all these valuable sources of information, which sometimes use their own nomenclature and jargon, in order to build their own unified, consistent knowledge about embedded software development in their minds.
This might hardly be feasible when the reader is just entering the embedded software development domain as a novice. The problem is further compounded by the fact that the embedded software development process is quite different from its general-purpose counterpart. Hence, previous experience in writing, for instance, PC-based applications, may not be easy to leverage in the new domain.
This book takes a rather different path. In fact, all basic topics presented in the first part of the book are discussed by following a unified approach and consistently emphasizing their relationships and mutual dependencies, rather than isolating them in their own world.
For instance, the description of a central topic like interrupt handling is carried out starting from the hardware event that may trigger an interrupt request, and then guiding the reader through the whole process—partly performed by hardware, and partly by software—that eventually culminates in the execution of the corresponding interrupt handling routine.
In this way, readers gain a complete understanding of several aspects of interrupt handling that are often kept “behind the scenes” in general-purpose programming,
but are indeed of utmost importance to guarantee that embedded systems work reliably and efficiently.
Furthermore, virtually all chapters in the first part of the book make explicit reference to real fragments of code and, when necessary, to a specific operating system, that is, FREERTOS. This also addresses a shortcoming of other textbooks, that is, the lack of practical programming examples presented and commented on in the main text (some provide specific examples in appendices).
From this point of view FREERTOS is an extremely useful case study because it has a very limited memory footprint and execution-time overhead, but still provides a quite comprehensive range of primitives.
In fact, it supports a multithreaded programming model with synchronization and communication primitives that are not far away from those available on much bigger, and more complex systems. Moreover, thanks to its features, is has successfully been used in a variety of real-world embedded applications.
At the same time, it is still simple enough to be discussed in a relatively detailed way within a limited number of pages and without overwhelming the reader with information. This also applies to its hardware abstraction layer—that is, the code module that layers the operating system on top of a specific hardware architecture— which is often considered an “off-limits” topic in other operating systems.
As a final remark, the book title explicitly draws attention to the open-source approach to software development. In fact, even though the usage of open-source components, at least in some scenarios (like industrial or automotive applications) is still limited nowadays, it is the authors’ opinion that open-source solutions will enjoy an ever-increasing popularity in the future.
For this reason, all the software components mentioned and taken as examples in this book—from the software development environment to the real-time operating system, passing through the compiler and the software analysis and verification tools—are themselves open-source.
The first part of the book guides the reader through the key aspects of embedded software development, spanning from the peculiar requirements of embedded systems in contrast to their general-purpose counterparts, without forgetting network communication, implemented by means of open-source protocol stacks.
In fact, even though the focus of this book is mainly on software development techniques, most embedded systems are nowadays networked or distributed, that is, they consist of a multitude of nodes that cooperate by communicating through a network. For this reason, embedded programmers must definitely be aware of the opportunities and advantages that adding network connectivity to the systems they design and develop may bring.
The chapters of the first part of the book are:
Chapter 2, Embedded Applications and Their Requirements. This chapter outlines the role and purpose of embedded systems, introducing readers to
their internal structure and to the most common way they are interfaced to software development tools. The chapter also gives a first overview of the embedded software development process, to be further expanded in the following.
Chapter 3, GCC-Based Software Development Tools. The main topic of this chapter is a thorough description of the GNU compiler collection (GCC)-based software development system, or toolchain, which is arguably the most popular open-source product of this kind in use nowadays. The discussion goes through the main toolchain components and provides insights on their inner workings, focusing in particular on the aspects that may affect programmers’ productivity,
Chapter 4, Execution Models for Embedded Systems. This chapter and the next provide readers with the necessary foundations to design and implement embedded system software. Namely, this chapter presents in detail two different software execution models that can be profitably applied to model and express the key concept of concurrency, that is, the parallel execution of multiple activities, or tasks, within the same software system.
Chapter 5, Concurrent Programming Techniques. In this chapter, the concept of execution model is further expanded to discuss in detail how concurrency must be managed to achieve correct and timely results, by means of appropriate concurrent programming techniques.
Chapter 6, Scheduling Algorithms and Analysis. After introducing some basic nomenclature, models, and concepts related to task-based scheduling algorithms, this chapter describes the most widespread ones, that is, rate monotonic (RM) and earliest deadline first (EDF). The second part of the chapter briefly discusses scheduling analysis, a technique that allows programmers to predict the worst-case timing behavior of their systems.
Chapter 7, Configuration and Usage of Open-Source Protocol Stacks. In recent years, many embedded systems rapidly evolved from centralized to networked or distributed architectures, due to the clear advantages this approach brings. In this chapter, we illustrate how an open-source protocol stack—which provides the necessary support for inter-node communication—can easily be integrated in an embedded software system and how it interfaces with other software components.
Chapter 8, Device Driver Development. Here, the discourse goes from the higher-level topics addressed in the previous three chapters to a greater level of detail, concerning how software manages and drives hardware devices. This is an aspect often neglected in general-purpose software development, but of utmost importance when embedded systems are considered, because virtually all of them are strongly tied to at least some dedicated hardware.
Chapter 9, Portable Software. While the previous chapters set the stage for effective embedded software development, this chapter outlines the all-important trade-off between code execution efficiency and portability, that is, easiness of migrating software from one project to another. This aspect
is becoming more and more important nowadays due to the ever-increasing need to reduce time to market and to implement quick prototyping.
Chapter 10, The FREERTOS Porting Layer. This technically oriented chapter scrutinizes the main components of the FREERTOS porting layer, diving into the implementation details of key operating system concepts, for instance, context switching and the implementation of low-level critical regions by disabling interrupts.
Chapter 11, Performance and Footprint at the Toolchain Level. This chapter illustrates, by means of a running real-world example for the most part, how a modern high-level software development toolchain can be used to achieve a satisfactory level of optimization, for what concerns both execution speed and memory footprint, without resorting to assembly-level programming or other non-portable software development techniques.
Chapter 12, Example: A MODBUS TCP Device. To conclude the first part of the book, this chapter contains a comprehensive example of how the software development techniques described in the previous chapters can be applied to design and build a simple, but complete embedded system.
In the second part, the book presents a few advanced topics, focusing mainly on improving software quality and dependability. The importance of these goals is ever increasing nowadays, as embedded systems are becoming commonplace in critical application areas, like anti-lock braking system (ABS) and motion control.
In order to reach the goal, it is necessary to adopt a range of different techniques, spanning from the software design phase to runtime execution, passing through its implementation. In particular, this book first presents the basic principles of formal verification through model checking, which can profitably be used since the very early stages of algorithm and software design.
Then, a selection of runtime techniques to prevent or, at least, detect memory corruption are discussed. Those techniques are useful to catch any software error that escaped verification and testing, and keep within bounds the damage it can do to the system and its surroundings.
Somewhat in between these two extremes, static code analysis techniques are useful, too, to spot latent software defects that may escape manual code inspection. With respect to formal verification, static code analysis techniques have the advantage of working directly on the actual source code, rather than on a more abstract model.
Moreover, their practical application became easier in recent years because several analysis tools moved away from being research prototypes and became stable enough for production use. The book focuses on one of them as an example.
The second part of the book consists of the following chapters:
Chapter 13, Model Checking of Distributed and Concurrent Systems. This chapter describes how formal verification, and model checking in particular, can be profitably used to improve software quality and even prove that it satisfies some critical requirements. The practical advantages of this
technique become evident as embedded software complexity grows, thus limiting the effectiveness of more traditional testing techniques.
Chapter 14, Model Checking: An Example. Building upon the general concept of model checking introduced previously, this chapter shows the application of model checking to a case study of practical, industrial interest. It demonstrates how model checking can be used to identify low-probability defects that may never be observed during testing, and how counterexamples found by the model checker can be helpful to correct them.
Chapter 15, Memory Protection Techniques. Since it is usually impossible to design and develop perfect software, even after extensive testing and formal verification, another way to enhance software dependability is to introduce various runtime checks. This chapter focuses on several specific kinds of check, aimed at preventing or detecting memory corruption.
Chapter 16, Security and Dependability Aspects. This chapter describes how software dependability can be further enhanced by means of sophisticated static code analysis techniques, which go beyond what an ordinary compiler is able to do. Furthermore, the same techniques also enhance software quality from what concerns security attacks, an aspect of utmost importance as embedded systems are nowadays often connected to public communication networks.
The bibliography at the end of the book has been kept rather short because it has been compiled with software practitioners in mind. Hence, instead of providing an exhaustive and detailed list of references that would have been of interest mainly to people willing to dive deep into the theoretical aspects of embedded real-time systems, we decided to highlight a smaller number of additional sources of information.
In this way, readers can more effectively use the bibliography as a starting point to seek further knowledge on this rather vast field, without getting lost. Within the works we cite, readers will also find further, more specific pointers to pursue their quest.

Part I Basic...

Table of contents