Added more documentation

Tweaks to CSS
This commit is contained in:
John Wellbelove 2026-05-06 07:59:33 +01:00
parent 48ec571c9e
commit e1c8a5db11
29 changed files with 2044 additions and 1186 deletions

View File

@ -0,0 +1,179 @@
---
title: "message_router_registry"
---
{{< callout type="info">}}
Header: `message_router_registry`
Since: `20.6.0`
{{< /callout >}}
A class that will act as a registry for all message router types.
When iterating through the registry, routers with identical IDs are ordered by insertion.
**Defines the following classes**
```cpp
etl::imessage_router_registry
etl::message_router_registry
```
## imessage_router_registry
The base class for all router registries.
### Iterators
```cpp
iterator
const_iterator
```
### Member functions
```cpp
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
```
Get the beginning of the registry.
---
```cpp
iterator end()
const_iterator end() const
const_iterator cend() const
```
Get the end of the registry.
---
```cpp
iterator lower_bound(etl::message_router_id_t id)
const_iterator lower_bound(etl::message_router_id_t id) const
```
Get the lower bound in the registry of the router with the specified ID.
---
```cpp
iterator upper_bound(etl::message_router_id_t id)
const_iterator upper_bound(etl::message_router_id_t id) const
```
Get the upper bound in the registry of the router with the specified ID.
---
```cpp
etl::imessage_router* find(etl::message_router_id_t id)
const etl::imessage_router* find(etl::message_router_id_t id) const
```
Returns a pointer to the first router with the specified ID, or `ETL_NULLPTR` if it cannot be found.
---
```cpp
void add(etl::imessage_router& router)
void add(etl::imessage_router* p_router)
```
Registers a router.
If the registry is full then an ETL assert is emitted (`etl::message_router_registry_full`).
Duplicate routers will be ignored.
---
```cpp
template <typename TIterator>
void add(TIterator first, const TIterator& last)
```
Registers a collection of routers.
If the registry becomes full then an ETL assert is emitted (`etl::message_router_registry_full`).
Duplicate routers will be ignored.
---
```cpp
void remove(etl::message_router_id_t id)
```
Unregisters a router.
---
```cpp
bool contains(const etl::message_router_id_t id) const
bool contains(const etl::imessage_router* const p_router) const
bool contains(const etl::imessage_router& router) const
```
Returns `true` if the registry contains a router that has the specified ID or object.
---
```cpp
bool empty() const
```
Returns `true` if the registry is empty, otherwise `false`.
---
```cpp
bool full() const
```
Returns `true` if the registry is full, otherwise `false`.
---
```cpp
size_t size() const
```
Returns the size of the registry.
---
```cpp
size_t available() const
```
Returns the available size of the registry.
---
```cpp
size_t max_size() const
```
Returns the maximum size of the registry.
---
## message_router_registry
```cpp
message_router_registry()
```
Default constructor.
---
```cpp
template <typename TIterator>
message_router_registry(TIterator first, const TIterator& last)
```
Constructs from an iterator range.
---
```cpp
message_router_registry(std::initializer_list<etl::imessage_router*> init)
```
Initializer_list constructor.
Enabled for C++11 or above.
---
```cpp
message_router_registry(const message_router_registry& rhs)
```
Copy constructor.
---
```cpp
message_router_registry& operator =(const message_router_registry& rhs)
```
Assignment operator.

View File

@ -0,0 +1,505 @@
---
title: message_router
---
A class that will automatically route incoming messages to specific handlers based on the message types declared in the template parameter list. Messages are passed to the receive member function which will static cast it to its real type and call the matching on_receive function in the derived class. A compilation error will occur if the matching on_receive does not exist.
The `on_receive` functions are not virtual. The template base class uses `CRTP` to directly call the derived class's functions.
**Defines the following classes**
```cpp
etl::imessage_router
etl::message_router
etl::null_message_router
```
Note: This C++03 portion of this header is a generated from `message_router_generator.h`. To handle more than the standard 16 message types then a new one must be generated.
See [Generators](./generators-tutorial)
## Message router ID
Allowable router IDs run from `0` to `MAX_MESSAGE_ROUTER` (`249`) inclusive.
Each message router is given an ID. Whether this ID is unique or not depends on how you are using and identifying message routers.
Note: A message router 'group' is deemed to be a set of routers with identical IDs.
The default router id is `etl::imessage_router::MESSAGE_ROUTER`.
### Scenario 1
You never send a message to a router using it's ID.
You never use the ID to uniquely identify a router.
You do not require the router ID to act as a priority level when subscribing to a message bus.
You do not require that messages can be sent to a group.
All message router IDs can be identical.
### Scenario 2
You never use the ID to uniquely identify a router.
You may use the router ID to send to a particular router group.
You require the router ID to act as a priority level when subscribing to a message bus.
Router IDs will be assigned in groups. i.e. Some routers may share IDs.
### Scenario 3
You use the ID to uniquely identify a router.
You use the router ID to send to a particular router.
You require the router ID to act as a priority level when subscribing to a message bus.
You require all priority levels to be unique.
All router IDs are unique
## imessage_router
The base class for all routers.
#### Member functions
```cpp
virtual ~imessage_router() {}
```
---
```cpp
virtual void receive(const etl::imessage& message) = 0;
```
Overridden by the derived class.
---
```cpp
virtual void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& message)
```
Receive a message for a specific destination id.
If the destination id is the router's id, then the message is forwarded to `receive(message)`.
Can be overridden by the derived class.
---
```cpp
virtual void receive(etl::shared_message shared_msg)
```
Receive a shared message.
By default, forwards to `receive(shared_msg.get_message())`.
---
```cpp
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg)
```
Receive a message for a specific destination id.
By default, forwards to `receive(destination_router_id, shared_msg.get_message())`.
---
```cpp
virtual bool accepts(etl::message_id_t id) const = 0;
```
Returns `true` if the router accepts the message id.
Overridden by the derived class.
---
```cpp
bool accepts(const etl::imessage& msg) const;
```
Returns `true` if the router accepts the message.
---
```cpp
etl::message_router_id_t get_message_router_id() const;
```
Returns the router id.
---
```cpp
virtual bool is_null_router() const = 0;
```
Returns `true` if the router is a null message router, otherwise `false`.
**Deprecated. **
---
```cpp
virtual bool is_producer() const = 0;
```
Returns `true` if the router is a producer of messages, otherwise `false`.
---
```cpp
virtual bool is_consumer() const = 0;
```
Returns `true` if the router is a consumer of messages, otherwise `false`.
---
```cpp
void set_successor(etl::imessage_router& successor);
```
Sets the successor router. Any unhandled message will be sent here.
Allows the router to implement the Chain Of Responsibility design pattern.
## Enumerations
```cpp
NULL_MESSAGE_ROUTER
MESSAGE_BUS
ALL_MESSAGE_ROUTERS
MAX_MESSAGE_ROUTER
```
---
## message_router
User defined message routers are derived from this class.
Derived from `## imessage_router`.
---
### For C++03
```cpp
template <typename TDerived,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
class message_router
```
**Template parameters**
`TDerived` The derived class.
`T1` The first message type.
`T2...` The additional message types.
The maximum number of types can be set by running the generator for this file.
The default is 16.This may be changed by running a modified version of generate_message_router.bat.
See [Generators](../tutorials/generators-tutorial)
---
### For C++11 and above
```cpp
template <typename TDerived, typename... TMessageTypes>
class message_router
```
**Template parameters**
`TDerived` The derived class.
`TMessageTypes` The list of message types.
**Before: 20.47.0**
This definition will automatically be selected if the compiler supports C++17 or above. It uses fold expressions to resolve `on_receive()` calls.
To use the older C++03 compatible definition, define `ETL_MESSAGE_ROUTER_FORCE_CPP03` as a project setting or in the optional `etl_profile.h`.
**Since: 20.47.0**
This definition will automatically be selected if the compiler supports C++11 or above. It uses either an O(1) or O(N) mechanism to resolve `on_receive()` calls.
To use the older C++03 compatible definition, define `ETL_MESSAGE_ROUTER_FORCE_CPP03` as a project setting or in the optional `etl_profile.h`.
---
The derived class must define the following member functions.
```cpp
void on_receive(const Type& msg);
```
Replace Type with each concrete message type.
Define for all of the template parameter types.
---
```cpp
void on_receive_unknown(const etl::imessage& msg)
```
Called when a message type is received that is not in the template list.
## message_packet
This is a nested member class.
See [etl::message_packet](./message-packet)
---
### Member functions
```cpp
message_router()
```
Constructs the router.
The router id is set to `etl::imassage_router::MESSAGE_ROUTER`.
---
```cpp
message_router(etl::imessage_router& successor)
```
Constructs the router.
The router id must be between `0` and `MAX_MESSAGE_ROUTER` (`249`). Other IDs are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
Sets the successor router to this one. Any unhandled message will be sent here.
---
```cpp
message_router(etl::message_router_id_t id)
```
Constructs the router.
The router id must be between `0` and `249`. Ids `250` to `255` are reserved for ETL use.
Asserts an error if the id is outside the legal range.
Routers may have duplicate ids.
---
```cpp
message_router(etl::message_router_id_t id, etl::imessage_router& successor)
```
Constructs the router.
The router id must be between 0 and MAX_MESSAGE_ROUTER (249) . Other IDs are reserved for ETL use.
Sets the successor router to this one. Any unhandled message will be sent here.
---
```cpp
void receive(const etl::imessage& msg)
```
Receives a message and routes to the `on_receive()` handler.
If not handled, passes the message on to a successor, if it exists.
---
```cpp
template <typename TMessage>
void receive(const TMessage& msg)
```
Receives a message and routes directly to the `on_receive()` handler.
This template function will be chosen for concrete message types.
If not handled, passes the message on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `true` if the router accepts the message id.
---
### Errors
```cpp
message_router_exception
```
Base exception for router errors.
Derived from `etl::exception`.
---
```cpp
message_router_illegal_id
```
The router id is out of the legal range.
Derived from `etl::message_router_exception`.
---
### null_message_router
This router can be used as a sink for messages or a 'null source' router.
Derived from `etl::imessage_router`.
---
```cpp
null_message_router()
```
Constructs a null message router.
The router id will be `etl::imessage_router::NULL_MESSAGE_ROUTER`.
---
```cpp
void receive(const etl::imessage& message)
```
Receives a message.
Does nothing, except pass on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `false` if no successor is set.
Returns `true` if a successor accepts the message id.
---
```cpp
static null_message_router& instance()
```
Returns an instance of `etl::null_message_router`.
## message_producer
This router can be used as a producer-only of messages, such an interrupt routine.
Derived from `etl::imessage_router`.
---
```cpp
message_producer(etl::message_router_id_t id);
```
Constructs the router.
The router id must be between `0` and `249`. Ids `250` to `255` are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
---
```cpp
void receive(const etl::imessage& message)
```
Receives a message.
Does nothing, except pass on to a successor, if it exists.
---
```cpp
bool accepts(etl::message_id_t id) const
```
Returns `false` if no successor is set.
Returns `true` if a successor accepts the message id.
---
```cpp
static null_message_router& instance()
```
Returns an instance of `etl::null_message_router`.
---
## Global functions
```cpp
void send_message(etl::imessage_router& router,
const etl::imessage& message)
```
Send the message to the router.
---
```cpp
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
const etl::imessage& message)
```
Send the message to the router if it has the specified id.
---
```cpp
void send_message(etl::imessage_router& router,
etl::shared_message& message)
```
Send the shared message to the router.
---
```cpp
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
etl::shared_message& message)
```
Send the shared message to the router if it has the specified id.
## Example
```cpp
// Message ids.
enum
{
START,
STOP,
SET_SPEED
};
// The start message.
struct Start : public etl::message<START>
{
};
// The stop message.
struct Stop : public etl::message<STOP>
{
};
// The set speed message.
struct SetSpeed : public etl::message<SET_SPEED>
{
SetSpeed(uint32_t speed_)
: speed(speed_)
{
}
uint32_t speed;
};
// The router.
class Router : public etl::message_router<Router, Start, Stop, SetSpeed>
{
public:
// Construct the router with an id of 0.
Router()
: message_router(0)
{
}
// Received a start message.
void on_receive(etl::imessage_router& sender, const Start& msg)
{
std::cout << "Start message received\n";
}
// Received a stop message.
void on_receive(const Stop& msg)
{
std::cout << "Start message received\n";
}
// Received a set speed message.
void on_receive(const SetSpeed& msg)
{
std::cout << "SetSpeed(" << msg.speed << ") message received\n";
}
// Received an unknown message.
void on_receive_unknown(const etl::imessage& msg)
{
std::cout << "Unknown message " << msg.message_id << " received\n";
}
}
// Router and message instances.
Router router;
Start start;
Stop stop;
SetSpeed halfSpeed(50);
SetSpeed maxSpeed(100);
// A queue for Router messages.
etl::queue<Router::message_packet, 10> queue;
// Add to the queue.
queue.emplace(start);
queue.emplace(stop);
queue.emplace(maxSpeed);
queue.emplace(halfSpeed);
// Send the queued messages to 'router'.
while (!queue.empty())
{
etl::send_message(router, queue.front().get());
queue.pop();
}
```
---
An example of a queued message router can be found in the repository in `examples/QueuedMessageRouter`.

