Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the hardware monitoring structure #9

Merged
merged 5 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ LDLIBS += -l $(NAME)
LDFLAGS += $(shell pkg-config --libs-only-L *.pc)
LDLIBS += $(shell pkg-config --libs-only-l *.pc)

SOURCES := $(shell find $(SOURCE_FOLDER) -name '*.c')
SOURCES != find $(SOURCE_FOLDER) -name '*.c'
OBJECTS := $(SOURCES:$(SOURCE_FOLDER)/%.c=$(CACHE_FOLDER)/%.o)
MAIN_OBJ := $(CACHE_FOLDER)/parse_ublox.o

SOURCE_SUBFOLDERS != find $(SOURCE_FOLDER) -type d

PDF := $(DOC_FOLDER)/latex/refman.pdf
HTML := $(DOC_FOLDER)/html/index.html
MAN := $(DOC_FOLDER)/man/man3/ublox.h.3
Expand Down Expand Up @@ -128,18 +130,15 @@ fclean: clean ## Remove all generated files

include $(wildcard $(OBJECTS:.o=.d)) # To know on which header each .o depends

$(CACHE_FOLDER): # Create the cache folder
mkdir $@
$(SOURCE_SUBFOLDERS:$(SOURCE_FOLDER)%=$(CACHE_FOLDER)%): # Create the cache folder
mkdir -p $@

$(EXECUTABLE): $(MAIN_OBJ) $(LIBRARY) # Link the executable
$(CC) $(CFLAGS) $< $(LDFLAGS) $(LDLIBS) -o $@

$(OBJECTS): $(CACHE_FOLDER)/%.o: $(SOURCE_FOLDER)/%.c # declare the dependency between objects in cache and sources in src.
$(MAIN_OBJ): $(CACHE_FOLDER)/%.o: %.c # declare the dependency of the object containing the main

$(OBJECTS) $(MAIN_OBJ): | $(CACHE_FOLDER) libft.pc # Compile a single object
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@

$(LIBRARY): $(OBJECTS) # Group all the compiled objects into an indexed archive
$(AR) rcs $@ $^

Expand All @@ -152,3 +151,11 @@ $(MAN) $(HTML) $(LATEX)/Makefile: $(DOC_FOLDER)/Doxyfile $(SOURCES) include/*.h

%.pc: # Warm about missing pkg-config file
@$(error Run ./setup.sh first !)

# When a rule is expanded, both the target and the prerequisites
# are immediately evaluated. Enabling a second expansion allows
# a prerequisite to use automatic variables like $@, $*, etc
.SECONDEXPANSION:

$(OBJECTS) $(MAIN_OBJ): | $$(@D) libft.pc # Compile a single object
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
10 changes: 5 additions & 5 deletions doc/pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
## ANT-OM : ANTena Operation Management

Pour la fonction : `ANT-OM` c'est à dire le module qui vérifie le bon fonctionnement de l'antenne GNSS utilisée dans l'application:
1) Problème de Celestica qui a un splitter qui ne permet pas de détecter l'état de l'alimentation de l'antenne
2) Problème où l'antenne est en bypass sur la carte (antenna_status = 3) mais journalctl nous affiche que le recepteur à un Fix3D. Le recepteur fonctionne mais ocillartord nous indique que l'antenne est en court-circuit et reste en holdover.
3) Le recepteur peut fonctionner alors que l'antenne_status indique que l'antenne n'est pas connecté(antenna_status : 4).
4) Ne pas diminuer trop la puissance du signal en en chainant les splitters, le recepteur ne detectera plus le signal.
5) Un signal en sortie de simulateur qui n'est pas bien synchronisé peut généré un Fix3D sur recepteur mais peut empêcher oscillatord d'entrer dans ses boucles d'asservissement.
1. Problème de Celestica qui a un splitter qui ne permet pas de détecter l'état de l'alimentation de l'antenne
2. Problème où l'antenne est en bypass sur la carte (antenna_status = 3) mais journalctl nous affiche que le recepteur à un Fix3D. Le recepteur fonctionne mais ocillartord nous indique que l'antenne est en court-circuit et reste en holdover.
3. Le recepteur peut fonctionner alors que l'antenne_status indique que l'antenne n'est pas connecté(antenna_status : 4).
4. Ne pas diminuer trop la puissance du signal en en chainant les splitters, le recepteur ne detectera plus le signal.
5. Un signal en sortie de simulateur qui n'est pas bien synchronisé peut généré un Fix3D sur recepteur mais peut empêcher oscillatord d'entrer dans ses boucles d'asservissement.
1 change: 0 additions & 1 deletion include/ublox.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "file_input_stream.h"
#include "serial.h"

#include <ft_prepro/enum.h>
#include <ft_string.h>

#include <sys/types.h> // size_t
Expand Down
22 changes: 21 additions & 1 deletion include/ublox_enums.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <ft_prepro/enum.h>

/**
* @file ublox_enums.h
*/
Expand Down Expand Up @@ -37,6 +39,13 @@ DECLARE_ENUM_WITH_VALUES(ublox_monitoring_message,
(COMMS /**< Communication port information */, 0x36)
);

