Skip to content

Commit e3c1106

Browse files
author
Avi SZYCHTER
committed
Improved README section on the API
1 parent c3ae285 commit e3c1106

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

README.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,102 @@ This project provides a C++ library that reads and parses [CAN](https://en.wikip
44

55
Currently the library only understand a subset of the DBC file format.
66

7+
## Parsing a CAN database
8+
9+
The main feature of the library is the possibility of parsing a file representing the CAN database. There are several popular file formats and the list of the currently ones is available at the end of this README.
10+
11+
`CANDatabase::fromFile("path/to/the/data.dbc")` is the function to call in order to parse the database from a file. See the following example for a more "advanced" use:
12+
13+
```c++
14+
#include <iostream>
15+
#include "CANDatabase.h"
16+
17+
int main(int argc, char** argv) {
18+
try {
19+
CANDatabase db = CANDatabase::fromFile(argv[1]);
20+
21+
// ...
22+
}
23+
catch(const CANDatabaseException& e) {
24+
std::cerr << "Error: " << e.what();
25+
return 1;
26+
}
27+
28+
return 0;
29+
}
30+
```
31+
32+
One can see that `CANDatabase::fromFile()` can throw a CANDatabaseException. This happens when the parsing goes wrong (basically when the given file does not exist or when there is a syntax error). `CANDatabaseException::what()` will give you details on the error.
33+
34+
If the data that you are using does not come from a file, it is also possible to use `CANDatabase::fromString("...")` which behaves just like its counterpart.
35+
36+
37+
## The API
38+
39+
The library exposes three main kind of objects:
40+
* `CANDatabase` : represents the whole database. It gatherse all the informations of the database such as the frames and their signals, but you can also find the filename from which the database was created (if applicable).
41+
* `CANFrame`: represents a single frame: we know its CAN ID, the DLC (Data length code), its period (in ms) and also its name (if any). Of course, a `CANFrame` also gathers the list of signals that can be read in a frame
42+
* `CANSignal`: represents a single signal: a signal is a parameter of a frame characterized by different properties. It is mostly identificable through its start bit, length and [endianness](https://en.wikipedia.org/wiki/Endianness) (those three parameters are enough to extract the "raw data" that the signals represent) but one usually also specify a scale and offset factor, a signedness, and a name. More parameters are available and you are welcome to look into the `CANSignal.h` file to look at all the available properties.
43+
44+
All those classes try to behave the closest possible to STL containers. They notably implement all the required iterators methods so **they can be used in range-based for loops**
45+
46+
### `CANSignal`
47+
48+
Here are the most important properties of a `CANSignal` instance:
49+
50+
* `name()`: gives the name of the signal
51+
* `length()` : gives the length of the signal
52+
* `start_bit()` : gives the start bit of the signal
53+
* `scale()` : gives the scale factor of the signal
54+
* `offset()` : gives the offset factor of the signal
55+
* `signedness()` : gives the signedness of the signal
56+
* `endianness()` : gives the endianness of the signal
57+
* `range()` : gives the range of the signal (which has a `min` and `max` property)
58+
* `comment()` : gives the registered comment (if any)
59+
60+
Sometimes the database also includes "enumerations", ie for given signals we associate string literals to values (example: 0 = Nothing, 1 = State 1, 2 = State 2). `choices()` allows to iterate through the signal's enumeration (if any).
61+
62+
### `CANFrame`
63+
64+
Here are the most important properties of a `CANFrame` instance:
65+
66+
* `name()`: gives the name of the signal
67+
* `can_id()`: gives the CAN ID of the signal
68+
* `dlc()`: gives the DLC of the signal
69+
* `period()`: gives the period of the signal
70+
* `comment()` : gives the registered comment (if any)
71+
* more properties to behave like a "standard container"
72+
73+
Use `begin()`/`end()` and!/or a ranged-based for loop to iterate through the signals of the frame.
74+
75+
```c++
76+
const CANFrame& frame = ...;
77+
78+
// Print the name of all the frames by increasing order
79+
for(const auto& sig : frame) {
80+
std::cout << "Signal: " << sig.second.name() << std::endl;
81+
}
82+
```
83+
84+
### `CANDatabase`
85+
86+
Here are the most important properties of a `CANDatabase` instance:
87+
88+
* `filename()` : gives the source file name (if any)
89+
* `operator[std::string]` and `at(std::string)` : returns a reference to the `CANFrame` associated with the given frame name. The deviation from the STL behavior is that they both throw an `std::out_of_range` exception if the key does not exist (no `CANFrame` is created like it would with `std::map` for instance)
90+
* `operator[unsigned long long]` and `at(unsigned long long)`: same but the key is the CAN ID of the `CANFrame`
91+
* more properties to behave like a "standard container"
92+
93+
```c++
94+
CANDatabase db = ...;
95+
96+
// Print the name of all the frames by increasing order
97+
size_t i = 0;
98+
for(const auto& frame : db) {
99+
std::cout << "Frame " << i++ << ": " << frame.second.name() << std::endl;
100+
}
101+
```
102+
7103
## Compiling the project
8104

9105
The project uses CMake to be compiled. It can also be used to easily include the library in your own project.

0 commit comments

Comments
 (0)