View File

@ -0,0 +1,139 @@
---
title: "reference_counted_message_pool"
---
{{< callout type="info">}}
Header: `reference_counted_message_pool.h`
Header: `ireference_counted_message_pool.h`
{{< /callout >}}
Allocates `etl::ireference_counted_message` types that are used by `etl::shared_message`.
Uses a supplied `memory_block allocator` derived from `etl::imemory_block_allocator`.
## ireference_counted_message_pool.h
Defines the following class.
`etl::ireference_counted_message_pool`
## reference_counted_message_pool.h
Defines the following classes.
`etl::reference_counted_message_pool_exception`
`etl::reference_counted_message_pool_allocation_failure`
`etl::reference_counted_message_pool_release_failure`
## ireference_counted_message_pool
```cpp
etl::ireference_counted_message_pool
```
The interface for reference counted message pools.
```cpp
virtual ~ireference_counted_message_pool() {}
```
```cpp
virtual void release(const etl::ipool_message& msg) = 0;
```
Virtual `lock()` and `unlock()` functions are defined. The default action is to do nothing.
A derived class may override these functions to provide a thread or interrupt safe pool.
`virtual void lock()`
`virtual void unlock()`
## reference_counted_message_pool
```cpp
etl::reference_counted_message_pool<TCounter>
```
The concrete reference counted message pool.
```cpp
reference_counted_message_pool(imemory_block_allocator& memory_block_allocator)
```
Constructs the pool and assigns the memory block allocator to it.
---
```cpp
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate()
```
Returns a pointer to a pool message that holds a `TMessage`.
The message is default constructed.
ETL_ASSERT if one cannot be allocated and returns `ETL_NULLPTR`.
---
```cpp
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate(const TMessage& message)
```
Returns a pointer to a pool message that holds a `TMessage`.
ETL_ASSERT if one cannot be allocated and returns `ETL_NULLPTR`.
---
```cpp
void release(const etl::ireference_counted_message& rcmessage)
```
Returns the reference counted to a pool message that holds a `TMessage`.
`ETL_ASSERT` if it cannot be released. Reasons can include the message not belonging to the pool.
## pool_message_parameters
**C++03**
The C++03 version defines the largest size and alignment of up to 8 types at a time.
```cpp
template <typename TMessage1, typename TMessage2 = TMessage1,
typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1,
typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct pool_message_parameters
```
---
```cpp
static const size_t max_size;
```
The maximum size.
---
```cpp
static const size_t max_alignment;
```
The maximum alignment.
**C++11 or above**
The C++11 version defines the largest size and alignment of a set of message types.
```cpp
template <typename TMessage1, typename... TMessages>
struct pool_message_parameters
```
---
```cpp
static constexpr size_t max_size
```
The maximum size.
---
```cpp
static constexpr size_t max_alignment;
```
The maximum alignment.
---
**For C++11, with atomic support.**
```cpp
template <typename TObject>
using atomic_counted_message_pool = etl::reference_counted_message_pool<etl::atomic_int32_t>;
```
Defines an alias to a reference counted message pool that uses an atomic.

View File

@ -70,7 +70,7 @@ The Embedded Template Library (ETL) is not intended as a full replacement for th
- Providing a set of containers with fixed or maximum sizes defined at compile-time.
- Offering APIs that closely resemble those of the STL, enabling familiar and consistent usage.
- Maintaining compatibility with C++98 while implementing many features introduced in later standards
(C++11/14/17/20/23) where possible.
(C++11/14/17/20/23/26) wherever possible.
- Ensuring deterministic behavior, which is critical in real-time and resource-constrained environments.
- Introducing additional components and utilities useful in embedded contexts but absent from the STL.
- The ETL avoids dynamic memory allocation entirely; the heap is never used. All non-intrusive containers have a fixed capacity, allowing memory requirements to be fully determined at compile-time. This makes the ETL ideal for lower-resource embedded applications where predictability, performance, and memory control are essential.

View File

@ -1,96 +0,0 @@
Message Router Registry
20.6.0
A class that will act as a registry for all message router types.
When iterating through the registry, routers with identical IDs are ordered by insertion.
Defines the following classes:-
etl::imessage_router_registry
etl::message_router_registry
____________________________________________________________________________________________________
imessage_router_registry
The base class for all router registries.
Iterators
iterator
const_iterator
____________________________________________________________________________________________________
Member functions
iterator begin()
const_iterator begin() const
const_iterator cbegin() const
Get the beginning of the registry.
____________________________________________________________________________________________________
iterator end()
const_iterator end() const
const_iterator cend() const
Get the end of the registry.
____________________________________________________________________________________________________
iterator lower_bound(etl::message_router_id_t id)
const_iterator lower_bound(etl::message_router_id_t id) const
Get the lower bound in the registry of the router with the specified ID.
____________________________________________________________________________________________________
iterator upper_bound(etl::message_router_id_t id)
const_iterator upper_bound(etl::message_router_id_t id) const
Get the upper bound in the registry of the router with the specified ID.
____________________________________________________________________________________________________
etl::imessage_router* find(etl::message_router_id_t id)
const etl::imessage_router* find(etl::message_router_id_t id) const
Returns a pointer to the first router with the specified ID, or ETL_NULLPTR if it cannot be found.
____________________________________________________________________________________________________
void add(etl::imessage_router& router)
void add(etl::imessage_router* p_router)
Registers a router.
If the registry is full then an ETL assert is emitted (etl::message_router_registry_full).
Duplicate routers will be ignored.
template <typename TIterator>
void add(TIterator first, const TIterator& last)
Registers a collection of routers.
If the registry becomes full then an ETL assert is emitted (etl::message_router_registry_full).
Duplicate routers will be ignored.
____________________________________________________________________________________________________
void remove(etl::message_router_id_t id)
Unregisters a router.
____________________________________________________________________________________________________
bool contains(const etl::message_router_id_t id) const
bool contains(const etl::imessage_router* const p_router) const
bool contains(const etl::imessage_router& router) const
Returns true if the registry contains a router that has the specified ID or object.
____________________________________________________________________________________________________
bool empty() const
Returns true if the registry is empty, otherwise false.
____________________________________________________________________________________________________
bool full() const
Returns true if the registry is full, otherwise false.
____________________________________________________________________________________________________
size_t size() const
Returns the size of the registry.
____________________________________________________________________________________________________
size_t available() const
Returns the available size of the registry.
____________________________________________________________________________________________________
size_t max_size() const
Returns the maximum size of the registry.
____________________________________________________________________________________________________
message_router_registry
message_router_registry()
Default constructor.
____________________________________________________________________________________________________
template <typename TIterator>
message_router_registry(TIterator first, const TIterator& last)
Constructs from an iterator range.
____________________________________________________________________________________________________
message_router_registry(std::initializer_list<etl::imessage_router*> init)
Initializer_list constructor.
Enabled for C++11 or above and when using the STL.
____________________________________________________________________________________________________
message_router_registry(const message_router_registry& rhs)
Copy constructor.
____________________________________________________________________________________________________
message_router_registry& operator =(const message_router_registry& rhs)
Assignment operator.

View File