/**
* Possible messages in the RXM class
*/
DECLARE_ENUM_WITH_VALUES(ublox_receiver_message,
(SFRBX /**< Broadcast navigation data subframe */, 0x13)
);

/**
* Possible values of @ref ublox_navigation_data::constellation
*/
Expand All @@ -63,7 +72,7 @@ enum ublox_jamming_state
};

[[ maybe_unused ]]
static const char* ublox_jamming_state_strings[] = {"unkown", "OK", "warning", "critical"};
static const char* ublox_jamming_state_strings[] = {"unknown", "OK", "warning", "critical"};

enum ublox_antenna_status
{
Expand All @@ -77,3 +86,14 @@ enum ublox_antenna_status

[[ maybe_unused ]]
static const char* ublox_antenna_status_strings[]= {"initializing", "unknown", "OK", "short", "open"};

enum ublox_antenna_power
{
UBLOX_ANTENNA_OFF,
UBLOX_ANTENNA_ON,
UBLOX_ANTENNA_POWER_UNKNOWN,
ublox_antenna_power_count
};

[[ maybe_unused ]]
static const char* ublox_antenna_power_strings[]= {"OFF", "ON", "unknown"};
89 changes: 50 additions & 39 deletions include/ublox_messages.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@
*/
struct ublox_navigation_data
{
struct ublox_header header;
uint8_t constellation; /**< GNSS identifier */
uint8_t satellite; /**< Satellite identifier */
uint8_t signal; /**< Signal identifier */
uint8_t glonass_frequency; /**< Only used for GLONASS */
/** The number of data words contained in this message. */
uint8_t word_count;
/** The tracking channel number the message was received on. */
uint8_t channel;
/** Message version (=2 for this version). */
uint8_t version;
uint8_t _reserved;
struct ublox_header header;/**< Inherit from ublox message base struct */

uint8_t constellation; /**< GNSS identifier */
uint8_t satellite; /**< Satellite identifier */
uint8_t signal; /**< Signal identifier */
uint8_t glonass_frequency; /**< Only used for GLONASS */
uint8_t word_count; /**< The number of data words contained in this message. */
uint8_t channel; /**< The tracking channel number the message was received on. */
uint8_t version; /**< Message version (=2 for this version). */
uint8_t _reserved;
};

/**
Expand All @@ -42,10 +40,11 @@ struct ublox_navigation_data
*/
struct ublox_monitoring_rf
{
struct ublox_header header;
uint8_t version; /**< Message version (=0 in this case) */
uint8_t block_count; /**< Number of RF blocks included */
uint16_t _reserved;
struct ublox_header header; /**< Inherit from ublox message base struct */

uint8_t version; /**< Message version (=0 in this case) */
uint8_t block_count; /**< Number of RF blocks included */
uint16_t _reserved;
};

struct ublox_monitoring_rf_block
Expand All @@ -58,7 +57,7 @@ struct ublox_monitoring_rf_block
uint32_t _reserved1;
uint16_t noise_per_ms; /**< Noise level as measured by the GPS core */
uint16_t agc_count; /**< Automatic Gain Control */
uint8_t jam_suppression; /**< Continuous Wave interference suppression level */
uint8_t jam_level; /**< Continuous Wave interference suppression level */
int8_t offset_i; /**< Imbalance of the I-part of the complex signal */
uint8_t magnitude_i; /**< Magnitude of the I-Part of the complex signal */
int8_t offset_q; /**< Imbalance of the Q-part of the complex signal */
Expand All @@ -68,27 +67,33 @@ struct ublox_monitoring_rf_block

struct ublox_monitoring_hardware
{
struct ublox_header header;
uint32_t pin_sel;
uint32_t pin_bank;
uint32_t pin_dir;
uint32_t pin_val;
uint16_t noise_per_ms;
uint16_t agc_count;
uint8_t antenna_status;
uint8_t antenna_power;
uint8_t rtc_calib :1;
uint8_t safe_boot :1;
uint8_t jamming_state :2;
uint8_t xtal_absent :1;
uint8_t _reserved0;
uint32_t used_mask;
uint8_t vp[17];
uint8_t jam_indicator;
uint8_t _reserved1[2];
uint32_t pin_irq;
uint32_t pull_high;
uint32_t pull_low;
struct ublox_header header; /**< Inherit from ublox message base struct */

uint32_t pins_selected; /**< Mask of pins set as peripheral/PIO */
uint32_t pins_bank; /**< Mask of pins set as bank A/B */
uint32_t pins_direction; /**< Mask of pins set as input/output */
uint32_t pins_value; /**< Mask of pins value low/high */
uint16_t noise_per_ms; /**< Noise level as measured by the GPS core */
uint16_t agc_count; /**< Automatic Gain Control */
/** Status of the antenna supervisor state machine */
uint8_t antenna_status;
uint8_t antenna_power; /**< Current power status of the antenna */
uint8_t is_rtc_calibrated :1; /**< is the Real-Time Clock calibrated ? */
uint8_t in_safe_boot_mode :1;
/** Output from Jamming/Interference Monitor */
uint8_t jamming_state :2;
/** Has the real-time clock's crystal been determined to be absent ? */
uint8_t is_crystal_absent :1;
uint8_t _reserved0;
/** Mask of pins that are used by the virtual pin manager */
uint32_t used_mask;
/** Array of pin mappings for each of the 17 physical pins */
uint8_t virtual_pins[17];
uint8_t jam_level; /**< Continuous Wave interference suppression level */
uint8_t _reserved1[2];
uint32_t pins_interrupt; /**< Mask of pins value using the PIO Irq */
uint32_t pins_pull_high; /**< Mask of pins value using the PIO pull high resistor */
uint32_t pins_pull_low; /**< Mask of pins value using the PIO pull low resistor */
};

t_string ublox_navigation_data_tostring(const struct ublox_navigation_data* message);
Expand All @@ -101,7 +106,7 @@ t_string ublox_monitoring_rf_tostring(const struct ublox_monitoring_rf* message)
- `1`: L2 or L5 band (depending on product configuration)

@var ublox_monitoring_rf_block::jamming_state
@see ublox_mon_rf_jamming_state
@see ublox_jamming_state
This flag is deprecated in protocol versions that support `UBX-SEC-SIG` (version 0x02);
instead `jammingState` in `UBX-SEC-SIG` should be monitored.

Expand All @@ -110,6 +115,12 @@ The AGC monitor counts the number of times the signal level crosses a certain th
by the signals SIGHI and SIGLO
*/

/**
@var ublox_monitoring_hardware::agc_count
The AGC monitor counts the number of times the signal level crosses a certain threshold, indicated
by the signals SIGHI and SIGLO
*/

/**
@var ublox_navigation_data::glonass_frequency
This is the frequency slot + 7 (range from 0 to 13)
Expand Down
16 changes: 12 additions & 4 deletions include/ublox_reader.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once

/**
* @file ublox_reader.h
*/

#include "file_input_stream.h"
#include "ublox.h"

Expand All @@ -14,10 +18,14 @@ typedef struct ublox_reader ublox_reader_t;

struct ublox_reader
{
ifstream_t* input;
t_array callbacks;
ifstream_t* input; /**< Buffured input stream */
t_array callbacks; /**< */
};

struct ublox_reader ublox_reader_init(ifstream_t* input);
void ublox_subscribe(ublox_reader_t* reader, ublox_callback_t callback);
bool ublox_reader_loop(ublox_reader_t* reader);
void ublox_reader_close(ublox_reader_t* self);

void ublox_subscribe(ublox_reader_t* reader, ublox_callback_t callback);
bool ublox_reader_loop(ublox_reader_t* reader);

#define Reader ublox_reader_t __attribute__((cleanup(ublox_reader_close)))
42 changes: 29 additions & 13 deletions parse_ublox.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ void ublox_printer(ublox_message_t* message)
{
RAII(t_string)
str = ublox_navigation_data_tostring((struct ublox_navigation_data*)message);
log_info("{%s}", cstring(&str));
printf("{%s}\n---\n", cstring(&str));
}
else if (message->class == MON && message->type == HW)
{
RAII(t_string)
str = ublox_monitoring_hardware_tostring((struct ublox_monitoring_hardware*)message);
log_info("{%s}", cstring(&str));
printf("{%s}\n---\n", cstring(&str));
}
else if (message->class == MON && message->type == RF)
{
RAII(t_string)
str = ublox_monitoring_rf_tostring((struct ublox_monitoring_rf*)message);
log_info("{%s}", cstring(&str));
printf("{%s}\n---\n", cstring(&str));
}
else
{
RAII(t_string) str = ublox_header_tostring(message);
log_info("{%s}", cstring(&str));
printf("{%s}\n---\n", cstring(&str));
}
}

