amp-embedded-infra-lib

Introduction

amp-embedded-infra-lib is a set of C++ libraries and headers that provide heap-less, STL like, infrastructure for embedded software development. It includes, amongst others; a hardware abstraction layer (HAL), a remote procedure call (RPC) implementation for TCP/IP and Serial communication, a networking layer, a secure upgrade mechanism and several other re-usable utility classes.

amp-embedded-infra-lib is available as Philips Open Source under a MIT license.

Lines of Code Coverage Reliability Rating Security Rating Maintainability Rating

Overview

Diagram

infra

The infra package contains the building blocks that all further code is built upon. There are basics concept like infra::MemoryRange that provides an abstraction for a block of memory and several Containers that provide fixed-size alternatives for the well-known standard library containers like: std::vector, std::list, std::queue, etc.

In the next few chapters the contents of the components within infra will be described.

util

infra::BoundedString

infra::BoundedString is similar to std::string except that it can contain a maximum number of characters, and is not zero-terminated by default (see GitHub issue #37).

infra::BoundedString::WithStorage<5> string("abc");
EXPECT_EQ('a', string.front());
EXPECT_EQ('c', string.back());
EXPECT_FALSE(string.empty());
EXPECT_FALSE(string.full());
EXPECT_EQ(3, string.size());
EXPECT_EQ(5, string.max_size());

infra::CyclicBuffer

infra::CyclicBuffer transforms a given chunk of memory into a cyclic buffer. Data can be pushed into this buffer, and popped out again. With ContiguousRange(), the largest block starting at the start can be obtained. This is useful when feeding large blocks to e.g. DMA. In practise, the typedef CyclicByteBuffer will most often be used.

infra::CyclicBuffer<uint8_t>::WithStorage<4> buffer;
buffer.Push(std::vector<uint8_t>{ 3, 7, 9 });
buffer.Pop(2);
buffer.Push(std::vector<uint8_t>{ 2, 4 });

EXPECT_EQ((std::vector<uint8_t>{ 9, 2 }), buffer.ContiguousRange());
EXPECT_EQ(3, buffer.Size());
EXPECT_EQ(1, buffer.Available());

infra::Function

infra::Function is similar to std::function. It is an object which can contain any callable function object, e.g. free function pointers and lambda expressions. A Function is declared by providing the function signature and optionally extra storage space for the function. For example, infra::Function<void()> f; declares a function object f that has a void return-type and no parameters. infra::Function<int(char x)> g; declares a function object g that has an int return-type and one parameter of type char.

Examples:

Function<void()> f = [this]() { Trigger(); };
if (f)
  f();        // Call the lambda function which calls this->Trigger
f = nullptr;  // Clear the function

Since no heap is used, all data used by the function object must be stored inside Function itself. The amount of data necessary is not known upfront, so the Function is parameterized with an ExtraSize parameter to reserve storage. For example, this lambda expression requires no storage: []() {} while this expression requires 8 bytes of extra storage on a 32-bit platform: [this, &x]() { DoSomething(x); }.

Function<void()> f = [this, &x]() { DoSomething(x); }; // Compile error, too much storage is needed
Function<void(), 2 * sizeof(void*)> g = [this, &x]() { DoSomething(x); }; // Ok.