@ -1,345 +0,0 @@
Message Router
This page documents version 20.0.0 and above.
For version 19.x.x or earlier see this page.
A class that will automatically route incoming messages to specific handlers based on the message types declared in the template parameter list. Messages are passed to the receive member function which will static cast it to its real type and call the matching on_receive function in the derived class. A compilation error will occur if the matching on_receive does not exist.
The on_receive functions are not virtual. The template base class uses CRTP to directly call the derived class's functions.
Defines the following classes:-
etl::imessage_router
etl::message_router
etl::null_message_router
Note: This header is a generated from message_router_generator.h. To handle more than the standard 16 message types then a new one must be generated.
See Generators
____________________________________________________________________________________________________
Message router ID
Allowable router IDs run from 0 to MAX_MESSAGE_ROUTER (249) inclusive.
Each message router is given an ID. Whether this ID is unique or not depends on how you are using and identifying message routers.
Note: A message router 'group' is deemed to be a set of routers with identical IDs.
The default router id is etl::imassage_router::MESSAGE_ROUTER.
Scenario 1
You never send a message to a router using it's ID.
You never use the ID to uniquely identify a router.
You do not require the router ID to act as a priority level when subscribing to a message bus.
You do not require that messages can be sent to a group.
All message router IDs can be identical.
____________________________________________________________________________________________________
Scenario 2
You never use the ID to uniquely identify a router.
You may use the router ID to send to a particular router group.
You require the router ID to act as a priority level when subscribing to a message bus.
Router IDs will be assigned in groups. i.e. Some routers may share IDs.
____________________________________________________________________________________________________
Scenario 3
You use the ID to uniquely identify a router.
You use the router ID to send to a particular router.
You require the router ID to act as a priority level when subscribing to a message bus.
You require all priority levels to be unique.
All router IDs are unique
____________________________________________________________________________________________________
imessage_router
The base class for all routers.
Member functions
virtual ~imessage_router() {}
____________________________________________________________________________________________________
virtual void receive(const etl::imessage& message) = 0;
Overridden by the derived class.
____________________________________________________________________________________________________
virtual void receive(etl::message_router_id_t destination_router_id,
const etl::imessage& message)
Receive a message for a specific destination id.
If the destination id is the router's id, then the message is forwarded to receive(message);
Can be overridden by the derived class.
____________________________________________________________________________________________________
virtual void receive(etl::shared_message shared_msg)
Receive a shared message.
By default, forwards to receive(shared_msg.get_message());
____________________________________________________________________________________________________
virtual void receive(etl::message_router_id_t destination_router_id,
etl::shared_message shared_msg)
Receive a message for a specific destination id.
By default, forwards to receive(destination_router_id, shared_msg.get_message());
____________________________________________________________________________________________________
virtual bool accepts(etl::message_id_t id) const = 0;
Returns true if the router accepts the message id.
Overridden by the derived class.
____________________________________________________________________________________________________
bool accepts(const etl::imessage& msg) const;
Returns true if the router accepts the message.
____________________________________________________________________________________________________
etl::message_router_id_t get_message_router_id() const;
Returns the router id.
____________________________________________________________________________________________________
virtual bool is_null_router() const = 0; DEPRECATED
Returns true if the router is a null message router, otherwise false.
____________________________________________________________________________________________________
virtual bool is_producer() const = 0;
Returns true if the router is a producer of messages, otherwise false.
____________________________________________________________________________________________________
virtual bool is_consumer() const = 0;
Returns true if the router is a consumer of messages, otherwise false.
____________________________________________________________________________________________________
void set_successor(etl::imessage_router& successor);
Sets the successor router. Any unhandled message will be sent here.
Allows the router to implement the Chain Of Responsibility design pattern.
Enumerations
NULL_MESSAGE_ROUTER
MESSAGE_BUS
ALL_MESSAGE_ROUTERS
MAX_MESSAGE_ROUTER
____________________________________________________________________________________________________
message_router
User defined message routers are derived from this class.
Derived from imessage_router
____________________________________________________________________________________________________
For C++03 to C++14
template <typename TDerived,
typename T1, typename T2 = void, typename T3 = void, typename T4 = void,
typename T5 = void, typename T6 = void, typename T7 = void, typename T8 = void,
typename T9 = void, typename T10 = void, typename T11 = void, typename T12 = void,
typename T13 = void, typename T14 = void, typename T15 = void, typename T16 = void>
class message_router
Template parameters
TDerived The derived class.
T1 The first message type.
T2... The additional message types.
The maximum number of types can be set by running the generator for this file.
The default is 16.This may be changed by running a modified version of generate_message_router.bat.
See Generators
____________________________________________________________________________________________________
For C++17 and above
template <typename TDerived, typename... TMessageTypes>
class message_router
Template parameters
TDerived The derived class.
TMessageTypes The list of message types.
This definition will automatically be selected if the compiler supports C++17. It uses fold expressions to resolve on_receive() calls.
To use the older C++03 compatible definition, define ETL_MESSAGE_ROUTER_FORCE_CPP03 as a project setting or in the optional etl_profile.h.
____________________________________________________________________________________________________
The derived class must define the following member functions.
void on_receive(const Type& msg);
Replace Type with each concrete message type.
Define for all of the template parameter types.
____________________________________________________________________________________________________
void on_receive_unknown(const etl::imessage& msg)
Called when a message type is received that is not in the template list.
___________________________________________________________________________________________________
Member classes
message_packet
See etl::message_packet
____________________________________________________________________________________________________
Member functions
message_router()
Constructs the router.
The router id is set to etl::imassage_router::MESSAGE_ROUTER.
____________________________________________________________________________________________________
message_router(etl::imessage_router& successor)
Constructs the router.
The router id must be between 0 and MAX_MESSAGE_ROUTER (249) . Other IDs are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
Sets the successor router to this one. Any unhandled message will be sent here.
____________________________________________________________________________________________________
message_router(etl::message_router_id_t id)
Constructs the router.
The router id must be between 0 and 249. Ids 250 to 255 are reserved for ETL use.
Asserts an error if the id is outside the legal range.
Routers may have duplicate ids.
____________________________________________________________________________________________________
message_router(etl::message_router_id_t id, etl::imessage_router& successor)
Constructs the router.
The router id must be between 0 and MAX_MESSAGE_ROUTER (249) . Other IDs are reserved for ETL use.
Sets the successor router to this one. Any unhandled message will be sent here.
____________________________________________________________________________________________________
void receive(const etl::imessage& msg)
Receives a message and routes to the on_receive() handler.
If not handled, passes the message on to a successor, if it exists.
____________________________________________________________________________________________________
template <typename TMessage>
void receive(const TMessage& msg)
Receives a message and routes directly to the on_receive() handler.
This template function will be chosen for concrete message types.
If not handled, passes the message on to a successor, if it exists.
____________________________________________________________________________________________________
bool accepts(etl::message_id_t id) const
Returns true if the router accepts the message id.
____________________________________________________________________________________________________
Errors
message_router_exception
Base exception for router errors.
Derived from etl::exception.
____________________________________________________________________________________________________
message_router_illegal_id
The router id is out of the legal range.
Derived from etl::message_router_exception
____________________________________________________________________________________________________
null_message_router
This router can be used as a sink for messages or a 'null source' router.
Derived from imessage_router
____________________________________________________________________________________________________
null_message_router()
Constructs a null message router.
The router id will be etl::imessage_router::NULL_MESSAGE_ROUTER.
____________________________________________________________________________________________________
void receive(const etl::imessage& message)
Receives a message.
Does nothing, except pass on to a successor, if it exists.
____________________________________________________________________________________________________
bool accepts(etl::message_id_t id) const
Returns false if no successor is set.
Returns true if a successor accepts the message id.
____________________________________________________________________________________________________
static null_message_router& instance()
Returns an instance of etl::null_message_router.
____________________________________________________________________________________________________
message_producer
This router can be used as a producer-only of messages, such an interrupt routine.
Derived from imessage_router
____________________________________________________________________________________________________
message_producer(etl::message_router_id_t id);
Constructs the router.
The router id must be between 0 and 249. Ids 250 to 255 are reserved for ETL use.
Emits an error if the id is outside the legal range.
Routers may have duplicate ids.
____________________________________________________________________________________________________
void receive(const etl::imessage& message)
Receives a message.
Does nothing, except pass on to a successor, if it exists.
____________________________________________________________________________________________________
bool accepts(etl::message_id_t id) const
Returns false if no successor is set.
Returns true if a successor accepts the message id.
____________________________________________________________________________________________________
static null_message_router& instance()
Returns an instance of etl::null_message_router.
____________________________________________________________________________________________________
Global functions
void send_message(etl::imessage_router& router,
const etl::imessage& message);
Send the message to the router.
____________________________________________________________________________________________________
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
const etl::imessage& message);
Send the message to the router if it has the specified id.
____________________________________________________________________________________________________
void send_message(etl::imessage_router& router,
etl::shared_message& message);
Send the shared message to the router.
____________________________________________________________________________________________________
void send_message(etl::imessage_router& router,
etl::message_router_id_t id,
etl::shared_message& message);
Send the shared message to the router if it has the specified id.
____________________________________________________________________________________________________
Example
// Message ids.
enum
{
START,
STOP,
SET_SPEED
};
// The start message.
struct Start : public etl::message<START>
{
};
// The stop message.
struct Stop : public etl::message<STOP>
{
};
// The set speed message.
struct SetSpeed : public etl::message<SET_SPEED>
{
SetSpeed(uint32_t speed_)
: speed(speed_)
{
}
uint32_t speed;
};
// The router.
class Router : public etl::message_router<Router, Start, Stop, SetSpeed>
{
public:
// Construct the router with an id of 0.
Router()
: message_router(0)
{
}
// Received a start message.
void on_receive(etl::imessage_router& sender, const Start& msg)
{
std::cout << "Start message received\n";
}
// Received a stop message.
void on_receive(const Stop& msg)
{
std::cout << "Start message received\n";
}
// Received a set speed message.
void on_receive(const SetSpeed& msg)
{
std::cout << "SetSpeed(" << msg.speed << ") message received\n";
}
// Received an unknown message.
void on_receive_unknown(const etl::imessage& msg)
{
std::cout << "Unknown message " << msg.message_id << " received\n";
}
}
// Router and message instances.
Router router;
Start start;
Stop stop;
SetSpeed halfSpeed(50);
SetSpeed maxSpeed(100);
// A queue for Router messages.
etl::queue<Router::message_packet, 10> queue;
// Add to the queue.
queue.emplace(start);
queue.emplace(stop);
queue.emplace(maxSpeed);
queue.emplace(halfSpeed);
// Send the queued messages to 'router'.
while (!queue.empty())
{
etl::send_message(router, queue.front().get());
queue.pop();
}
____________________________________________________________________________________________________
An example of a queued message router can be found in the repository in examples/QueuedMessageRouter

View File

@ -1,88 +0,0 @@
Reference Counted Message Pool
Allocates etl::ireference_counted_message types that are used by etl::shared_message.
Uses a supplied memory_block allocator derived from etl::imemory_block_allocator
ireference_counted_message_pool.h
Defines the following class.
etl::ireference_counted_message_pool
reference_counted_message_pool.h
Defines the following classes.
etl::reference_counted_message_pool_exception
etl::reference_counted_message_pool_allocation_failure
etl::reference_counted_message_pool_release_failure
etl::reference_counted_message_pool<typename TCounter>
____________________________________________________________________________________________________
ireference_counted_message_pool
etl::ireference_counted_message_pool
The interface for reference counted message pools.
virtual ~ireference_counted_message_pool() {}
virtual void release(const etl::ipool_message& msg) = 0;
Virtual lock() and unlock() functions are defined. The default action is to do nothing.
A derived class may override these functions to provide a thread or interrupt safe pool.
virtual void lock()
virtual void unlock()
____________________________________________________________________________________________________
reference_counted_message_pool
etl::reference_counted_message_pool<TCounter>
The concrete reference counted message pool.
reference_counted_message_pool(imemory_block_allocator& memory_block_allocator)
Constructs the pool and assigns the memory block allocator to it.
____________________________________________________________________________________________________
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate()
Returns a pointer to a pool message that holds a TMessage.
The message is default constructed.
ETL_ASSERT if one cannot be allocated and returns ETL_NULLPTR .
____________________________________________________________________________________________________
template <typename TMessage>
etl::reference_counted_message<TMessage, TCounter>* allocate(const TMessage& message)
Returns a pointer to a pool message that holds a TMessage.
ETL_ASSERT if one cannot be allocated and returns ETL_NULLPTR .
____________________________________________________________________________________________________
void release(const etl::ireference_counted_message& rcmessage)
Returns the reference counted to a pool message that holds a TMessage.
ETL_ASSERT if it cannot be released. Reasons can include the message not belonging to the pool.
____________________________________________________________________________________________________
pool_message_parameters
C++03
The C++03 version defines the largest size and alignment of up to 8 types at a time.
template <typename TMessage1, typename TMessage2 = TMessage1,
typename TMessage3 = TMessage1, typename TMessage4 = TMessage1,
typename TMessage5 = TMessage1, typename TMessage6 = TMessage1,
typename TMessage7 = TMessage1, typename TMessage8 = TMessage1>
struct pool_message_parameters
static const size_t max_size;
The maximum size.
static const size_t max_alignment;
The maximum alignment.
C++11 or above
The C++11 version defines the largest size and alignment of a set of message types.
template <typename TMessage1, typename... TMessages>
struct pool_message_parameters
static constexpr size_t max_size
The maximum size.
static constexpr size_t max_alignment;
The maximum alignment.
____________________________________________________________________________________________________
For C++11, with atomic support.
template <typename TObject>
using atomic_counted_message_pool = etl::reference_counted_message_pool<etl::atomic_int32_t>;
Defines an alias to a reference counted message pool that uses an atomic.