Expand All @@ -46,20 +46,32 @@ void ublox_printer(ublox_message_t* message)
*
* @param passive: When passive, do not change the port config, only display it
* and try to read.
* @param is_file: Do not try to access the terminal options
*/
void parse_ublox(const char* port_name, bool passive)
void parse_ublox(const char* file_name, bool passive, bool is_file)
{
Serial port = serial_open(port_name);
serial_port_t port;

if (port.file.descriptor < 0
|| (!passive && ublox_port_config(&port, 115200) == false))
if (is_file)
port.file = file_open(file_name, O_RDONLY);
else
{
port = serial_open(file_name);

if (!passive && ublox_port_config(&port, 115200) == false)
return ;
serial_print_config(&port);

}

if (port.file.descriptor < 0)
return ;
serial_print_config(&port);

ublox_reader_t reader = ublox_reader_init(&port.file);
Reader reader = ublox_reader_init(&port.file);

ublox_subscribe(&reader, ublox_printer);
ublox_reader_loop(&reader);
} /* <- port will be closed at this point */
}

const char* argp_program_version = "ublox_parser " PP_STR(VERSION);
const char* argp_program_bug_address = "<antoine.gagniere@orolia2s.com>";
Expand All @@ -68,12 +80,14 @@ static char args_doc[] = "[PATH]";

