This library is a C implementation of the Astronode serial commands protocol.
Table of contents generated with markdown-toc
The astronode library allows the asset application to communicate with the astronode.
It contains all Astronode commands and performs the serialization/deserialization, encoding/decoding, crc check.
The device interface allows the library to be platform independent.
asset───────────────────────────────────────────┐
│ │
│ ┌─────────────────┐ │
│ │asset_application│ │
│ └─────┐▲──────┐▲──┘ │
│ ││ ││ │
│ astronode_lib───────┼┼──────┼┼──────────────┐ │
│ │ ││ ││ │ │
│ │ ┌────────────────▼└───┐ ││ │ │
│ │ │astronode_application│ ││ │ │
│ │ └──────────────┐▲─────┘ ││ │ │
│ │ ││ ││ │ │
│ │ ││ ││ │ │
│ │ ┌─────────────▼└────┐ ┌─▼└───────────┐ │ │
│ │ │astronode_transport│ │astronode_gpio│ │ │
│ │ └─────────────▲┌────┘ └─▲┌───────────┘ │ │
│ │ ││ ││ │ │
│ └─────────────────┼┼────────┼┼──────────────┘ │
│ ││ ││ │
│ ┌──┘▼────────┘▼──┐ │
│ │device_interface│ │
│ └───────┐▲───────┘ │
│ ││ │
│ ┌────────▼└───────┐ │
│ │ hardware │ │
│ └────────┐▲───────┘ │
│ ││ │
└────────────────────────┼┼─────────────────────┘
││
┌─────▼└───────┐
│ astronode │
└──────────────┘
├── example //
│ ├── application // application example
│ └── device_interface //
├── src // c library
└── test //
├── external // test framework (modified unity and fff)
└── test // test files
Files | Content |
---|---|
astronode_application | Serialize and deserialize astronode commands. online doc. |
astronode_transport | Encode and decode serialized commands. online doc. |
astronode_gpio | Access and control the device gpio. |
astronode_definitions | Contains opcodes and structures. |
The library is designed to handle synchronous (blocking) and asynchronous (by interrupt) serial communication. In synchronous mode, the asset is blocking (active wait) until the Astonode answers.
In asynchronous mode, the answer is stored by interrupt and the program should poll the function astronode_poll_answer_xxx to get the answer.
Enabling/disabling modes is done in astronode_definitions.h:
ASTRONODE_TRANSPORT_BLOCKING_MODE
ASTRONODE_TRANSPORT_ASYNC_MODE
In order to interface with the hardware, the library will call generic functions located in device_interface file. All device interface function should be mapped to the corresponding HAL functions of the specific platform.
Example, the wake-up pin for the board B-U5851-IOT02A from ST.
void di_gpio_astronode_write_wake_up_pin(bool state)
{
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_13, state);
}
To communicate, the asset sends a command, then waits for the Astronode answer.
Each command has one synchronous function (which send the command and wait for the answer):
as_return_status_t astronode_request_command_name(command_name_response_t)
And two asynchronous functions (one which send the command, the other to poll the answer):
as_return_status_t astronode_send_async_command_name()
as_return_status_t astronode_poll_answer_command_name(command_name_response_t)
The return value as_return_status_t indicates the status of the communication.
typedef enum as_return_status_t
{
RS_ASSET_SUCCESS = 0U, /*!< Operation succeed */
RS_ASSET_CRC_ERROR, /*!< CRC error on Astronode answer */
RS_ASSET_BUSY, /*!< Waiting for Astronode answer */
RS_ASSET_TIMEOUT, /*!< Astronode did not answer before timeout */
RS_ASSET_FAILURE, /*!< Failure in communication with the Astronode */
RS_ASTRONODE_FAILURE, /*!< Astronode answers an error (0xFF opcode) */
} as_return_status_t;
Note: RS_ASSET_BUSY is not available in synchronous mode.
Note: The communication with the Astronode is sequential, therefore, wait for the answer (or timeout / error) before sending a new command.
The answer is available in the argument command_name_response_t.
astronode_request_command_name(command_name*_response_t)
or
astronode_poll_answer_command_name(command_name_response_t)
Depending on the return status, the answer (command_name_response_t) may have a different type (using union) or be empty.
- If return status equals RS_ASSET_FAILURE, RS_ASSET_CRC_ERROR, RS_ASSET_BUSY, RS_ASSET_TIMEOUT, the answer is empty.
- If return status equals RS_ASTRONODE_FAILURE, the answer is an enum astronode_error_code corresponding to the error code returned by the Astronode. online doc..
- If return status equals RS_ASSET_SUCCESS, the type is a structure depending on the command, command_name_response_data_t
For example, if the return status of astronode_request_configuration_r is RS_ASSET_SUCCESS, configuration_r_response_t type will be the structure configuration_r_response_data_t.
Example to read the configuration of the Astronode:
#include "astronode_application.h"
#include "astronode_transport.h"
#include "device_interface.h"
int main(void)
{
di_device_initialize();
// Send the command and wait for an answer
configuration_r_response_t ans = {0};
as_return_status_t ret = astronode_request_configuration_r(&ans);
if (ret != RS_ASSET_SUCCESS)
{
// Error
}
// For example, firmware version is: ans.data.fw_major_v, ans.data.fw_minor_v, ans.data.fw_rev_v
}
First, configure your device to receive characters from the Astonode by interrupt. Then register the callback:
di_uart_astronode_register_rx_it_callback(astronode_transport_it_receive_char_handler);
By this way, the function astronode_transport_it_receive_char_handler will be notified when a character is received.
Example to read the configuration of the Astronode:
#include "astronode_application.h"
#include "astronode_transport.h"
#include "device_interface.h"
int main(void)
{
di_device_initialize();
di_uart_user_register_rx_it_callback(user_interface_rx_interrupt_handler);
// Send the command
as_return_status_t ret = astronode_send_async_configuration_r();
if (ret != RS_ASSET_SUCCESS)
{
// Error
}
// Wait for the answer
configuration_r_response_t ans = {0};
ret = RS_ASSET_BUSY;
while (ret == RS_ASSET_BUSY)
{
ret = astronode_poll_answer_configuration_r(&ans); // Non blocking operation
// Free time to do other operations
}
if (ret == RS_SUCCESS)
{
// For example, firmware version is: ans.data.fw_major_v, ans.data.fw_minor_v, ans.data.fw_rev_v
}
else
{
// Error
}
}
The gpio event, reset and wake-up can be controlled by the functions located in astronode_gpio.c.
mkdir build
cd build
cmake ..
make
Copy the library and the device_interface.c.h in your project. Fill the device_interface. Then, depending on your compiler, set the cross-compiler path:
example:
set(path your-compiler-path)
set(prefix your-compiler-prefix)
set(CMAKE_C_COMPILER ${path}${prefix}gcc)
set(CMAKE_ASM_COMPILER ${path}${prefix}gcc)
set(CMAKE_OBJCOPY ${path}${prefix}objcopy)
set(CMAKE_OBJDUMP ${path}${prefix}objdump)
set(CMAKE_SIZE ${path}${prefix}size)
To run the tests, first, compile the code as mentioned before, then run the following lines.
cd test
ctest --verbose
The test setup is composed by a modified version of fff and unity.
Unity: http://www.throwtheswitch.org/
fff: https://github.com/meekrosoft/fff
See this article on our homepage for a detailed description of this project.