Reader small image

You're reading from  Hands-On Embedded Programming with C++17

Product typeBook
Published inJan 2019
Reading LevelIntermediate
PublisherPackt
ISBN-139781788629300
Edition1st Edition
Languages
Tools
Right arrow
Author (1)
Maya Posch
Maya Posch
author image
Maya Posch

Maya Posch is a senior C++ developer with more than 15 years of experience. Discovering the joys of programming early on, and later the joys of electronics, she has always expressed a profound interest in technology, a passion that she gladly shares with others. Describing herself as a C developer who happens to like C++ and Ada, she likes to seek the limits of what can be done with the minimum of code and hardware to accomplish everything that is cool, new, and exciting. She also enjoys FPGA development, AI, and robotics research, in addition to creative writing, music, and drawing.
Read more about Maya Posch

Right arrow

Chapter 4. Resource-Restricted Embedded Systems

Using a smaller embedded system such as a microcontroller (MCU) means having small amounts of RAM, CPU power, and storage. This chapter deals with planning for and making efficient use of limited resources taking into account the wide range of currently available MCUs and System-on-Chip (SoC) solutions. We will be considering the following aspects

  • Selecting the right MCU for a project
  • Concurrency and memory management
  • Adding sensors, actuators, and network access
  • Bare-metal development versus real-time OSes

The big picture for small systems


When first confronted with a new project that requires the use of at least one type of MCU, it can seem like an overwhelming task to. As we saw in Chapter 1What are Embedded Systems?, there is a large number of MCUs to choose from, even if we limit ourselves to just those that have been released recently.

It may seem obvious to start by asking how many bits one needs, as in selecting between 8-bit, 16-bit, and 32-bit MCUs, or something as easy to quantify as clock speed, but these metrics are sometimes misleading and often don't lend themselves well to narrowing down the product selection. As it turns out, the parent categories are availability of sufficient I/O and the integrated peripherals to make the hardware happen in a lean and reliable way, as well as processing power tailored to the requirements faced at design-time and predicted to emerge throughout the product life-time.

So in more detail we need to answer questions like these:

  • Peripherals: Which...

Embedded IDEs and frameworks


While the application development for SoCs tends to be quite similar to desktop and server environments, as we saw in the previous chapter, MCU development requires a far more intimate knowledge of the hardware that one is developing for, sometimes down to the exact bits to set in a particular register.

There exist some frameworks that seek to abstract away such details for particular MCU series, so that one can develop for a common API without having to worry about how it is implemented on a specific MCU. Of these, the Arduino framework is the most well-known outside of industrial applications, though there are also a number of commercial frameworks that are certified for production use.

Frameworks such as the Advanced Software Framework (ASF) for AVR and SAM MCUs can be used with a variety of IDEs, including Atmel Studio, Keil µVision, and IAR Embedded Workbench.

A non-exhaustive list of popular embedded IDEs follows:

Programming MCUs


After we have compiled our code for the target MCU, the binary image needs to be written to a controller memory prior to execution and debugging. In this section we will look at the varied ways in which this can be accomplished. These days only factory-side programming is done with test sockets, or better yet at the wafer level before a known good die is bonded to a leadframe and encapsulated. Surface-mount parts already rule out easy removal of an MCU for (repeated) programming.

A number of (frequently vendor-specific) options for in-circuit programming exist, distinguished by the peripherals they use and the memories they affect.

So a pristine MCU often needs to be programmed using an external programming adapter. These generally work by setting the pins of the MCU so that it enters programming mode, after which the MCU accepts the data stream containing the new ROM image.

Another option that is commonly used is to add a boot loader to the first section of the ROM, which...

Memory management


The storage and memory system of microcontrollers consists out of multiple components. There is a section of read-only-memory (ROM) that is only written to once when the chip is programmed, but which cannot normally be altered by the MCU itself, as we saw in the previous section.

The MCU may also have a bit of persistent storage, in the form of EEPROM or equivalent. Finally, there are CPU registers and the random-access memory (RAM). This results in the following exemplary memory layout:

The use of a modified Harvard architecture (split program and data memory at some architectural level, generally with the data buses) is common with MCUs. With the AVR architecture, for example, the program memory is found in the ROM, which for the ATmega2560 is connected using its own bus with the CPU core, as one can seen on the block diagram for this MCU, which we looked at previously in Chapter 1, What Are Embedded Systems?

A major advantage of having separate buses for these memory spaces...

Concurrency


With a few exceptions, MCUs are single-core systems. Multitasking is not something that is generally done; instead, there's a single thread of execution with timers and interrupts adding asynchronous methods of operation.