static struct argp_option options[] = {
{"passive", 'p', 0, OPTION_ARG_OPTIONAL, "Do not change the port configuration, only display it.", 1},
{"file", 'f', 0, OPTION_ARG_OPTIONAL, "Input is not a serial port but a file", 1},
{0}
};

struct arguments
{
bool is_passive;
bool is_file;
};

static error_t parse_opt(int key, char* arg, struct argp_state* state)
Expand All @@ -82,9 +96,10 @@ static error_t parse_opt(int key, char* arg, struct argp_state* state)
switch (key)
{
case 'p': arguments->is_passive = true; break;
case 'f': arguments->is_file = true; break;
case ARGP_KEY_ARG:
if (arg)
parse_ublox(arg, arguments->is_passive);
parse_ublox(arg, arguments->is_passive, arguments->is_file);
return 0;
default: return ARGP_ERR_UNKNOWN;
}
Expand All @@ -95,8 +110,9 @@ static struct argp argp = {options, parse_opt, args_doc, doc, 0, 0, 0};

int main(int arg_count, char** arg_values)
{
struct arguments arguments = {.is_passive = false};
struct arguments arguments = {.is_passive = false, .is_file = false};

printf("---\n");
argp_parse(&argp, arg_count, arg_values, 0, 0, &arguments);
return 0;
}
2 changes: 1 addition & 1 deletion src/file_close.c → src/file/close.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* In case of error when calling close, there is absolutely nothing interesting
* that can be done beyond reporting it, so it is not propagated.
*/
void serial_close(ifstream_t* file)
void file_close(ifstream_t* file)
{
log_trace("%s(%i)", __FUNCTION__, file->descriptor);
if (file->buffer.data)
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading