Skip to content

Commit d534f16

Browse files
authored
add beginning of the user guide (#40)
1 parent 1018429 commit d534f16

File tree

3 files changed

+146
-1
lines changed

3 files changed

+146
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ int main() {
7878
A larger and more illustrative example can be found in this repo at
7979
[examples/hello_world](examples/hello_world).
8080
81+
For more details on how to use *cib*, see the [User Guide](USER_GUIDE.md).
82+
8183
### Building
8284
8385
*cib* is built with CMake. The single header is built with the

USER_GUIDE.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# *cib* User Guide
2+
3+
## Overview
4+
5+
*cib* allows for firmware to be efficiently composed of self-contained
6+
*components*. A *component* is composed of zero or more *features* and
7+
*services*.
8+
9+
> *cib* introduces new terminology with concrete definitions. Whenever a *cib*
10+
concept is written, it will be *italic*. Whenever a C++ type or function is
11+
written, it will be formatted as `code`.
12+
13+
### Services
14+
15+
> A *service* is something that can be *extended* with new functionality.
16+
17+
For example, a serial port that can receive messages has a driver for
18+
interfacing with the hardware. When data is received over the serial port, the
19+
driver needs to direct the data to the appropriate *feature*. How does the
20+
driver know what *features* to send the data to?
21+
22+
If the serial port driver is implemented as a *service* with *cib*, then
23+
*features* will `extend` the serial port *service* with their own
24+
functionality.
25+
26+
```c++
27+
/// Invoked for each byte of data received on the serial port
28+
struct serial_port_rx : public cib::callback_meta<0, std::uint8_t>{};
29+
```
30+
31+
In *cib*, *features* have source-code dependencies on *services*. This follows
32+
the [Dependency Inversion Principle](https://en.wikipedia.org/wiki/Dependency_inversion_principle):
33+
34+
1. High-level modules should not import anything from low-level modules. Both
35+
should depend on abstractions (e.g., interfaces).
36+
2. Abstractions should not depend on details. Details (concrete implementations)
37+
should depend on abstractions.
38+
39+
*Features* maybe change from one project to the next. The selection of which
40+
*features* are in a project will change as well. They have the most change and
41+
are the least stable.
42+
43+
*Services* on the other hand are stable. They provide generic functionality
44+
that can be reused over and over again.
45+
46+
During firmware startup, there will be hardware registers that need to be
47+
initialized before they can be used. The `runtime_init` and `main_loop`
48+
*services* are generic enough to be used in many types of firmware applications.
49+
50+
```c++
51+
/// Invoked once on startup before interrupts are enabled
52+
struct runtime_init : public cib::callback_meta<>{};
53+
54+
/// Invoked each iteration through the main loop
55+
struct main_loop : public cib::callback_meta<>{};
56+
```
57+
58+
*Components* use `cib::exports` in their configuration to *export* services to
59+
features. All *services* must be exported for them to be extended.
60+
61+
```c++
62+
struct board_component {
63+
constexpr static auto config =
64+
cib::exports<serial_port_rx, runtime_init, main_loop>;
65+
};
66+
```
67+
68+
### Features
69+
70+
> *Features* are the code that performs the work we are actually interested in.
71+
72+
In application development this would be called the "business logic." In
73+
systems programming this is the code that gets the job done.
74+
75+
With *cib*, *features* `extend` services with their functionality.
76+
77+
```c++
78+
/// Echo serial port rx data back to tx
79+
struct echo_component {
80+
constexpr static auto echo_feature =
81+
[](std::uint8_t data){
82+
serial_port.transmit(data);
83+
};
84+
85+
constexpr static auto config =
86+
cib::extend<serial_port_rx>(echo_feature);
87+
};
88+
```
89+
90+
### Project
91+
92+
> A project is a collection of *components*.
93+
94+
It is the embedded application that is being developed. The implementation of
95+
the application is entirely contained within the components it comprises.
96+
97+
Only a small amount of startup and glue-code is necessary outside *cib*
98+
*components*.
99+
100+
### Nexus
101+
102+
> The `cib::nexus` combines all the *services* and *features* within a project.
103+
It performs the compile-time initialization and build process across all
104+
components.
105+
106+
The [definition](https://www.google.com/search?q=define+nexus) of *nexus* fits `cib::nexus` well:
107+
108+
1. a connection or series of connections linking two or more things.
109+
110+
"the nexus between industry and political power“
111+
112+
2. connected group or series.
113+
114+
"a nexus of ideas“
115+
116+
3. the central and most important point or place.
117+
118+
"the nexus of all this activity was the disco"
119+
120+
The `cib::nexus` implements the heart of *cib*. Once a *cib* configuration has
121+
been created, using the `cib::nexus` is easy:
122+
123+
```c++
124+
cib::nexus<hello_world> nexus{};
125+
126+
int main() {
127+
nexus.init();
128+
nexus.service<runtime_init>();
129+
130+
while (true) {
131+
nexus.service<main_loop>();
132+
}
133+
}
134+
```
135+
136+
Services can be accessed with the `service<...>` template variable on a
137+
`cib::nexus` instance. Because the `runtime_init` and `main_loop` services
138+
extend `cib::callback_meta`, their *service implementation* is a simple
139+
function pointer.

examples/hello_world/README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,8 @@ So long and thanks for all the fish.
133133
Don't Panic.
134134
The quick brown fox jumps over the lazy dog.
135135
Hello, world!
136-
```
136+
```
137+
138+
### User guide
139+
140+
For more details on how to use *cib*, see the [User Guide](../../USER_GUIDE.md).

0 commit comments

Comments
 (0)