Atomic operations are generally supported by compilers and AVR is no exception. The need for atomic blocks of instructions can be seen in the following cases. Keep in mind that while a few exceptions exist (MOVW to copy a register pair and indirect addressing via X, Y, Z pointers), instructions on an 8 bit architecture generally only affect 8 bit values.

  • A 16 bit variable is byte-wise read in the main function and updated in an ISR.
  • A 32 bit variable is read, modified and subsequently stored back in either main function or ISR while the other routine could try to access it.
  • The execution of a block of code is time-critical (bitbanging I/O, disabling JTAG).

A basic example for the first case is given in the AVR libc documentation:

#include <cinttypes> 
#include...

AVR development with Nodate


Microchip provides a binary version of the GCC toolchain for AVR development. At the time of writing, the most recent release of AVR-GCC is 3.6.1, containing GCC version 5.4.0. This implies full support for C++14 and limited support for C++17.

Using this toolchain is pretty easy. One can simply download it from the Microchip website, extract it to a suitable folder, and add the folder containing the GCC executable files to the system path. After this, it can be used to compile AVR applications. Some platforms will have the AVR toolchain available via a package manager as well, which makes the process even easier.

One thing that one may notice after installing this GCC toolchain is that there is no C++ STL available. As a result, one is limited to just the C++ language features supported by GCC. As the Microchip AVR FAQ notes:

  • Obviously, none of the C++ related standard functions, classes, and template classes are available.
  • The operators new and delete are not implemented...

ESP8266 development with Sming


For ESP8266-based development, no official development tools exist from its creator (Espressif) beyond a bare-metal and RTOS-based SDK. Open source projects including Arduino then provide a more developer-friendly framework to develop applications with. The C++ alternative to Arduino on ESP8266 is Sming (https://github.com/SmingHub/Sming), which is an Arduino-compatible framework, similar to Nodate for AVR, which we looked at in the previous section.

In the next chapter (Chapter 5, Example - Soil Humidity Monitor with Wi-Fi) we will take an in-depth look at developing with this framework on the ESP8266.

ARM MCU development


Developing for ARM MCU platforms isn't significantly different from developing for AVR MCUs, except that C++ is far better supported, and there exists a wide range of toolchains to choose from, as we saw at the beginning of this chapter with just the list of popular IDEs. The list of available RTOSes for Cortex-M is much larger than for AVR or ESP8266 as well.

Using a free and open source compiler including GCC and LLVM to target a wide range of ARM MCU architectures (Cortex-M-based and similar) is where developing for ARM MCUs offers a lot of freedom, along with easy access to the full C++ STL (though one might want to hold off on exceptions).

When doing bare-metal development for Cortex-M MCUs, one may have to add this linker flag to provide basic stubs for some functionality that is normally provided by the OS:

-specs=nosys.specs

One thing that makes ARM MCUs less attractive is that there are far fewer standard boards and MCUs, such as with what one sees with AVR in the...

RTOS usage


With the limited resources available on the average MCU, and the generally fairly straightforward process loop in the applications that run on them, it is hard to make a case for using an RTOS on these MCUs. It's not until one has to do complicated resource and task management that it becomes attractive to use an RTOS in order to save development time.

The benefit of using an RTOS thus lies mostly in preventing one from having to reinvent the wheel. This is however something that has to be decided on a case-by-case basis. For most projects, having to integrate an RTOS into the development toolchain is more likely than an unrealistic idea that would add more to the workload than it would lighten it.

For projects where one is, for example, trying to balance CPU time and system resources between different communication and storage interfaces, as well as a user interface, the use of an RTOS might make a lot of sense, however.

As we saw in this chapter, a lot of embedded development uses...

Summary


In this chapter, we took a look at how to select the right MCU for a new project, as well as how to add peripherals and deal with Ethernet and serial interface requirements in a project. We considered how memory is laid out in a variety of MCUs and how to deal with the stack and heap. Finally, we looked at an example AVR project, how to develop for other MCU architectures, and whether to use an RTOS.

At this point, the reader is expected to be able to argue why they would pick one MCU over another, based on a set of project requirements. They should be capable of implementing simple projects using the UART and other peripherals, and understand proper memory management as well as the use of interrupts.

In the next chapter, we will take a good look at how to develop for the ESP8266, in the form of an embedded project that will keep track of soil moisture levels and control a watering pump when needed.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Hands-On Embedded Programming with C++17
Published in: Jan 2019Publisher: PacktISBN-13: 9781788629300
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Maya Posch

Maya Posch is a senior C++ developer with more than 15 years of experience. Discovering the joys of programming early on, and later the joys of electronics, she has always expressed a profound interest in technology, a passion that she gladly shares with others. Describing herself as a C developer who happens to like C++ and Ada, she likes to seek the limits of what can be done with the minimum of code and hardware to accomplish everything that is cool, new, and exciting. She also enjoys FPGA development, AI, and robotics research, in addition to creative writing, music, and drawing.
Read more about Maya Posch

Name

Company

License

Platforms

Notes

Atmel Studio...