Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Settings, values, commands and messaging structures.
Settings, values, commands and messages are determined by the settings.json structure, that is parsed in build time to several .h and .c files, as described below.
It contains the following main fields:
fw_version
major
minor
hardware
type - firmware type, for example "wisentedge_nrf52840"
version
major
minor
settings
port - port on which settings are sent and received from
type - settings type, based on tracker type
setting of the form:
setting_name
id - for "basic settings" from 0x01 to 0x0F, for "advanced" from 0x11 to 0x9F
enabled - true or false
default - default value
min - min value
max - max value
length - in bytes
conversion - data type, possible options:
uint8, uint16, uint32, int8, int16, int32
float
byte_array
bool
commands
port - port on which commands are sent and received from
commands of the form:
command_name
id - from 0xA1 to 0xCF
length - length of send command value, if 0 none
conversion - data type of send value, if there is non uint8 is used
value - default value, 0 if none
values
port - port on which settings are sent and received from
values of the form:
value_name
id - from 0xD1 to 0xEF
enabled - true or false
default - default value
min - min value
max - max value
length - in bytes
conversion - data type, possible options:
uint8, uint16, uint32, int8, int16, int32
float
byte_array
bool
messages
messages of the form:
message_name
port - to send message on
id - from 0xF1 to 0xFF
length - in bytes
conversion - data type, possible options:
uint8, uint16, uint32, int8, int16, int32
float
byte_array
bool
Python parser py2h.py
and validation script validate_data.py
are used to convert settings.json
file to c files.
In particular the following files are generated:
hardware_def.h
- containing only definitions from "hardware" field
settings_def.h
and settings_def.c
- containing settings structure and auto-generated functions for access and writing to structure
commands_def.h
and commands_def.c
- commands defines and settings
values_def.h
and values_def.c
- containing main values structure and auto-generated functions for access and writing to structure
messages_def.h
and messages_def.c
- message defines and messages
All auto-generated files are equipped with /* AUTOGENERATED FILE - DO NOT MODIFY! */
comment. Sections below describe content of each generated file and helping files.
Settings module controls stored values, settings and messaging forms. Structures are auto-generated at build time, allowing for convenient modification when new HW or tracker is introduced.
Structure is ilustrated on the diagram below and further explained in the following sections.
Auto-generated files messages_def.h and messages_def.c containing all message forms as defined in settings.json file.
Auto-generated defines for all messages ID-s. Based on message ID, appropriate message is composed and returend in firmware. All defines are of the form MSG_XXX_ID
.
main_messages
struct is auto-generated to contain all messages of cmd_message
struct type as defined in settings.json file. In addition to message structs containing different message forms, it contains:
n_values - number of values
messages_id - array containing all messages ids
messages_length - array containing all messages lengths
messages_port - array containing all port numbers on which message is sent
Main_messages
is global main_messages
struct, accessible in all threads and modules that contains all defined message types.
Structures definitions for usage in settings, values, messages and commands. Defined in settings_types.h file.
settings_types.h
file contains all structures and enums used in settings module, that are used in subsequent files and do not need to be auto-generated at build time.
enum conversion_t
defines all possible data types used in settings:
UINT8_T = 1,
UINT16_T = 2,
UINT32_T = 3,
INT8_T = 4,
INT16_T = 5,
INT32_T = 6,
FLOAT = 7,
BYTE_ARRAY = 8,
BOOL = 9
hw_type
defines all possible HW versions that are supported.
wisentedge_nrf52840 = 1
fw_type
defines all possible FW versions that are supported in FW.
lion_tracker = 1
Structures containing settings governing settings, values, messages and commands communication and fields. Mainly containing port number for specific type.
fw_version
major
minor
hw_version
hw_type
(enum)
major
minor
settings_defines
- settings for basic settings values
port
fw_type
advanced_settings
- settings for advanced settings values
port
commands_settings
port
values_settings
port
Definitions of structs holding values and settings of certain types:
value_uint8
value_uint16
value_uint32
value_int8
value_int16
value_int32
value_float
value_byte_array
value_bool
Each structure is of the same format containing:
uint8_t id
- id of setting or value
bool enabled
- is setting or value enabled
def_val
- default value of certain type
min
- min value of certain type
max
- max value of certain type
uint8_t len
- length of type in bytes
conversion_t conversion
- data type
Note that float values are stored as int16_t array[2]
with encoding:
array[0] = (int16_t) float_val
and
array[1] = (int16_t) (float_val - array[0]) * 10000
Most files, containing settings, values, commands and messages data and forms are auto-generated at build time, as they depend on Settings.json file and are dependent on specific tracker type.
Python parser py2h.py
and validation script validate_data.py
are used to convert settings.json
file to c files.
In particular the following files are generated:
hardware_def.h
- containing only definitions from "hardware" field
settings_def.h
and settings_def.c
- containing settings structure and auto-generated functions for access and writing to structure
commands_def.h
and commands_def.c
- commands defines and settings
values_def.h
and values_def.c
- containing main values structure and auto-generated functions for access and writing to structure
messages_def.h
and messages_def.c
- message defines and messages
All auto-generated files are equipped with /* AUTOGENERATED FILE - DO NOT MODIFY! */
comment. Sections below describe content of each generated file and helping files.
Auto-generated files commands_def.h and commands_def.c containing all commands defined in settings.json file.
Auto-generated files settings_def.h and settings_def.c containing all settings defined in settings.json file and functions for getting and setting values.
Returns data type for setting with specified ID.
Returns value struct based on setting ID.
main_settings
struct is auto-generated to contain all settings as defined in settings.json file. In addition to value structs containing settings, it contains:
n_settings - number of settings
settings_id - array containing all settings ids
settings_length - array containing all settings lengths
Main_settings
is global main_settings
struct, accessible in all threads and modules that contains all settings data.
Settings_defines
is global settings_defines
struct , accessible in all threads and modules that contains settings for receiving and sending settings.
void *get_setting_struct_by_id(uint8_t id)
- returns setting value, provided ID of setting.
int set_setting_value_by_id(uint8_t id, uint8_t *data, uint8_t len)
- sets value of setting, provided setting id, new value in form of a byte array and its length. Function returns 0 if ok and -1 if error in provided length.
For all settings defined in settings.json, structs of appropriate type are auto-generated and initialised with provided data. Main_settings
struct is initialised with generated setting structures.
Described functions definitions are auto-generated.
Auto-generated files values_def.h and values_def.c containing all values defined in settings.json file and functions for getting and setting values.
main_values
struct is auto-generated to contain all values as defined in settings.json file. In addition to value structs containing settings, it contains:
n_values - number of values
values_id - array containing all values ids
values_length - array containing all values lengths
Values are defined using same values structs as are used for settings and defined in settings_types.h
.
Main_values
is global main_values
struct, accessible in all threads and modules that contains all tracker functionality values.
Values_settings
is global values_settings
struct , accessible in all threads and modules that contains settings for receiving and sending values.
void *get_value_struct_by_id(uint8_t id)
- returns value struct, provided ID of value.
int get_value_by_id(uint8_t id, uint8_t *data)
- returns value from the value struct, provided ID of value.
int set_value_by_id(uint8_t id, uint8_t *data, uint8_t len)
- sets value, provided value id, new value in form of a byte array and its length. Function returns 0 if ok and -1 if error in provided length.
For all values defined in settings.json, structs of appropriate type are auto-generated and initialised with provided data. Main_values
struct is initialised with generated values structures.
Described functions definitions are auto-generated.
Interface files for utilising auto-generated settings files from the main thread and firmware modules.
Function int init_settings(void)
, initialises the settings module. It first initialises nvs storage system by calling int nvs_storage_init()
and upon success updates all values and settings from nvs storage by calling int update_all_from_nvs()
.
Settings are updated only if previousy stored in the nvs storage and if stored type is compatible with setting variable.
Upon receiving new BLE or LoRa message in the main thread, message is parsed by calling int parse_message(uint8_t *message, uint8_t message_length)
function that takes message and its length as input parameters, then replaces message with response, if there is one, and returns response length. Upon error, negative error code is returned.
Message can consist of several stacked messages, however all need to be sent on the same port. In both BLE and LoRa messages, first message entry is sent port, based on which messages are parsed later on.
New message begins with ID, the length and number of bytes define by length. If length is 0, only message ID is needed for execution. Once new message is red, it is executed by passing it to int execute_message(uint8_t port, uint8_t id, uint8_t len, uint8_t data, uint8_t *response_message)
function.
Based on port number, message is treated as:
setting - {setting_id, setting_len, setting[setting_len]}
if ID is valid, new value is stored to nvs and replaced in the Main_settings
structure
values - currently only outgoing value messages are supported
command - commands are executed in int execute_command_message(uint8_t port, uint8_t id, uint8_t len, uint8_t data, uint8_t *response_message)
function.
execute_command_message
function, executes commands, based on theirs ID number, which are defined in commands_def.h auto-generated file. Currently the following are supported:
CMD_RESET - system reboot
CMD_SEND_SINGLE_VAL - returns response message of the form {val_id, val_len, val[val_len]}
.
CMD_SEND_ALL_VAL - return a string of single values, containing all supported values, of total max message length
CMD_SEND_STATUS - returns status message. See Status chapter for detailed description.
CMD_SEND_POSITION - returns gps coordinates values.
After execute_message
returns length of the response, non-zero responses are stacked in single response message, thath is returend via approprite port, determined in execute_message
function. New port is stored as a first entry of final response. parse_message
returns length of the response message or negative error code.
status.h and status.c files define status structs and form in which firmware parameters are stored and periodically sent via LoRa and as BLE advertisement.
Status can consit of several building blocks, defined by FW and tracker type. Each building block is a byte array, where each byte reperesents a values as defined in governing status structre.
Total status cannot exceed 24 - DEVICE_NAME_LEN bytes, as this is the maximum length of BLE advertisment packet. Currently max length is set to 19 bytes.
Main building block is defined by statusData_t struct:
that can be compressed in byte array by
Individual values are defined as:
reset_cause - TBD
system_functions_errors - TBD
battery = (battery_mV - 2500)/10
charging_voltage - TBD
temperature - TBD
uptime - uptime in hours, with 255 turnaround
acc_x - abs(acc_x*10)
acc_y - abs(acc_y*10)
acc_z - abs(acc_z*10)
Total length of main status part is 9 bytes.
If #define STATUS_LR
is enabled, additional LR chip status block is added.
where:
satellites - nr. of satellites used in last LR fix
last_fix - TBD
Total length of LR buildning block is 2 bytes.
If #define STATUS_UBLOX
is enabled, additional UBLOX chip status block is added.
where:
lat - latitude defined as:
lat[0] = (lat+90)*1000 >> 16
lat[1] = (lat+90)*1000 >> 8
lat[2] = (lat+90)*1000
lon - longitude defined as:
lon[0] = (lat+180)*1000 >> 16
lon[1] = (lat+180)*1000 >> 8
lat[2] = (lat+180)*1000
time - TBD
Total length of UBLOX status is 8 bytes.
To obtain new status message for either BLE advertisement or LR status send, int get_status_message(uint8_t *message, uint8_t max_len)
function updates all values with int update_status_message(bool lr_status, bool ublox_status)
function and returns message length.
max_len
can be passed as an argument, as maximal length of message depends on the send format. If status message is too long, only max_len
message will be returned.
type_conversion.h and type_conversion.c files define conversion functions that convert all used var types from and to byte arrays, using little endian rule.
Since settings and values are stored in nvs storage in byte array form, as well they are sent via LoRa and BLE messages, functions are used to convert byte arrays to data data format used in firmware and back.
Provided functions for byte array to variable type conversion:
uint32_t bytes_to_uint32_t(uint8_t bytes)
int32_t bytes_to_int32_t(uint8_t bytes)
uint16_t bytes_to_uint16_t(uint8_t bytes)
int16_t bytes_to_int16_t(uint8_t bytes)
int8_t bytes_to_int8_t(uint8_t bytes)
uint8_t bytes_to_uint8_t(uint8_t bytes)
void bytes_to_float(uint8_t bytes, int16_t data[])
uint8_t bytes_to_byte_array(uint8_t* bytes, uint8_t length)
Provided functions for variable type to byte array conversion:
void uint32_t_to_bytes(uint8_t bytes, uint32_t data)
void uint16_t_to_bytes(uint8_t bytes, uint16_t data)
void uint8_t_to_bytes(uint8_t bytes, uint8_t data)
void int32_t_to_bytes(uint8_t bytes, int32_t data)
void int16_t_to_bytes(uint8_t bytes, int16_t data)
void int8_t_to_bytes(uint8_t bytes, int8_t data)
void bool_to_bytes(uint8_t bytes, bool data)
void float_to_bytes(uint8_t bytes, int16_t data[2])
void byte_array_to_bytes(uint8_t bytes, uint8_t data, uint8_t length);
NVS storage system is used for permanent settings and values storage. nvs_storage.c and nvs_storage.h files provide user interface for accessing and storing values.
Values and settings are stored in NVS system by their assigned ID. IDs are ordered as follows:
Each setting, defined in Main_settings struc is stored by setting ID, defined in Settings.JSON file.
Basic settings IDs 0x01 - 0x0F
Advanced settings IDs 0x11 - 0x9F
Other values that needs to be permanently stored for fimware operation are shifted for 8 bits and start with 0x0100.
nvs_storage.h contains list of stored values IDs, that are not part of Main_settings:
STORAGE_unix_time 0x0100
STORAGE_latitude 0x0101
STORAGE_longitude 0x0102
STORAGE_altitude 0x0103
NVS storage is initialised with int nvs_storage_init(void)
function, returning 0 on success or negative error code.
To clear whole NVS system, int nvs_storage_clear(void)
function is used. To delete only single entry by ID int nvs_storage_delete(uint16_t id)
can be used.
To read from NVS by value ID int nvs_storage_read(uint16_t id, const void *data, size_t len)
function returns 0 on sucess.
To write to NVS storage int nvs_storage_write(uint16_t id, const void *data, size_t len)
function attempts to write new or existing value.