View File

@ -1,16 +0,0 @@
Tutorials
I've created a (growing) set of tutorials to help you get to know the library better.
If there is an aspect of the library that you find difficult to use or understand then let me know and I'll try to put together some examples of how to use it, and even why you should use it.
function A set of wrapper templates to allow a member or static function to be called without the caller having to know the specific details of the callee.
Containers A quick introduction to containers.
observer A templated set of classes to allow easier implementation of the observer pattern.
visitor A templated set of classes to allow easier implementation of the visitor pattern.
Messages The messaging framework.
Generators Generators create parts of the ETL code based on user requirements.
Concurrent Queues A set of concurrent queues, both Single Producer / Single Consumer (SPSC) and Muli Producer / Multi Consumer (MPMC)
callback_service This code demonstrates using the callback service for five example ARM interrupts.
delegate_service This code demonstrates using the delegate service for five example ARM interrupts.
shared_message How to use shared messages with the ETL messaging framework.
Locked Queues How the locked queues differ from each other.
etl::unique_ptr with etl::pool Using an etl::unique_ptr with etl::pool

View File

@ -1,104 +1,178 @@
Callback Timer Atomic
20.22.0
---
title: "callback_timer_atomic"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `callback_timer_atomic.h`
Since: `20.22.0`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to `tick(uint32_t count)`. This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
The framework relies on an atomic counter type. With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
Each timer may have a period of up to 2<sup>32</sup>-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
Defines the following classes:-
The framework relies on an atomic counter type. With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
**Defines the following classes**
```cpp
etl::icallback_timer_atomic<uint_least8_t MAX_TIMERS, typename TSemaphore>
etl::callback_timer_atomic<typename TSemaphore>
```
20.25.0
From this version, an atomic 'semaphore' counter type must be supplied.
Since: `20.25.0`
From this version, an atomic 'semaphore' counter type must be supplied.
Uses definitions from timer.h
Uses definitions from `timer.h`.
Important:
For correct operation of the timer framework, the routine that calls tick must not be pre-emptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution
____________________________________________________________________________________________________
icallback_timer_atomic
**Important**
For correct operation of the timer framework, the routine that calls tick must not be pre-emptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution.
## icallback_timer_atomic
The base class for all timer controllers.
Type definitions
### Type definitions
```cpp
callback_type etl::delegate<void(void)>
```
The function type used for callbacks.
_____________________________________________________________________________________________________
Member functions
### Member functions
```cpp
etl::timer::id::type register_timer(callback_type callback,
uint32_t period,
bool repeating)
```
**Description**
Registers a timer calling a free or static function.
callback A delegate to the callback funtion that will be callled when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
Returns the allocated timer id or etl::timer::mode::NO_TIMER if one was not available.
____________________________________________________________________________________________________
**Parameters**
callback A delegate to the callback funtion that will be callled when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
**Return**
The allocated timer id or `etl::timer::mode::NO_TIMER` if one was not available.
---
```cpp
bool unregister_timer(etl::timer::id::type id)
```
**Description**
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
___________________________________________________________________________________________________
Returns `true` if a timer with the id was successfully unregistered.
---
```cpp
void enable(bool state)
```
**Description**
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
```
**Description**
Returns `true` if the timer manager is enabled.
---
```cpp
void clear()
```
**Description**
Clears the callback timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
This function updates the internal tick counter (if enabled) and must pass the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
____________________________________________________________________________________________________
```
**Description**
This function updates the internal tick counter (if enabled) and must pass the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
**Description**
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is `true` then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool stop(etl::timer::id::type id)
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
**Description**
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id, uint32_t period)
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
```
**Description**
Stops the timer with the specified id.
Sets a new timer period.
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id, bool repeating)
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
```
**Description**
Stops the timer with the specified id.
Sets a new timer mode.
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
MAX_TIMERS
```
**Description**
Returns the time to the next timeout.
Since: `20.38.0`
### Constants
`MAX_TIMERS`
The maximum number of timer that can be handled.
____________________________________________________________________________________________________
callback_timer_atomic
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
---
## callback_timer_atomic
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
____________________________________________________________________________________________________
message_timer_atomic()
Default construct.
____________________________________________________________________________________________________
Example
---
```cpp
message_timer_atomic()
```
**Description**
Default constructor.
## Example
```cpp
//***************************************************************************
// Class callback via etl::function
//***************************************************************************
@ -197,4 +271,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,109 +1,178 @@
Callback Timer Interrupt
20.25.0
---
title: "callback_timer_interrupt"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `callback_timer_interrupt.h`
Since: `20.25.0`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to `tick(uint32_t count)`. This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
The framework relies on a supplied interrupt enable/disable guard type. With this mechanism, calls to tick are disabled if certain member functions are called. If the program flow is within a disable/enable section when the timer interrupt is activated then the tick update will be deferred until the next tick period. The timer interrupt may interrogate the return value of tick() to check whether the update was deferred. The guard allows timer functions to be to be called from the callback called by tick().
Each timer may have a period of up to 2<sup>32</sup>-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
Defines the following classes:-
The framework relies on a supplied interrupt enable/disable guard type. With this mechanism, calls to tick are disabled if certain member functions are called. If the program flow is within a disable/enable section when the timer interrupt is activated then the tick update will be deferred until the next tick period. The timer interrupt may interrogate the return value of tick() to check whether the update was deferred. The guard allows timer functions to be to be called from the callback called by tick().
**Defines the following classes**
```cpp
etl::icallback_timer_atomic<uint_least8_t MAX_TIMERS, typename TInterruptGuard>
etl::callback_timer_atomic<typename TInterruptGuard>
```
Uses definitions from timer.h
Uses definitions from `timer.h`.
Important:
For correct operation of the timer framework, the routine that calls tick must not be pre-emptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution
____________________________________________________________________________________________________
icallback_timer_atomic
The base class for all timer controllers.
**Important**
For correct operation of the timer framework, the routine that calls tick must not be preemptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution.
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
## icallback_timer_interrupt
The base class for all timer controllers.
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
_____________________________________________________________________________________________________
TInterruptGuard The type that enables/disables interrupts.
Type definitions
`TInterruptGuard` The type that enables/disables interrupts.
**Type definitions**
```cpp
callback_type etl::delegate<void(void)>
```
The function type used for callbacks.
_____________________________________________________________________________________________________
Member functions
### Member functions
```cpp
etl::timer::id::type register_timer(callback_type callback,
uint32_t period,
bool repeating)
Registers a timer calling a free or static function.
callback A delegate to the callback funtion that will be callled when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
```
**Description**
Registers a timer calling a free or static function.
Returns the allocated timer id or etl::timer::mode::NO_TIMER if one was not available.
____________________________________________________________________________________________________
**Parameters**
callback A delegate to the callback function that will be called when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
**Return**
The allocated timer id or etl::timer::mode::NO_TIMER if one was not available.
---
```cpp
bool unregister_timer(etl::timer::id::type id)
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
___________________________________________________________________________________________________
void enable(bool state)
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
bool is_running() const
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
void clear()
Clears the callback timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
bool tick(uint32_t count)
This function updates the internal tick counter (if enabled) and must pass the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
____________________________________________________________________________________________________
bool start(etl::timer::id::type id, bool immediate = false)
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
bool stop(etl::timer::id::type id)
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
bool set_period(etl::timer::id::type id, uint32_t period)
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
bool set_mode(etl::timer::id::type id, bool repeating)
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
etl::timer::id::type time_to_next()
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
MAX_TIMERS
The maximum number of timer that can be handled.
____________________________________________________________________________________________________
callback_timer_atomic
```
Unregisters a timer.
If the timer is active then it will be stopped.
Returns `true` if a timer with the id was successfully unregistered.
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
---
```cpp
void enable(bool state)
```
**Description**
Enables or disables the timer manager according to the state.
---
```cpp
bool is_running() const
```
**Description**
```cpp
Returns `true` if the timer manager is enabled.
---
```cpp
void clear()
```
**Description**
Clears the callback timer back to the initial state. All timers will be stopped and unregistered.
---
```cpp
bool tick(uint32_t count)
```
**Description**
This function updates the internal tick counter (if enabled) and must pass the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
```
**Description**
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is `true` then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool stop(etl::timer::id::type id)
```
**Description**
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id, uint32_t period)
```
**Description**
Stops the timer with the specified id.
Sets a new timer period.
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id, bool repeating)
```
**Description**
Stops the timer with the specified id.
Sets a new timer mode.
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
```
**Description**
Returns the time to the next timeout.
Since: `20.38.0`
### Constants
`MAX_TIMERS`
The maximum number of timer that can be handled.
## callback_timer_atomic
**Template parameters**
`MAX_TIMERS`
The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
TInterruptGuard The type that enables/disables interrupts.
____________________________________________________________________________________________________
message_timer_atomic()
Default construct.
____________________________________________________________________________________________________
Example
`TInterruptGuard`
The type that enables/disables interrupts.
## message_timer_interrupt()
**Description**
Default constructor.
## Example
```cpp
//***************************************************************************
// Class callback via etl::function
//***************************************************************************
@ -223,4 +292,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,146 +1,220 @@
Callback Timer
This class has been superseded.
Consider using callback_timer_atomic or callback_timer_locked.
---
title: "callback_timer"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `callback_timer.h`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
**This class has been superseded.**
Consider using `callback_timer_atomic` or `callback_timer_locked`.
Defines the following classes:-
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will call the selected function. The function may be a class member or free function.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination function will receive the callback in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
Each timer may have a period of up to 2<sup>32</sup>-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
**Defines the following classes**
```cpp
etl::icallback_timer
etl::callback_timer
etl::callback_timer_data
```
Uses definitions from timer.h
Uses definitions from `timer.h`.
An example Keil project for the Nucleo 401RE may be found in examples/ArmTimerCallbacks - C++
An example Keil project for the Nucleo 401RE may be found in `examples/ArmTimerCallbacks - C++`
Usage notes
The message timer is designed to be used in a timer interrupt/thread - single foreground task environment. The timer tick call may pre-empt the foreground task, except when a timer function is within a ETL_DISABLE_TIMER_UPDATES / ETL_ENABLE_TIMER_UPDATES section. These macros will either use an atomic semaphore or contain code to disable or enable the relevant timer interrupts.
---
**Usage notes**
The message timer is designed to be used in a timer interrupt/thread - single foreground task environment. The timer tick call may pre-empt the foreground task, except when a timer function is within a `ETL_DISABLE_TIMER_UPDATES` / `ETL_ENABLE_TIMER_UPDATES` section. These macros will either use an atomic semaphore or contain code to disable or enable the relevant timer interrupts.
---
There are two macros that control which mechanism is used.
____________________________________________________________________________________________________
ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK
The framework relies on an atomic counter type. By default this is defined as etl::timer_semaphore_t.
This in turn is either defined as std::atomic<uint32_t>, if the compiler supports std::atomic, or
etl::atomic<uint32_t> if there is an atomic_xxx.h defined for the platform. A user defined type may be used for the semaphore by defining ETL_TIMER_SEMAPHORE_TYPE. Only the timer interrupt/thread and one foreground task may call register_timer, unregister_timer, clear, start or stop.
With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
____________________________________________________________________________________________________
ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK
`ETL_CALLBACK_TIMER_USE_ATOMIC_LOCK`
The user must supply two macro definitions (ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS and ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS) to control interrupt enables. These macros must enable/disable all interrupts that may call tick, register_timer, unregister_timer, clear, start or stop.
The user should ensure that mechanisms, such as memory barriers are used to disable re-ordering of the instructions.
If the foreground task is within a disable/enable section when the timer interrupt is triggered then the tick update will be deferred until the interrupts are re-enabled. Depending on the resolution of the timers, the interrupt routine may be able to compensate for the delay by passing a modified tick count to tick().
The framework relies on an atomic counter type. By default this is defined as etl::timer_semaphore_t.
This in turn is either defined as std::atomic<uint32_t>, if the compiler supports `std::atomic`, or
`etl::atomic<uint32_t>` if there is an `atomic_xxx.h` defined for the platform. A user defined type may be used for the semaphore by defining `ETL_TIMER_SEMAPHORE_TYPE`. Only the timer interrupt/thread and one foreground task may call `register_timer`, `unregister_timer`, `clear`, `start` or `stop`.
With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
Important:
For correct operation of the timer framework, the routine that calls tick must not be pre-emptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution
____________________________________________________________________________________________________
icallback_timer
---
`ETL_CALLBACK_TIMER_USE_INTERRUPT_LOCK`
The user must supply two macro definitions (`ETL_CALLBACK_TIMER_DISABLE_INTERRUPTS` and `ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS`) to control interrupt enables. These macros must enable/disable all interrupts that may call `tick`, `register_timer`, `unregister_timer`, `clear`, `start` or `stop`.
The user should ensure that mechanisms, such as memory barriers are used to disable re-ordering of the instructions.
If the foreground task is within a disable/enable section when the timer interrupt is triggered then the tick update will be deferred until the interrupts are re-enabled. Depending on the resolution of the timers, the interrupt routine may be able to compensate for the delay by passing a modified tick count to `tick()`.
---
**Important**
For correct operation of the timer framework, the routine that calls tick must not be preemptible by another routine that calls a timer function. Also, calls to the timer framework may only be made from the caller of tick and one other, lower priority, thread of execution.
## icallback_timer
The base class for all timer controllers.
Member functions
### Member functions
```cpp
etl::timer::id::type register_timer(void (*p_callback)(),
uint32_t period,
bool repeating)
```
**Description**
Registers a timer calling a free or static function.
p_callback A pointer to the callback free funtion that will be callled when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
Returns the allocated timer id or etl::timer::mode::NO_TIMER if one was not available.
_____________________________________________________________________________________________________
**Parameters**
`p_callback` A pointer to the callback free function that will be called when the timer expires.
`period` The timer period in ticks.
`repeating` `false` if single shot, `true` if repeating.
**Return**
The allocated timer id or `etl::timer::mode::NO_TIMER` if one was not available.
---
```cpp
etl::timer::id::type register_timer(etl::ifunction<void>& callback,
uint32_t period,
bool repeating)
```
**Description**
Registers a timer calling a free, static or member function through the etl::ifunction interface.
**Parameters**
p_callback A reference to the etl::function callback function that will be called when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
repeating `false` if single shot, `true` if repeating.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
_____________________________________________________________________________________________________
**Return**
The allocated timer id or `etl::timer::id::NO_TIMER` if one was not available.
---
```cpp
etl::timer::id::type register_timer(etl::delegate<void()>& callback,
uint32_t period,
bool repeating)
```
**Description**
Registers a timer calling a free, static or member function through the etl::delegate interface.
p_callback A reference to the etl::delegate callback function that will be called when the timer expires.
period The timer period in ticks.
repeating false if single shot, true if repeating.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
____________________________________________________________________________________________________
bool unregister_timer(etl::timer::id::type id)
---
```cpp
bool unregister_timer(etl::timer::id::type id)
```
**Description**
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
___________________________________________________________________________________________________
Returns `true` if a timer with the id was successfully unregistered.
---
```cpp
void enable(bool state)
```
**Description**
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
```
**Description**
Returns `true` if the timer manager is enabled.
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
---
```cpp
void clear()
```
**Description**
Clears the callback timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
```
**Description**
This function updates the internal tick counter (if enabled) and must pass the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
____________________________________________________________________________________________________
bool start(etl::timer::id::type id, bool immediate = false)
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
```
**Description**
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
bool stop(etl::timer::id::type id)
If immediate is `true` then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool stop(etl::timer::id::type id)
```
**Description**
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
bool set_period(etl::timer::id::type id, uint32_t period)
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id, uint32_t period)
```
**Description**
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
bool set_mode(etl::timer::id::type id, bool repeating)
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id, bool repeating)
```
**Description**
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
```
**Description**
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
Since: `20.38.0`
MAX_TIMERS
____________________________________________________________________________________________________
callback_timer
### Constants
`MAX_TIMERS`
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
## callback_timer
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
____________________________________________________________________________________________________
Example
## Example
```cpp
//***************************************************************************
// Class callback via etl::function
//***************************************************************************
@ -241,4 +315,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,101 +1,157 @@
Message Timer Atomic
---
title: "message_timer_atomic"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
{{< callout type="info">}}
Header: `message_timer_atomic.h`
{{< /callout >}}
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to `tick(uint32_t count)`. This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
Each timer may have a period of up to 2<sup>32</sup> - 2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
The framework relies on an atomic counter type. With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
The framework relies on an atomic counter type. With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of `tick()` to check whether the update was deferred.
Defines the following classes:-
**Defines the following classes**
```cpp
etl::imessage_timer_atomic<uint_least8_t MAX_TIMERS, typename TSemaphore>
etl::message_timer_atomic<typename TSemaphore>
```
20.25.0
From this version, an atomic 'semaphore' counter type must be supplied.
Since: `20.25.0`
From this version, an atomic 'semaphore' counter type must be supplied.
Uses definitions from timer.h
____________________________________________________________________________________________________
imessage_timer_atomic
Uses definitions from `timer.h`.
The base class for all timer controllers.
## imessage_timer_atomic
Member functions
The base class for all timer controllers.
---
```cpp
etl::timer::id::type register_timer(const etl::imessage& message,
etl::imessage_router& router,
uint32_t period,
bool repeating,
etl::message_router_id_t destination_router_id =
etl::imessage_router::ALL_MESSAGE_ROUTERS)
Registers a timer.
message A reference to the message that will be sent when the timer expires.
router A reference to a router or bus that will receive to message.
period The timer period in ticks.
repeating false if single shot, true if repeating.
destination_router_id The id of the destination router. Only valid if the router is a bus. Default to all routers.
```
Registers a timer.
`message` A reference to the message that will be sent when the timer expires.
`router` A reference to a router or bus that will receive to message.
`period` The timer period in ticks.
`repeating` `false` if single shot, `true` if repeating.
`destination_router_id` The id of the destination router. Only valid if the router is a bus. Default to all routers.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
____________________________________________________________________________________________________
---
```cpp
bool unregister_timer(etl::timer::id::type id)
Unregisters a timer.
If the timer is active then it will be stopped.
```
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
____________________________________________________________________________________________________
---
```cpp
void enable(bool state)
```
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
```
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
---
```cpp
void clear()
```
Clears the message timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
___________________________________________________________________________________________________
```
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool stop(etl::timer::id::type id)
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id_, uint32_t period)
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Sets a new timer period.
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id_, bool repeating)
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Sets a new timer mode.
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
MAX_TIMERS
____________________________________________________________________________________________________
message_timer_atomic
```
Returns the time to the next timeout.
Since: `20.38.0`
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
____________________________________________________________________________________________________
### Constants
`MAX_TIMERS`
## message_timer_atomic
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is `254`.
A value of `255` will result in a compilation error.
---
```cpp
message_timer_atomic()
Default construct.
____________________________________________________________________________________________________
Example
```
Default constructor.
---
## Example
```cpp
//***************************************************************************
// The set of messages.
//***************************************************************************
@ -229,4 +285,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,100 +1,165 @@
Message Timer Interrupt
20.25.0
---
title: "message_timer_interrupt"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `message_timer_interrupt.h`
Since: `20.25.0`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to `tick(uint32_t count)`. This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
The framework relies on a supplied interrupt enable/disable guard type. With this mechanism, calls to tick are disabled if certain member functions are called. If the program flow is within a disable/enable section when the timer interrupt is activated then the tick update will be deferred until the next tick period. The timer interrupt may interrogate the return value of tick() to check whether the update was deferred. The guard allows timer functions to be to be called from the message handler called by tick().
Each timer may have a period of up to 2<sup>32</sup> - 2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
Defines the following classes:-
The framework relies on a supplied interrupt enable/disable guard type. With this mechanism, calls to tick are disabled if certain member functions are called. If the program flow is within a disable/enable section when the timer interrupt is activated then the tick update will be deferred until the next tick period. The timer interrupt may interrogate the return value of `tick()` to check whether the update was deferred. The guard allows timer functions to be to be called from the message handler called by `tick()`.
**Defines the following classes**
```cpp
etl::imessage_timer_atomic<uint_least8_t MAX_TIMERS, typename TInterruptGuard>
etl::message_timer_atomic<typename TInterruptGuard>
```
The TInterruptGuard type must disable and save the interrupt state on construction, and restore on destruction.
The `TInterruptGuard` type must disable and save the interrupt state on construction, and restore on destruction.
Uses definitions from timer.h
____________________________________________________________________________________________________
imessage_timer_atomic
The base class for all timer controllers.
Uses definitions from `timer.h`.
Template parameters
TInterruptGuard The type that enables/disables interrupts.
____________________________________________________________________________________________________
Member functions
etl::timer::id::type register_timer(const etl::imessage& message,
etl::imessage_router& router,
uint32_t period,
bool repeating,
etl::message_router_id_t destination_router_id =
etl::imessage_router::ALL_MESSAGE_ROUTERS)
## imessage_timer_atomic
The base class for all timer controllers.
**Template parameters**
`TInterruptGuard` The type that enables/disables interrupts.
### Member functions
```cpp
etl::timer::id::type
register_timer(const etl::imessage& message,
etl::imessage_router& router,
uint32_t period,
bool repeating,
etl::message_router_id_t destination_router_id = etl::imessage_router::ALL_MESSAGE_ROUTERS)
```
**Description**
Registers a timer.
message A reference to the message that will be sent when the timer expires.
router A reference to a router or bus that will receive to message.
period The timer period in ticks.
repeating false if single shot, true if repeating.
destination_router_id The id of the destination router. Only valid if the router is a bus. Default to all routers.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
____________________________________________________________________________________________________
**Parameters**
`message` A reference to the message that will be sent when the timer expires.
`router` A reference to a router or bus that will receive to message.
`period` The timer period in ticks.
`repeating` false if single shot, true if repeating.
`destination_router_id` The id of the destination router. Only valid if the router is a bus. Default to all routers.
**Return**
The allocated timer id or `etl::timer::id::NO_TIMER` if one was not available.
---
```cpp
bool unregister_timer(etl::timer::id::type id)
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
____________________________________________________________________________________________________
```
**Description**
Unregisters a timer.
If the timer is active then it will be stopped.
Returns `true` if a timer with the id was successfully unregistered.
---
```cpp
void enable(bool state)
```
**Description**
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
```
**Description**
Returns `true` if the timer manager is enabled.
---
```cpp
void clear()
```
**Description**
Clears the message timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
___________________________________________________________________________________________________
```
**Description**
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
```
**Description**
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
---
```cpp
bool stop(etl::timer::id::type id)
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
```
**Description**
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
---
```cpp
bool set_period(etl::timer::id::type id_, uint32_t period)
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
```
**Description**
Stops the timer with the specified id.
Sets a new timer period.
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id_, bool repeating)
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
```
**Description**
Stops the timer with the specified id.
Sets a new timer mode.
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
MAX_TIMERS
____________________________________________________________________________________________________
message_timer_atomic
```
**Description**
Returns the time to the next timeout.
Since: `20.38.0`
____________________________________________________________________________________________________
### Constants
`MAX_TIMERS`
## message_timer_atomic
```cpp
message_timer_atomic()
```
**Description**
Default construct.
____________________________________________________________________________________________________
Example
## Example
```cpp
//***************************************************************************
// The set of messages.
//***************************************************************************
@ -249,4 +314,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,111 +1,192 @@
Message Timer Locked
---
title: "message_timer_locked"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `message_timer_locked.h`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to `tick(uint32_t count)`. This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
Defines the following classes:-
Each timer may have a period of up to 2<sup>32</sup>-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
**Defines the following classes**
```cpp
etl::imessage_timer_locked
etl::message_timer_locked
```
The access to the timers is controlled by three external functions, supplied to the timer by the
member function set_locks.
The access to the timers is controlled by three external functions, supplied to the timer by the member function set_locks.
The three delegate parameters are:-
Try Lock Attempts to set the lock. Returns true if successful, otherwise false.
Lock Sets the lock.
Unlock Resets the lock.
**The three delegate parameters are**
`Try Lock` Attempts to set the lock. Returns `true` if successful, otherwise `false`.
`Lock` Sets the lock.
`Unlock` Resets the lock.
Uses definitions from timer.h
____________________________________________________________________________________________________
imessage_timer_atomic
Uses definitions from `timer.h`
## imessage_timer_atomic
The base class for all timer controllers.
Member functions
### Member functions
```cpp
etl::timer::id::type register_timer(const etl::imessage& message,
etl::imessage_router& router,
uint32_t period,
bool repeating,
etl::message_router_id_t destination_router_id =
etl::imessage_router::ALL_MESSAGE_ROUTERS)
```
**Description**
Registers a timer.
message A reference to the message that will be sent when the timer expires.
router A reference to a router or bus that will receive to message.
period The timer period in ticks.
repeating false if single shot, true if repeating.
destination_router_id The id of the destination router. Only valid if the router is a bus. Default to all routers.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
____________________________________________________________________________________________________
**Parameters**
`message` A reference to the message that will be sent when the timer expires.
`router` A reference to a router or bus that will receive to message.
`period` The timer period in ticks.
`repeating` `false` if single shot, `true` if repeating.
`destination_router_id` The id of the destination router. Only valid if the router is a bus. Default to all routers.
**Return**
The allocated timer id or `etl::timer::id::NO_TIMER` if one was not available.
---
```cpp
bool unregister_timer(etl::timer::id::type id)
```
**Description**
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
____________________________________________________________________________________________________
Returns `true` if a timer with the id was successfully unregistered.
---
```cpp
void enable(bool state)
```
**Description**
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
```
**Description**
Returns `true` if the timer manager is enabled.
---
```cpp
void clear()
```
**Description**
Clears the message timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
```
**Description**
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
___________________________________________________________________________________________________
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
```
**Description**
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If immediate is `true` then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
---
```cpp
bool stop(etl::timer::id::type id)
```
**Description**
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id_, uint32_t period)
```
**Description**
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id_, bool repeating)
```
**Description**
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
Returns `true` if successful.
---
```cpp
void set_locks(try_lock_type try_lock_, lock_type lock_, lock_type unlock_)
```
**Description**
Sets the try-lock, lock and unlock delegates.
____________________________________________________________________________________________________
---
```cpp
etl::timer::id::type time_to_next()
```
**Description**
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
MAX_TIMERS
____________________________________________________________________________________________________
message_timer_atomic
Since: `20.38.0`
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
---
### Constants
`MAX_TIMERS`
## message_timer_locked
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
____________________________________________________________________________________________________
message_timer_locked()
Default construct.
The lock callback delegates are not set.
____________________________________________________________________________________________________
message_timer_locked(try_lock_type try_lock, lock_type lock, unlock_type unlock)
Construct from lock callback delegates are not set.
____________________________________________________________________________________________________
Example
---
```cpp
message_timer_locked()
```
**Description**
Default construct.
The lock callback delegates are not set.
---
```cpp
message_timer_locked(try_lock_type try_lock, lock_type lock, unlock_type unlock)
```
**Description**
Construct from lock callback delegates are not set.
## Example
```cpp
//***************************************************************************
// The set of messages.
//***************************************************************************
@ -239,4 +320,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,115 +1,173 @@
Message Timer
This class has been superseded.
Consider using message_timer_atomic or message_timer_locked.
---
title: "message_timer"
---
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
{{< callout type="info">}}
Header: `message_timer.h`
{{< /callout >}}
Each timer may have a period of up to 232-2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
This class has been superseded.
Consider using `message_timer_atomic` or `message_timer_locked`.
Defines the following classes:-
A software timer class that can manage up to 254 timers. Each one may be repeating or single shot.
When a timer triggers it will send the defined message to the selected message router or bus.
The timers are driven from a call to tick(uint32_t count). This call would normally be made from a high priority interrupt routine. The destination router will receive the message in the same context as the tick call.
The call to tick has a low overhead when a timer is not 'due'. Internally the timers are stored in 'first timeout' order so only the head of the list needs to be checked.
Each timer may have a period of up to 2<sup>32</sup> - 2 ticks (4,294,967,294).
At 1ms per tick this would equate to just over 49 days.
**Defines the following classes**
```cpp
etl::imessage_timer
etl::message_timer
etl::message_timer_data
```
Uses definitions from timer.h
____________________________________________________________________________________________________
Usage notes
The message timer is designed to be used in a timer interrupt/thread - single foreground task environment. The timer tick call may pre-empt the foreground task, except when a timer function is within a ETL_DISABLE_TIMER_UPDATES / ETL_ENABLE_TIMER_UPDATES section. These macros will either use an atomic semaphore or contain code to disable or enable the relevant timer interrupts.
Uses definitions from `timer.h`.
There are two macros that control which mechanism is used.
____________________________________________________________________________________________________
ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK
## Usage notes
The message timer is designed to be used in a timer interrupt/thread - single foreground task environment. The timer tick call may pre-empt the foreground task, except when a timer function is within a `ETL_DISABLE_TIMER_UPDATES` / `ETL_ENABLE_TIMER_UPDATES` section. These macros will either use an atomic semaphore or contain code to disable or enable the relevant timer interrupts.
The framework relies on an atomic counter type. By default this is defined as etl::timer_semaphore_t.
This in turn is either defined as std::atomic<uint32_t>, if the compiler supports std::atomic, or
etl::atomic<uint32_t> if there is an atomic_xxx.h defined for the platform. A user defined type may be used for the semaphore by defining ETL_TIMER_SEMAPHORE_TYPE. Only the timer interrupt/thread and one foreground task may call register_timer, unregister_timer, clear, start or stop.
With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of tick() to check whether the update was deferred.
____________________________________________________________________________________________________
ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK
There are two macros that control which mechanism is used.
The user must supply two macro definitions (ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS and ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS) to control interrupt enables. These macros must enable/disable all interrupts that may call tick, register_timer, unregister_timer, clear, start or stop.
The user should ensure that mechanisms, such as memory barriers are used to disable re-ordering of the instructions.
If the foreground task is within a disable/enable section when the timer interrupt is triggered then the tick update will be deferred until the interrupts are re-enabled. Depending on the resolution of the timers, the interrupt routine may be able to compensate for the delay by passing a modified tick count to tick().
____________________________________________________________________________________________________
imessage_timer
---
The base class for all timer controllers.
`ETL_MESSAGE_TIMER_USE_ATOMIC_LOCK`
Member functions
The framework relies on an atomic counter type. By default this is defined as `etl::timer_semaphore_t`.
This in turn is either defined as `std::atomic<uint32_t>`, if the compiler supports `std::atomic`, or `etl::atomic<uint32_t>` if there is an `atomic_xxx.h` defined for the platform. A user defined type may be used for the semaphore by defining `ETL_TIMER_SEMAPHORE_TYPE`. Only the timer interrupt/thread and one foreground task may call register_timer, unregister_timer, clear, start or stop.
With this mechanism, calls to tick are never disabled. If the foreground thread is within a disable/enable section when the timer interrupt/thread is activated then the tick update will be deferred until the next tick period. The timer interrupt/thread may interrogate the return value of `tick()` to check whether the update was deferred.
---
`ETL_MESSAGE_TIMER_USE_INTERRUPT_LOCK`
The user must supply two macro definitions (`ETL_MESSAGE_TIMER_DISABLE_INTERRUPTS` and `ETL_MESSAGE_TIMER_ENABLE_INTERRUPTS`) to control interrupt enables. These macros must enable/disable all interrupts that may call `tick`, `register_timer`, `unregister_timer`, `clear`, `start` or `stop`.
The user should ensure that mechanisms, such as memory barriers are used to disable re-ordering of the instructions.
If the foreground task is within a disable/enable section when the timer interrupt is triggered then the tick update will be deferred until the interrupts are re-enabled. Depending on the resolution of the timers, the interrupt routine may be able to compensate for the delay by passing a modified tick count to `tick()`.
## imessage_timer
The base class for all timer controllers.
**Member functions**
```cpp
etl::timer::id::type register_timer(const etl::imessage& message,
etl::imessage_router& router,
uint32_t period,
bool repeating,
etl::message_router_id_t destination_router_id =
etl::imessage_router::ALL_MESSAGE_ROUTERS)
Registers a timer.
message A reference to the message that will be sent when the timer expires.
router A reference to a router or bus that will receive to message.
period The timer period in ticks.
repeating false if single shot, true if repeating.
destination_router_id The id of the destination router. Only valid if the router is a bus. Default to all routers.
```
**Description**
Registers a timer.
Returns the allocated timer id or etl::timer::id::NO_TIMER if one was not available.
____________________________________________________________________________________________________
**Parameters**
`message` A reference to the message that will be sent when the timer expires.
`router` A reference to a router or bus that will receive to message.
`period` The timer period in ticks.
`repeating` `false` if single shot, `true` if repeating.
`destination_router_id` The id of the destination router. Only valid if the router is a bus. Default to all routers.
Returns the allocated timer id or `etl::timer::id::NO_TIMER` if one was not available.
```cpp
bool unregister_timer(etl::timer::id::type id)
Unregisters a timer.
If the timer is active then it will be stopped.
Returns true if a timer with the id was successfully unregistered.
____________________________________________________________________________________________________
```
**Description**
Unregisters a timer.
If the timer is active then it will be stopped.
Returns `true` if a timer with the id was successfully unregistered.
---
```cpp
void enable(bool state)
```
Enables or disables the timer manager according to the state.
____________________________________________________________________________________________________
---
```cpp
bool is_running() const
```
Returns true if the timer manager is enabled.
____________________________________________________________________________________________________
---
```cpp
void clear()
```
Clears the message timer back to the initial state. All timers will be stopped and unregistered.
____________________________________________________________________________________________________
---
```cpp
bool tick(uint32_t count)
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns true if the tick counter was updated, otherwise false. This may be used by the calling routine to accumulate unprocessed tick counts.
___________________________________________________________________________________________________
```
This function updates the internal tick counter (if enabled) and must be passed the number of ticks that have occurred since the last call. If the count encompasses more than one period of a repeating timer then the timer will be triggered multiple times in one call to tick.
Returns `true` if the tick counter was updated, otherwise `false`. This may be used by the calling routine to accumulate unprocessed tick counts.
---
```cpp
bool start(etl::timer::id::type id, bool immediate = false)
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is true then the timer is triggered on the next call to tick(). Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
Starts the timer with the specified id.
If the timer is already running then the timer Is restarted from the current tick count.
If immediate is `true` then the timer is triggered on the next call to `tick()`. Note: Single shot timers will only trigger once.
If the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool stop(etl::timer::id::type id)
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns false.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Does nothing if the timer is already stopped.
if the id does not correspond to a registered timer then returns `false`.
---
```cpp
bool set_period(etl::timer::id::type id_, uint32_t period)
Stops the timer with the specified id.
Sets a new timer period.
Returns true if successful.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Sets a new timer period.
Returns `true` if successful.
---
```cpp
bool set_mode(etl::timer::id::type id_, bool repeating)
Stops the timer with the specified id.
Sets a new timer mode.
Returns true if successful.
____________________________________________________________________________________________________
```
Stops the timer with the specified id.
Sets a new timer mode.
Returns `true` if successful.
---
```cpp
etl::timer::id::type time_to_next()
Returns the time to the next timeout.
20.38.0
____________________________________________________________________________________________________
Constants
```
Returns the time to the next timeout.
Since: `20.38.0`
### Constants
```cpp
MAX_TIMERS
____________________________________________________________________________________________________
message_timer
```
Template parameters
MAX_TIMERS The number of timers to be supported. The maximum number is 254.
A value of 255 will result in a compile error.
## message_timer
____________________________________________________________________________________________________
Example
**Template parameters**
`MAX_TIMERS` The number of timers to be supported. The maximum number is `254`.
A value of `255` will result in a compile error.
### Example
```cpp
//***************************************************************************
// The set of messages.
//***************************************************************************
@ -243,4 +301,4 @@ void timer_interrupt()
nticks += TICK;
}
}
```

View File

@ -1,6 +1,16 @@
Timer
---
title: "timer"
---
{{< callout type="info">}}
Header: `timer.h`
{{< /callout >}}
Contains definitions common to timers.
## timer
```cpp
struct timer
{
// Timer modes.
@ -47,44 +57,45 @@ struct timer
};
};
};
```
____________________________________________________________________________________________________
timer
mode
Types
type
The type for timer mode.
Defined as bool
### mode
**Types**
`type`
The type for timer mode.
Defined as `bool`.
Constants
SINGLE_SHOT
The timer expires once and then stops.
**Constants**
`SINGLE_SHOT`
The timer expires once and then stops.
REPEATING
The timer is restarted after every timeout.
`REPEATING`
The timer is restarted after every timeout.
start
Types
type
The type for timer start mode.
Defined as bool
### start
**Types**
`type`
The type for timer start mode.
Defined as `bool`.
Constants
IMMEDIATE
Single Shot
The timer is triggered on the next tick. The normal timeout does not occur.
Repeating
The timer is triggered on the next tick and then on subsequent timeouts.
DELAYED
**Constants**
`IMMEDIATE`
- *Single Shot*
The timer is triggered on the next tick. The normal timeout does not occur.
- *Repeating*
The timer is triggered on the next tick and then on subsequent timeouts.
`DELAYED`
The timer is triggered on the timeout.
id
Types
type
The type for timer identifiers.
Defined as uint_least8_t
### id
**Types**
`type`
The type for timer identifiers.
Defined as `uint_least8_t`.
Constants
NO_TIMER
**Constants**
`NO_TIMER`
The id of an unregistered timer.

View File

@ -1,45 +0,0 @@
---
title: "Generators"
---
Some templates within the ETL are designed to support a variable number of template parameters. To accommodate this, these template classes have a number of specialisations to handle each variant. The ETL sets this number to a reasonable default, but there will almost certainly be circumstances where these are too small for the project at hand.
To this end, the ETL supplies 'generators' to enable the creation of customised variants of these template classes.
The code generation is handled by a Python library called COG. This allows Python code to be embedded within the C++. When COG is run on the generator header, it will produce a customised version of that header.
The naming convention used is
The generator file: xxxx_generator.h
The output file: xxxx.h
The script: generate_xxxx.bat
The script generate.bat will run all of the generate scripts.
e.g.
Running the COG script on the generator type_traits_generator.h will create type_traits.h
The syntax for processing a generator file is
python -m cogapp -d -e -o<output> -D<parameter>=<N> <generator>
e.g.
python -m cogapp -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h
The line above will create type_traits.h with the ability to handle up to 16 types in the etl::is_one_of structure.
All of the generator files may be processed by running the script generate.bat
There are generator scripts for each generator header.
This can be run as a command line batch file under Windows or as a script under Linux (if set to 'executable')
Defined generators
Functionality Generator Output Parameters Notes
Finite State Machine fsm_generator.h fsm.h Handlers Defines the maximum number of events that can be handled
Message Router message_router_generator.h message_router.h Handlers Defines the maximum number of messages that can be handled
Smallest smallest_generator.h smallest.h NTypes Defines the maximum number of types that can be declared
Largest largest_generator.h largest.h
NTypes Defines the maximum number of types that can be declared
Type Traits type_traits_generator.h type_traits.h IsOneOf Defines the maximum number of types that can be declared in the class etl::is_one_of
Type Lookup type_lookup_generator.h type_lookup.h NTypes Defines the maximum number of types that can be declared in the classes etl::type_id_lookup and etl::type_type_lookup
Type Select type_select_generator.h type_select.h Defines the maximum number of types that can be declared in the class etl::type_select
Variant Pool variant_pool_generator.h variant_pool.h NTypes Defines the maximum number of types that can be declared

View File

@ -3,4 +3,62 @@ title: "Tutorials"
weight: 2001
---
I've created a set of tutorials to help you get to know the library better.
If there is an aspect of the library that you find difficult to use or understand then let me know and I'll try to put together some examples of how to use it, and even why you should use it.
---
[Containers](./containers-tutorial)
A quick introduction to containers.
---
[observer](./observer-tutorial)
A templated set of classes to allow easier implementation of the observer pattern.
---
[visitor](./visitor-tutorial)
A templated set of classes to allow easier implementation of the visitor pattern.
---
[Messages](./message-tutorial)
The messaging framework.
---
[Generators](./generators-tutorial)
Generators create parts of the ETL code based on user requirements.
---
**Concurrent Queues**
A set of concurrent queues, both Single Producer / Single Consumer (SPSC) and Muli Producer / Multi Consumer (MPMC)
---
**callback_service**
This code demonstrates using the callback service for five example ARM interrupts.
---
**delegate_service**
This code demonstrates using the delegate service for five example ARM interrupts.
---
**shared_message**
How to use shared messages with the ETL messaging framework.
---
**Locked Queues**
How the locked queues differ from each other.
---
**etl::unique_ptr with etl::pool**
Using an etl::unique_ptr with `etl::pool`
---

View File

@ -1,18 +1,27 @@
callback_service
---
title: "callback_service"
---
The following code can be found in examples\FunctionInterruptSimulation
{{< callout type="warning">}}
**Deprecated**.
This documentation is for reference only.
Use `etl::delegate_service` for new code.
{{< /callout >}}
This code demonstrates using the callback service for five example ARM interrupts.
The following code can be found in `examples\FunctionInterruptSimulation`.
Timer1 interrupt is handled by an instance of class Timer. The member callback function is wrapped by the most efficient version of etl::function which all of the information it needs at compile time.
This code demonstrates using the callback service for five example ARM interrupts.
Timer2 interrupt is handled by a global function.
`Timer1` interrupt is handled by an instance of class `Timer`. The member callback function is wrapped by the most efficient version of `etl::function` which all of the information it needs at compile time.
Timer3 has no entry in the callback service and will therefore trigger execution of the unhandled handler.
`Timer2` interrupt is handled by a global function.
USART1 and USART2 interrupts are handled by instances of Uart.
`Timer3` has no entry in the callback service and will therefore trigger execution of the unhandled handler.
`USART1` and `USART2` interrupts are handled by instances of Uart.
There callbacks are defined withing the class and are initialised in the Uart constructor.
```cpp
#include <iostream>
#include "etl/function.h"
@ -165,12 +174,15 @@ int main()
return 0;
}
```
____________________________________________________________________________________________________
Output
---
**Output**
```
Timer interrupt (member) : ID 42
Timer interrupt (free) : ID 43
UART0 : ID 52
UART1 : ID 53
Unhandled Interrupt : ID 44
```

View File

@ -1,25 +1,27 @@
Concurrent Queues
The ETL defines a selection of concurrent queue types to be used in interrupt driven or multi-threaded applications.
The queues may be either Single Producer / Single Consumer (SPSC) or Multi Producer / Multi Consumer (MPMC)
---
title: "Concurrent Queues"
---
The queues use different methods to protect access to the queue. You must select one that matches your platform and requirements.
The ETL defines a selection of concurrent queue types to be used in interrupt driven or multi-threaded applications.
The queues may be either Single Producer / Single Consumer (SPSC) or Multi Producer / Multi Consumer (MPMC)
The queues have a slightly different API from the standard etl::queue. The push and pop member functions return a boolean flag to indicate if the required operation was successful. This allows the calling function to either defer a retry to a later time, or block until successful.
The queues use different methods to protect access to the queue. You must select one that matches your platform and requirements.
There are currently three concurrent queues defined.
The queues have a slightly different API from the standard `etl::queue`. The `push` and `pop` member functions return a boolean flag to indicate if the required operation was successful. This allows the calling function to either defer a retry to a later time, or block until successful.
queue_spsc_isr
queue_spsc_isr
This queue is designed to be used in an interrupt driven context, where one end of the queue is driven from an interrupt and the other from the main application loop. The direction of the queue to/from the interrupt is not important, but only one end must be interrupt driven.
There are currently three concurrent queues defined.
The queue expects a type to be supplied that defines static void lock() and void unlock() functions. These must disable and re-enable the relevant interrupt. They must also affect a memory barrier to ensure that the calls are not re-sequenced by the compiler or processor.
## queue_spsc_isr
`queue_spsc_isr`
queue_spsc_atomic
queue_spsc_atomic
This queue uses atomic integral counters internally to enable a lock-free queue to be defined. The ability to use this queue is dependent on whether your compiler supports atomic operations. If your compiler supports C++11 or above or you are using GCC with support for __sync built-ins then the answer is yes.
This queue is designed to be used in an interrupt driven context, where one end of the queue is driven from an interrupt and the other from the main application loop. The direction of the queue to/from the interrupt is not important, but only one end must be interrupt driven.
queue_mpmc_mutex
queue_mpmc_mutex
This queue uses a user supplied mutex type to enable access. By using a mutex the queue may be multi producer / multi consumer. Users of C++11 or above may use std::mutex.
The queue expects a type to be supplied that defines static void lock() and void unlock() functions. These must disable and re-enable the relevant interrupt. They must also affect a memory barrier to ensure that the calls are not re-sequenced by the compiler or processor.
## queue_spsc_atomic
`queue_spsc_atomic`
This queue uses atomic integral counters internally to enable a lock-free queue to be defined. The ability to use this queue is dependent on whether your compiler supports atomic operations. If your compiler supports C++11 or above or you are using GCC with support for `__sync` built-ins then the answer is yes.
## queue_mpmc_mutex
`queue_mpmc_mutex`
This queue uses a user supplied mutex type to enable access. By using a mutex the queue may be multi producer / multi consumer. Users of C++11 or above may use `std::mutex`.

View File

@ -1,18 +1,21 @@
elegate_service
---
title: "delegate_service"
---
The following code can be found in examples\FunctionInterruptSimulation-Delegates
The following code can be found in `examples\FunctionInterruptSimulation-Delegates`
This code demonstrates using the delegate service for five example ARM interrupts.
This code demonstrates using the delegate service for five example ARM interrupts.
Timer1 interrupt is handled by an instance of class Timer. The member callback function is wrapped by the most efficient version of etl::delegate in which all of the information it requires is known at compile time.
`Timer1` interrupt is handled by an instance of class `Timer`. The member callback function is wrapped by the most efficient version of `etl::delegate` in which all of the information it requires is known at compile time.
Timer2 interrupt is handled by a global function.
`Timer2` interrupt is handled by a global function.
Timer3 has no entry in the callback service and will therefore trigger execution of the unhandled handler.
`Timer3` has no entry in the callback service and will therefore trigger execution of the unhandled handler.
USART1 and USART2 interrupts are handled by instances of Uart.
There callbacks are defined withing the class and are initialised in the Uart constructor.
`USART1` and `USART2` interrupts are handled by instances of `Uart`.
There callbacks are defined withing the class and are initialised in the `Uart` constructor.
```cpp
#include <iostream>
#include "etl/delegate.h"
@ -166,12 +169,15 @@ int main()
return 0;
}
```
__________________________________________________________________________________________________
Output
---
**Output**
```
Timer interrupt (member) : ID 42
Timer interrupt (free) : ID 43
UART0 : ID 52
UART1 : ID 53
Unhandled Interrupt : ID 44
```

View File

@ -0,0 +1,44 @@
00---
title: "Generators"
---
Some templates within the ETL are designed to support a variable number of template parameters. To accommodate this, these template classes have a number of specialisations to handle each variant. The ETL sets this number to a reasonable default, but there will almost certainly be circumstances where these are too small for the project at hand.
To this end, the ETL supplies 'generators' to enable the creation of customised variants of these template classes.
The code generation is handled by a Python library called `COG`. This allows Python code to be embedded within the C++. When `COG` is run on the generator header, it will produce a customised version of that header.
The naming convention used is
The generator file: `xxxx_generator.h`
The output file: `xxxx.h`
The script: `generate_xxxx.bat`
The script `generate.bat` will run all of the generate scripts.
e.g.
Running the `COG` script on the generator `type_traits_generator.h` will create `type_traits.h`
The syntax for processing a generator file is
`python -m cogapp -d -e -o<output> -D<parameter>=<N> <generator>`
e.g.
`python -m cogapp -d -e -otype_traits.h -DIsOneOf=16 type_traits_generator.h`
The line above will create type_traits.h with the ability to handle up to 16 types in the `etl::is_one_of` structure.
All of the generator files may be processed by running the script `generate.bat`
There are generator scripts for each generator header.
This can be run as a command line batch file under Windows or as a script under Linux (if set to 'executable')
**Defined generators**
| Functionality | Generator | Output | Parameters | Notes |
| -------------------- | ---------------------------- | ------------------ | ---------- | ----- |
| Finite State Machine | `fsm_generator.h` | `fsm.h` | Handlers | Defines the maximum number of events that can be handled |
| Message Router | `message_router_generator.h` | `message_router.h` | Handlers | Defines the maximum number of messages that can be handled |
| Smallest | `smallest_generator.h` | `smallest.h` | NTypes | Defines the maximum number of types that can be declared |
| Largest | `largest_generator.h` | `largest.h` | NTypes | Defines the maximum number of types that can be declared |
| Type Traits | `type_traits_generator.h` | `type_traits.h` | NTypes | Defines the maximum number of types that can be declared in the class `etl::is_one_of` |
| Type Lookup | `type_lookup_generator.h` | `type_lookup.h` | NTypes | Defines the maximum number of types that can be declared in the classes `etl::type_id_lookup` and `etl::type_type_lookup` |
| Type Select | `type_select_generator.h` | `type_select.h` | NTypes | Defines the maximum number of types that can be declared in the class `etl::type_select` |
| Variant Pool | `variant_pool_generator.h` | `variant_pool.h` | NTypes | Defines the maximum number of types that can be declared |

View File

@ -1,22 +1,29 @@
Locked Queues
---
title: "Locked Queues"
---
There are several lockable queues in the ETL.
There are several lockable queues in the ETL.
Each offers a different method of locking and unlocking a queue for modification.
____________________________________________________________________________________________________
queue_spsc_isr
## queue_spsc_isr
```cpp
template <typename T, size_t SIZE, typename TAccess>
class queue_spsc_isr
```
This queue was originally designed for use with an Interrupt Service Routine (ISR), where functionality would be provided to it to enable and disable interrupts. This is achieved in this queue by supplying a template parameter type that implements two static functions;
This queue was originally designed for use with an Interrupt Service Routine (ISR), where functionality would be provided to it to enable and disable interrupts. This is achieved in this queue by supplying a template parameter type that implements two static functions;
```cpp
lock()
unlock()
```
The first disables the relevant interrupts and the second enables them.
The queue, of course, is not limited to just interrupts.
____________________________________________________________________________________________________
Example
**Example**
```cpp
struct InterruptControl
{
static void lock()
@ -31,15 +38,19 @@ struct InterruptControl
};
etl::queue_spsc_isr<char, 100, InterruptControl> charQueue;
____________________________________________________________________________________________________
queue_spsc_locked
```
## queue_spsc_locked
```cpp
template <typename T, size_t SIZE>
class queue_spsc_locked
```
This queue is similar to the above, but the access control functions are supplied at run time as references to etl::ifunction.
____________________________________________________________________________________________________
Example
This queue is similar to the above, but the access control functions are supplied at run time as references to `etl::ifunction`.
**Example**
```cpp
void QueueLock()
{
OsDisableInterrupts();
@ -54,15 +65,19 @@ etl::function_fv<QueueLock> queueLock;
etl::function_fv<QueueUnlock> queueUnlock;
etl::queue_spsc_isr<char, 100> charQueue(queueLock, queueUnlock);
____________________________________________________________________________________________________
queue_lockable
```
## queue_lockable
```cpp
template <typename T, size_t SIZE>
class queue_lockable
```
This queue provides access to locking by providing two pure virtual functions, lock() and unlock() that the user of the queue must supply implementations for.
____________________________________________________________________________________________________
Example
This queue provides access to locking by providing two pure virtual functions, `lock()` and `unlock()` that the user of the queue must supply implementations for.
**Example**
```cpp
class QueueInt : public etl::queue_lockable<int, 4>
{
public:
@ -81,4 +96,4 @@ public:
OsEnableInterrupts();
}
};
```

View File

@ -12,7 +12,8 @@ html:not(.dark) .highlight .chroma .cpf {
html:not(.dark) h1 {
color: white !important;
width: 100%;
background-color: royalblue !important;
background-color: coral !important;
border: width 0.15rem solid rgb(163, 81, 51) !important;
padding: 0.5rem 0.5rem !important;
}
@ -119,8 +120,7 @@ html.dark h1
{
color: white !important;
width: 100%;
#background-color: rgb(50, 50, 50) !important;
background-color: #7099c7 !important;
background-color: rgb(177, 87, 54) !important;
padding: 0.5rem 0.5rem !important;
}
@ -283,7 +283,7 @@ html.dark .hextra-code-block .highlight .chroma .cpf {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-size: 110% !important;
font-size: 1.1rem !important;
}
.err {
@ -295,7 +295,7 @@ h1 {
font-family: Roboto, sans-serif !important;
font-style: i !important;
font-weight: 500 !important;
font-size: 180% !important;
font-size: 1.9rem !important;
margin-top: 0.5em !important;
margin-bottom: 0.0em !important;
border-radius: 0.5rem !important;
@ -305,7 +305,7 @@ h2 {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-size: 150% !important;
font-size: 1.5rem !important;
margin-top: 1.0em !important;
margin-bottom: 0.5em !important;
}
@ -314,18 +314,18 @@ h3 {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-size: 120% !important;
font-size: 1.2rem !important;
margin-top: 0.7em !important;
margin-bottom: 0em !important;
padding: 0 !important;
display: inline-block;
#display: inline-block;
}
h4 {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-size: 110% !important;
font-size: 1.1rem !important;
margin-top: 0.5em !important;
margin-bottom: 0.5em !important;
display: inline-block;
@ -411,7 +411,7 @@ p {
font-family: Roboto, sans-serif !important;
font-style: normal !important;
font-weight: normal !important;
font-size: 110% !important;
font-size: 1.1rem !important;
margin-top: 0.5em !important;
}