API Overview
API Overview
In this documentation, you will find the API structure, the description of the libraries used.
Structure
The firmware is divided into three applications: bootloader, Application A, and Application B. Each of them is built separately and, in the end, merged into a final image. This means that each of them uses both their own separate source files and shared ones. One good approach is to keep the source code structure the same as in our demonstration application. In this case, the structure is:
├── app_a
│ ├── BUILD
│ ├── build.sh
│ ├── mbed_app.json
│ ├── mbed-os
│ └── mbed-os.lib
├── app_b
│ ├── BUILD
│ ├── build.sh
│ ├── mbed_app.json
│ ├── mbed-os
│ └── mbed-os.lib
├── app_src
│ ├── drivers
│ ├── main.cpp
│ └── sensors
├── app_src_backup
│ ├── drivers
│ ├── main.cpp
│ └── sensors
├── bin
│ ├── app_a.bin
│ ├── app_b.bin
│ └── image.bin
├── build_app.sh
├── build_image.sh
├── CHANGELOG.md
├── clean.sh
├── common
│ └── global_consts.h
├── docker_build_image.sh
├── docker_build_windows.bat
├── docker_flash_image.sh
├── flash_image.sh
├── libs
│ └── vitroio-sdk
├── README.md
└── shard-v2-bootloader-image
├── bootloader.bin
└── README.md
Each subdirectory is organized as follows:
app_a
- Application A files only.
- To build the
app_a
binary, there is abuild.sh
script.
There are no source code files in this particular example, but only those used by Mbed OS to build.
app_b
- Application B files only.
- To build the
app_b
binary, there is abuild.sh
script.
There are no source code files in this particular example, but only those used by Mbed OS to build.
app_src
- Applications A and B common source files.
- At a minimum, a
main.cpp
file must be present. - Application's sensors source code should be saved on
drivers
andsensors
folders.
In this particular example, applications A and B are the same. As such, their source code is in this directory. Furthermore,
drivers
andsensors
folders have the source code for temperature and humidity DHT22, light LM393, and current meter MCT-0016.
-
app_src_backup
- If it doesn't exist, the
build_app.sh
script will create it. - When building the firmware,
build_app.sh
script creates a backup of theapp_src
directory.
- If it doesn't exist, the
-
bin
- Contains final binaries only.
- if it doesn't exist, it is created by
build_image.sh
script during the build process.
-
shard-v2-bootloader-image
- Contains the bootloader binary file (git submodule).
-
common
- Contains source files related to bootloader, and Applications A and B.
- At least
global_consts.h
file should be placed in this folder;
-
libs
- Contains necessary, external libraries packed into vitroio-sdk.
Details can be found in section Libraries of this documentation.
Scripts
- build_app.sh: Check for dependencies, backup
app-src
, and then calldocker_build_image.sh
. - docker_build_image.sh: Creates a docker container with vitrotech/docker-mbed-cli image, then call
build_image.sh
script. -
- build_image.sh: Create
bin
folder if it doesn't exist, configure the secure boot, and run thebuild.sh
script on each application directory.
- build_image.sh: Create
-
- build.sh: Install Mbed OS and compile the application on its directory.
- docker_flash_image.sh: Create a docker container with the required privileges and vitrotech/docker-mbec-sli image. After creating the container, it calls the
flash_image.sh
script. - flash_image.sh: Erases the device's firmware and then writes the new one starting at 0x8000000 memory address.
The 0x8000000 address comes from the memory mapping for the MCU. You can check it here, on Fig. 14.
- clean.sh: Delete the created build folders, bin folder, and files.
Libraries
The firmware requires external libraries. For convenience, they are all included in one package - vitroio-sdk. Vitro Shard needs some of them even to run a basic firmware. Others extend the list of features that can be implemented.
libvitro-shard-sdk1.5.2.a
- Library given in already pre-compiled binary form along with dedicated API in header files (git submodule).
- Core library for every Vitro Shard application. Thus, it must be included in all projects.
- It handles all low-level operations such as operating system initialization, upgrades process, task management, event handling, communication handling, and reliable measurements.
ecc-api
- Open-source library.
- It allows to communicate with Vitro Shard's ATECC608A to perform cryptographic operations, such as reading symmetric key, and computing SHA256 or ECDSA.
mbed-cryptoauthlib
- Mbed OS library which allows interaction with cryptographic elements via an I2C interface.
- It is an intermediate layer between
ecc-api
and the physical ATECC608A chip.
shard-edge-lib
- Library given in open source form.
- It allows to configure Vitro Shard Edge by enabling and disabling dedicated peripherals e.g. SPI or UART.
- It allows to configure ADCs and current loops ranges.
tls-api
- Library given in open source form.
- It allows performing AES encryption and decryption on given data. Those operations are performed directly by MCU.
- The symmetric key is kept on the ECC module and read whenever it must be used.
For more documentation, you can check the Mbed documentation and an example.
By using all the libraries mentioned, Vitro Shard can create IoT Blocks for any custom data measurement application. One benefit of using those libraries is many are open-source. This means that they can be modified, extended, and checked for vulnerabilities by anyone.
API Headers
Common
Located in vitroio-sdk/vitroio-sdk
.
- const.h: Defines required flash memory size in bytes for storing environment variables and Vitro Shard pinout.
- debug.h: Defines debug macros. There are four debug levels (from highest to lowest): HINFO, INFO, WARNING, ERROR. When some level is defined, the defined one and all of the lower levels are enabled.
- errors.h: Defines error codes. The errors are:
Error Code | Description |
---|---|
VITROIO_ERR_SET_CALLBACK | Callback error |
VITROIO_ERR_MEMORY_ALLOC | Memory allocation error |
VITROIO_ERR_INVALID_PARAMS | Invalid parameter error |
VITROIO_ERR_BUS_WRITE | Bus write error |
VITROIO_ERR_BUS_READ | Bus read error |
VITROIO_ERR_BUS_SET_FRAME_LENGTH | Bus error |
VITROIO_ERR_FLASH_INIT | Flash error |
VITROIO_ERR_FLASH_WRITE | Flasherror |
VITROIO_ERR_FLASH_READ | Flash error |
VITROIO_ERR_FLASH_ERASE | Flash error |
- types.h: Defines the variable types used to identify the firmware, version, and flash space parameters.
watchdog
Located in vitroio-sdk/vitroio-sdk/watchdog
.
- watchdog.h: Defines the watchdog class.
shard-edge-lib
Located in vitroio-sdk/vitroio-sdk/shard-edge-lib
.
- shard_edge.h: Provides an interface for Vitro Shard Edge.
measurement-api
Located in vitroio-sdk/vitroio-sdk/measurement-api
.
- abstract_sensor_driver.h: Virtual class that provides an interface for basic communication with the sensor and optionally performs sensor-specific operations.
- abstract_sensor_interface.h: Defines sensor parameters and an uniform reading measurement interface for all sensors.
- measurement_api.h: Uses event queue to cycle through each sensor and reads its measurements.
iot-block
Located in vitroio-sdk/vitroio-sdk/iot-block-api
.
- iot-block.h: Defines the parameters and interface to create and send IoT Blocks. The parameters define the size of the ciphertext, initialization vector, parameter ID (defined in
abstract_sensor_interface.h
), node ID, timestamp, digest, and signature.
control
Located in vitroio-sdk/vitroio-sdk/control
.
- node_controller.h: Defines the Vitro Shard's main component. It handles standard operations, like firmware updates and initialization of communication with the gateway. This is all done through the use of event queues.
communication
Located in vitroio-sdk/vitroio-sdk/communication
.
- canbus_frame.h: A wrapper for Mbed CANMessage. The modifications are done to allow the interface to support frames used by our API.
- canbus.h: Defines the default CAN communication frequency, and it is a wrapper for Mbed CAN, thus providing an interface for canbus_frame.h.
- transport_layer.h: Defines a basic communication interface to send IoT Blocks with other devices.
- can_layer.h: Defines an implementation of the
transport_layer.h
for the CAN interface.
Vitro Shard Upgrade
This section is explained in the Starter Guide documentation.
The IoT Block
An IoT Block is a special data structure created by Nodes when meaningful information needs to be sent to the Vitro Cloud (sensor's data, device HeartBeat, etc.).
Each IoT Block is created as a result of performing strictly defined steps in a strictly defined sequence. It consists of the Initialize Vector, encrypted data (usually the sensor's measurement), parameter ID (the sensor's ID defined in sensor_parameter.h
), Node ID, timestamp, digest, and signature. The digest is a result of SHA-256 hash function on the Initialize Vector + encrypted data + parameter ID + node ID + timestamp. Then, the digest is signed using ECDSA. Thus, creating the signature.
You can read more about it in the SDK documentation.
At the end of the creation process, CAN overhead is added at the end of the IoT Block. This IoT Block + CAN overhead is called Binary Large Object (BLOB). Both the IoT Block and BLOB must comply with the layout and sizes as follows:
IoT and BLOB size calculator table:
Size | S | M | L | XL | Absolute maximum | |
---|---|---|---|---|---|---|
Actual IoT Block | Payload size [bytes] | 32 | 144 | 528 | 1040 | 1638 |
Actual IoT Block | Node ID | 9 | 9 | 9 | 9 | 9 |
Actual IoT Block | Timestamp | 4 | 4 | 4 | 4 | 4 |
Actual IoT Block | IV and encrypted data | 48 | 160 | 544 | 1056 | 1664 |
Actual IoT Block | SHA256 | 32 | 32 | 32 | 32 | 32 |
Actual IoT Block | ECDSA | 64 | 64 | 64 | 64 | 64 |
Actual IoT Block | Actual size | 157 | 269 | 653 | 1165 | 1773 |
CAN related | Padding | 4 | 4 | 5 | 4 | 5 |
CAN related | Size with padding | 161 | 273 | 658 | 1169 | 1778 |
CAN related | CAN frames count | 24 | 40 | 95 | 168 | 255 |
Updated almost 3 years ago