Unification des sources CM4/CM5 : makefiles scindés (common/cm4/cm5/cm5.debug), #ifdef CIBLE_CM5 pour GPIO, correctifs get_ip_address()/signal handler/backtrace, portabilité 32/64 bits

This commit is contained in:
2026-09-23 14:51:33 +02:00
parent 8fe204361b
commit fdf08bf1d7
23 changed files with 373 additions and 154 deletions
+1
View File
@@ -2,3 +2,4 @@ objets/
bin/ bin/
versions/ versions/
sources/_version.txt sources/_version.txt
objets_debug/
+1 -2
View File
@@ -3,7 +3,6 @@
# Informations : # Informations :
# 1. Ce fichier doit être exécutable : sudo chmod +x <nom du fichier> # 1. Ce fichier doit être exécutable : sudo chmod +x <nom du fichier>
# 2. il peut être lancé manuellement par : ./<nom relatif ou complet du fichier> # 2. il peut être lancé manuellement par : ./<nom relatif ou complet du fichier>
# 3. les sorties standard et d'erreur sont redirigées vers un fichier dans le répertoire UPLOAD (donc il sera uploadé à la prochaine connexion puis supprimé localement)
################################################################################################# #################################################################################################
# Variables globales : # Variables globales :
DATEVERSION=$(date +"%y%m%d_%H%M%S") DATEVERSION=$(date +"%y%m%d_%H%M%S")
@@ -13,7 +12,7 @@ DATEVERSION=$(date +"%y%m%d_%H%M%S")
echo "#define VERSION_LOGICIEL \""$DATEVERSION"\"" > ../sources/_version.txt echo "#define VERSION_LOGICIEL \""$DATEVERSION"\"" > ../sources/_version.txt
#============================================================================================================== #==============================================================================================================
# Lancement du makefile : # Lancement du makefile :
make make -f makefile.cm5
#============================================================================================================== #==============================================================================================================
# Sauvegarde de la version : # Sauvegarde de la version :
cp "../bin/shipheart_appli" "../versions/shipheart_appli_"$DATEVERSION cp "../bin/shipheart_appli" "../versions/shipheart_appli_"$DATEVERSION
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
#################################################################################################
# Version DEBUG (ASan) — ne génère PAS d'entrée dans versions/, uniquement le binaire de test.
#################################################################################################
# Variables globales :
DATEVERSION=$(date +"%y%m%d_%H%M%S")
#==============================================================================================================
# Met à jour le fichier '_version.txt' dans le répertoire ../sources avec le 'datecode'. Celui-ci sera
# utilisé lors de la compilation/link de l'application comme version du logiciel.
echo "#define VERSION_LOGICIEL \""$DATEVERSION"\"" > ../sources/_version.txt
#==============================================================================================================
# Lancement du makefile :
make -f makefile.cm5.debug
#==============================================================================================================
# Déploiement vers le CM5 (nécessaire depuis le passage en cross-compilation WSL2 -
# auparavant la compilation avait lieu directement sur le CM5, donc le binaire y
# était déjà présent). Utilise l'alias SSH 'cm5' défini dans ~/.ssh/config.
# NB : shipheart_appli tourne en permanence sur le CM5 - une écriture directe sur
# le fichier cible échoue ("Text file busy"). On écrit donc dans un fichier
# temporaire, puis on renomme (opération atomique, fonctionne même sur un
# exécutable en cours d'utilisation).
scp -q "../bin/shipheart_appli" cm5:/home/koriolan/shipheart/versions/current/shipheart_appli.new
ssh cm5 "mv /home/koriolan/shipheart/versions/current/shipheart_appli.new /home/koriolan/shipheart/versions/current/shipheart_appli"
#==============================================================================================================
# Fin :
exit 0
-46
View File
@@ -1,46 +0,0 @@
# Choix du compilateur croisé (cible aarch64/CM5, exécuté depuis WSL2 x86_64) :
CC=aarch64-linux-gnu-gcc
# Recherche pkg-config restreinte aux .pc arm64 uniquement (PKG_CONFIG_LIBDIR
# écrase le chemin de recherche par défaut, pour ne jamais mélanger avec les
# .pc x86_64 de l'hôte). mariadb_config est abandonné : ce script n'est pas
# conscient du multiarch et renverrait les chemins x86_64 de l'hôte.
PKGCONFIG = PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig pkg-config
# Options de compilation :
# PRODUCTION :
CFLAGS = -O3 -Wall $(shell $(PKGCONFIG) --cflags mariadb alsa libssl libcrypto json-c libgpiod)
# DEBUG :
#CFLAGS = -O3 -Wall $(shell $(PKGCONFIG) --cflags mariadb alsa libssl libcrypto json-c libgpiod) -gstabs
# Possibilité d'utiliser aussi '-Wunused-variable' si besoin... Voire 'Wall' si on veut se faire mal...!
# Options de link pour accéder à MariaDB, Alsa, OpenSSL, json-c et GPIO :
LIBS = $(shell $(PKGCONFIG) --libs mariadb alsa libssl libcrypto json-c libgpiod) -lm
# Localisation des répertoires :
SRCDIR=../sources
OBJDIR=../objets
EXEDIR=../bin
# Nom de l'éxécutable généré :
EXECUTABLE=shipheart_appli
#------------------------------------------------------------------------------------------------------------
# !!!!!!!!! .............................NE DOIT PAS ETRE MODIFIE EN DESSOUS.......................!!!!!!!!!!
#------------------------------------------------------------------------------------------------------------
SRC= $(wildcard $(SRCDIR)/*.c)
DEPS= $(wildcard $(SRCDIR)/*.h)
OBJ = $(subst $(SRCDIR),$(OBJDIR), $(patsubst %.c, %.o, $(SRC)) )
# Règle de plus haut niveau :
all: $(EXEDIR)/$(EXECUTABLE)
# Linker (dépendance de l'exécutable vs les fichiers Objet) :
$(EXEDIR)/$(EXECUTABLE): $(OBJ)
$(CC) -o $@ $^ $(LIBS)
# Compilateur (dépendance des fichiers Objet vs leur fichier Source et TOUS les Headers) :
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(DEPS)
$(CC) -o $@ -c $< $(CFLAGS)
# Cas particulier du fichier '_version.c' qui dépend, en plus, du fichier '_version.txt' :
# cf fichier '_version.c' pour détails.
$(OBJDIR)/_version.o: $(SRCDIR)/_version.c $(SRCDIR)/_version.txt
$(CC) -o $(OBJDIR)/_version.o -c $(SRCDIR)/_version.c $(CFLAGS)
# NB : Les focntions de type Clean ou Mrproper ne sont pas laissées car
# on part du principe qu'on garde les fichiers objets dans le répertoire dédié...
+20
View File
@@ -0,0 +1,20 @@
# Choix du compilateur 'gcc' ou 'g++' NB : un (seul) test avec les deux donne un exécutable 20% plus petit avec GCC qu'avec G++ !
CC=gcc
# Options de compilation :
CFLAGS = -O3 -Wall -funwind-tables -fno-omit-frame-pointer `mariadb_config --cflags`
# Options de link pour accéder à MariaDB et à Alsa :
LIBS = -rdynamic `mariadb_config --libs` -lm -lasound -lssl -lcrypto -ljson-c
# Localisation des répertoires :
SRCDIR=../sources
OBJDIR=../objets
EXEDIR=../../versions/current
# Nom de l'éxécutable généré :
EXECUTABLE=shipheart_appli
# Inclusion des règles communes (aux CM4/CM5 et debug) :
include makefile.common
+23
View File
@@ -0,0 +1,23 @@
# Choix du compilateur croisé (cible aarch64/CM5, exécuté depuis WSL2 x86_64) :
CC=aarch64-linux-gnu-gcc
# Recherche pkg-config restreinte aux .pc arm64 uniquement (PKG_CONFIG_LIBDIR écrase le chemin de recherche par défaut, pour ne jamais mélanger avec les .pc x86_64 de l'hôte).
PKGCONFIG = PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig pkg-config
# Options de compilation :
CFLAGS = -O3 -Wall -funwind-tables -fno-omit-frame-pointer $(shell $(PKGCONFIG) --cflags mariadb alsa libssl libcrypto json-c libgpiod)
CFLAGS += -DCIBLE_CM5
# Options de link pour accéder à MariaDB, Alsa, OpenSSL, json-c et GPIO :
LIBS = -rdynamic $(shell $(PKGCONFIG) --libs mariadb alsa libssl libcrypto json-c libgpiod) -lm
# Localisation des répertoires :
SRCDIR=../sources
OBJDIR=../objets
EXEDIR=../bin
# Nom de l'éxécutable généré :
EXECUTABLE=shipheart_appli
# Inclusion des règles communes (aux CM4/CM5 et debug) :
include makefile.common
+22
View File
@@ -0,0 +1,22 @@
# Choix du compilateur croisé (cible aarch64/CM5, exécuté depuis WSL2 x86_64) :
CC=aarch64-linux-gnu-gcc
# Recherche pkg-config restreinte aux .pc arm64 uniquement (PKG_CONFIG_LIBDIR écrase le chemin de recherche par défaut, pour ne jamais mélanger avec les .pc x86_64 de l'hôte).
PKGCONFIG = PKG_CONFIG_PATH= PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig pkg-config
# Options de compilation :
CFLAGS = -O3 -Wall -funwind-tables -fno-omit-frame-pointer $(shell $(PKGCONFIG) --cflags mariadb alsa libssl libcrypto json-c libgpiod) -fsanitize=address -g
# Options de link pour accéder à MariaDB, Alsa, OpenSSL, json-c et GPIO :
LIBS = -rdynamic $(shell $(PKGCONFIG) --libs mariadb alsa libssl libcrypto json-c libgpiod) -lm -fsanitize=address
# Localisation des répertoires :
SRCDIR=../sources
OBJDIR=../objets_debug
EXEDIR=../bin
# Nom de l'éxécutable généré :
EXECUTABLE=shipheart_appli
# Inclusion des règles communes (aux CM4/CM5 et debug) :
include makefile.common
+20
View File
@@ -0,0 +1,20 @@
SRC= $(wildcard $(SRCDIR)/*.c)
DEPS= $(wildcard $(SRCDIR)/*.h)
OBJ = $(subst $(SRCDIR),$(OBJDIR), $(patsubst %.c, %.o, $(SRC)) )
# Règle de plus haut niveau :
all: $(EXEDIR)/$(EXECUTABLE)
# Linker (dépendance de l'exécutable vs les fichiers Objet) :
$(EXEDIR)/$(EXECUTABLE): $(OBJ)
$(CC) -o $@ $^ $(LIBS)
# Compilateur (dépendance des fichiers Objet vs leur fichier Source et TOUS les Headers) :
$(OBJDIR)/%.o: $(SRCDIR)/%.c $(DEPS)
$(CC) -o $@ -c $< $(CFLAGS)
# Cas particulier du fichier '_version.c' qui dépend, en plus, du fichier '_version.txt' (cf fichier '_version.c' pour détails) :
$(OBJDIR)/_version.o: $(SRCDIR)/_version.c $(SRCDIR)/_version.txt
$(CC) -o $(OBJDIR)/_version.o -c $(SRCDIR)/_version.c $(CFLAGS)
# NB : Les fonctions de type Clean ou Mrproper ne sont pas laissées car on part du principe qu'on garde les fichiers objets dans le répertoire dédié...
+19
View File
@@ -0,0 +1,19 @@
#!/bin/bash
# Usage : ./sync_vers_cm4.sh <IP-ou-alias-ssh>
if [ -z "$1" ]; then
echo "Usage : $0 <IP-ou-alias-ssh>"
echo "NB : Le certificat est lié à une adresse précise. Si changement d'adresse cible, mettre à jour dans WSL2 par 'nano ~/.ssh/config' "
exit 1
fi
CM4_HOST="cm4-dev"
CM4_DEST="~/shipheart/appli"
echo "Synchronisation des sources vers ${CM4_HOST}:${CM4_DEST}..."
rsync -av --delete ../sources/ ${CM4_HOST}:${CM4_DEST}/sources/
echo "Synchronisation des makefiles..."
rsync -av makefile.common makefile.cm4 ${CM4_HOST}:${CM4_DEST}/make/
echo "Terminé. Pour compiler sur la carte :"
echo "Terminé. Pour compiler : ssh ${CM4_HOST} 'cd ${CM4_DEST}/make && ./mak.sh'"
+10
View File
@@ -341,6 +341,16 @@ char suffixe_fichier_log[MAX_LONGUEUR_NOM_FICHIER];
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG]; char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// sprintf(tmp, "/!\\ \tFonction d'archivage TEMPORAIREMENT suspendue...");
// affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_WARNING);
// return(0);
// Calcul de la date courante pour nommer le fichier de logs : // Calcul de la date courante pour nommer le fichier de logs :
time(&now); time(&now);
maintenant = *localtime(&now); maintenant = *localtime(&now);
+14 -5
View File
@@ -200,22 +200,31 @@ affichage_debug(__FILE__, __LINE__, "------------------BDD_INIT", TYPE_MESSAGE_D
else if (strcmp(row[0], "Periode_check_adresses_ip") == 0) reseaux.periode_check_adresses_ip = atoi(row[1]); else if (strcmp(row[0], "Periode_check_adresses_ip") == 0) reseaux.periode_check_adresses_ip = atoi(row[1]);
else if (strcmp(row[0], "Periode_scan_wifi_sta") == 0) reseaux.periode_scan_sta = atoi(row[1]); else if (strcmp(row[0], "Periode_scan_wifi_sta") == 0) reseaux.periode_scan_sta = atoi(row[1]);
else if (strcmp(row[0], "Acces_webgl_1_validation") == 0) reseaux.webgl_new[0].validite = atoi(row[1]); else if (strcmp(row[0], "Acces_webgl_1_validation") == 0)
{
if (systeme.generation_shipbase <= GENERATION_SHIPBASE_V2) reseaux.webgl_new[0].validite = atoi(row[1]); // On n'autorise pas la validation de WebGl sur les V3
}
else if (strcmp(row[0], "Acces_webgl_1_parametres") == 0) else if (strcmp(row[0], "Acces_webgl_1_parametres") == 0)
{ {
if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[0].parametres, row[1]); if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[0].parametres, row[1]);
} }
else if (strcmp(row[0], "Acces_webgl_2_validation") == 0) reseaux.webgl_new[1].validite = atoi(row[1]); else if (strcmp(row[0], "Acces_webgl_2_validation") == 0)
{
if (systeme.generation_shipbase <= GENERATION_SHIPBASE_V2) reseaux.webgl_new[1].validite = atoi(row[1]); // On n'autorise pas la validation de WebGl sur les V3
}
else if (strcmp(row[0], "Acces_webgl_2_parametres") == 0) else if (strcmp(row[0], "Acces_webgl_2_parametres") == 0)
{ {
if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[1].parametres, row[1]); if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[1].parametres, row[1]);
} }
else if (strcmp(row[0], "Acces_webgl_3_validation") == 0) reseaux.webgl_new[2].validite = atoi(row[1]); else if (strcmp(row[0], "Acces_webgl_3_validation") == 0)
{
if (systeme.generation_shipbase <= GENERATION_SHIPBASE_V2) reseaux.webgl_new[2].validite = atoi(row[1]); // On n'autorise pas la validation de WebGl sur les V3
}
else if (strcmp(row[0], "Acces_webgl_3_parametres") == 0) else if (strcmp(row[0], "Acces_webgl_3_parametres") == 0)
{ {
if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[2].parametres, row[1]); if (strlen(row[1]) < MAX_LONGUEUR_PARAMETRES_WEBGL) strcpy(reseaux.webgl_new[2].parametres, row[1]);
} }
else if (strcmp(row[0], "Courant_masses_maxi_sp8dc") == 0) // SDIR #318 else if (strcmp(row[0], "Courant_masses_maxi_sp8dc") == 0) // SDIR #318
{ {
systeme.courant_masses_maxi_sp8dc = atof(row[1]); systeme.courant_masses_maxi_sp8dc = atof(row[1]);
if (systeme.courant_masses_maxi_sp8dc > MAX_COURANT_MASSES_SP8DC) systeme.courant_masses_maxi_sp8dc = MAX_COURANT_MASSES_SP8DC; if (systeme.courant_masses_maxi_sp8dc > MAX_COURANT_MASSES_SP8DC) systeme.courant_masses_maxi_sp8dc = MAX_COURANT_MASSES_SP8DC;
@@ -865,7 +874,7 @@ printf("Ciruit affecté à un module de type %i \n", systeme.modules_config[circ
sprintf(requete, "SELECT Cle_primaire, Adresse_module, Type_entrees, Entrees, Mode_entrees, ID_Variable, Etat, Decalage, Gain, Valeur, \ sprintf(requete, "SELECT Cle_primaire, Adresse_module, Type_entrees, Entrees, Mode_entrees, ID_Variable, Etat, Decalage, Gain, Valeur, \
Valeur_coeff_filtrage, Mode_enregistrement_mesures, Mode_enregistrement_historique \ Valeur_coeff_filtrage, Mode_enregistrement_mesures, Mode_enregistrement_historique \
FROM TB_Capteurs ORDER BY Type_entrees, Cle_primaire"); FROM TB_Capteurs ORDER BY Type_entrees, Cle_primaire");
printf("Requete = [ %s; ]\n", requete); //printf("Requete = [ %s; ]\n", requete);
mysql_query(bdd.pointeur, requete); // Envoi de la requête à MYSQL mysql_query(bdd.pointeur, requete); // Envoi de la requête à MYSQL
result = mysql_store_result(bdd.pointeur); // Récup des résultats de la requête result = mysql_store_result(bdd.pointeur); // Récup des résultats de la requête
while((row = mysql_fetch_row(result))) // Boucle sur tous les résultats de la requête while((row = mysql_fetch_row(result))) // Boucle sur tous les résultats de la requête
+3 -2
View File
@@ -164,7 +164,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
} }
else if (strlen(ptr[0]) >= MAX_LONGUEUR_NOM_FICHIER) else if (strlen(ptr[0]) >= MAX_LONGUEUR_NOM_FICHIER)
{ {
sprintf(tmp, "Le nom de fichier reçu via le champ New_bip est trop long (%li caractères pour %i max). La demande est rejetée...", strlen(ptr[0]), MAX_LONGUEUR_NOM_FICHIER); sprintf(tmp, "Le nom de fichier reçu via le champ New_bip est trop long (%zu caractères pour %i max). La demande est rejetée...", strlen(ptr[0]), MAX_LONGUEUR_NOM_FICHIER);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR); affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
} }
else emission_bip(ptr[0], atoi(ptr[1]), atoi(ptr[2]), atoi(ptr[3])); // NB : si 'atoi()' rencontre une erreur, il retourne '0' qui sera traité sans problème par 'emission_bip()' else emission_bip(ptr[0], atoi(ptr[1]), atoi(ptr[2]), atoi(ptr[3])); // NB : si 'atoi()' rencontre une erreur, il retourne '0' qui sera traité sans problème par 'emission_bip()'
@@ -1043,7 +1043,8 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// ******************************************************************************************************************************************************** // ********************************************************************************************************************************************************
// Mise à jour du timestamp dans la BDD : // Mise à jour du timestamp dans la BDD :
sprintf(requete, "UPDATE TB_Systeme SET Valeur='%li' WHERE Nom='Heart_beat'", (uint64_t) time(NULL)); // Enregistrement du timestamp de MAINTENANT (permet sur les pages Web d'afficher les feux vert, orange ou rouge en fonction de la dernière valeur écrite par l'application) sprintf(requete, "UPDATE TB_Systeme SET Valeur='%" PRIu64 "' WHERE Nom='Heart_beat'", (uint64_t) time(NULL)); // Enregistrement du timestamp de MAINTENANT (permet sur les pages Web d'afficher les feux vert, orange ou rouge en fonction de la dernière valeur écrite par l'application)
mysql_query(bdd.pointeur, requete); mysql_query(bdd.pointeur, requete);
+1 -1
View File
@@ -1945,7 +1945,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//etat_nmea = commande->cde[ptr_cde ++]; //etat_nmea = commande->cde[ptr_cde ++];
// Debug : // Debug :
// printf("Etat du Compagnon reçu : Etat alim = %i, Tension = %6.3f V, Courant=%6.3f A, Courant USB=%5.3f A, Température = %5.2f °C, Humidité=%5.2f %%RH, Pression=%7.2f hPa, Origine reset = %i \n", alim_etat, in_v, in_i, usb_i, temp, hum, pat, orig); //printf("Etat du Compagnon reçu : Etat alim = %i, Tension = %6.3f V, Courant=%6.3f A, Courant USB=%5.3f A, Température = %5.2f °C, Humidité=%5.2f %%RH, Pression=%7.2f hPa, Origine reset = %i \n", alim_etat, in_v, in_i, usb_i, temp, hum, pat, orig);
} }
+13 -1
View File
@@ -33,9 +33,11 @@ uint8_t lecture_entree_gpio(uint8_t no, int8_t logique);
// Variables globales : // Variables globales :
struct Struct_entrees entrees; struct Struct_entrees entrees;
#ifdef CIBLE_CM5
struct gpiod_chip *gpiod_chip0; // Nécessaire pour CM5 struct gpiod_chip *gpiod_chip0; // Nécessaire pour CM5
struct gpiod_line_request *gpiod_entrees_request; // Nécessaire pour CM5 struct gpiod_line_request *gpiod_entrees_request; // Nécessaire pour CM5
#endif
/********************************************************************************************************************************************************************************** /**********************************************************************************************************************************************************************************
@@ -574,6 +576,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//==================================================================================================== //====================================================================================================
if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3) if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3)
{ {
#ifdef CIBLE_CM5
unsigned int offsets[MAX_NOMBRE_ENTREES_GPIO]; unsigned int offsets[MAX_NOMBRE_ENTREES_GPIO];
uint8_t nb_lignes = 0; uint8_t nb_lignes = 0;
@@ -627,6 +630,13 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
entrees.gpio.sequenceur.compteur = TEMPO_INIT_ENTREES_GPIO; entrees.gpio.sequenceur.compteur = TEMPO_INIT_ENTREES_GPIO;
return(0); // On sort ici : la boucle V1/V2 ci-dessous ne doit pas s'exécuter pour V3 return(0); // On sort ici : la boucle V1/V2 ci-dessous ne doit pas s'exécuter pour V3
#else // Compilation pour CM4 donc V1 ou V2. Ne devrait jamais arriver ... :
sprintf(tmp, "GENERATION_SHIPBASE_V3 incompatible avec cette plateforme de compilation.");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
return(-1);
#endif
} }
@@ -849,12 +859,14 @@ uint8_t lecture_entree_gpio(uint8_t no, int8_t logique)
uint8_t x; uint8_t x;
#ifdef CIBLE_CM5
if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3) if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3)
{ {
enum gpiod_line_value val = gpiod_line_request_get_value(gpiod_entrees_request, no); enum gpiod_line_value val = gpiod_line_request_get_value(gpiod_entrees_request, no);
x = (val == GPIOD_LINE_VALUE_ACTIVE) ? ON : OFF; x = (val == GPIOD_LINE_VALUE_ACTIVE) ? ON : OFF;
} }
else // Pour V1 & V2 : accès direct aux registres else // Pour V1 & V2 : accès direct aux registres
#endif
{ {
// Lecture dans les registres du BCM2836 : // Lecture dans les registres du BCM2836 :
if (no < 32) // Entrées 0 à 31 : if (no < 32) // Entrées 0 à 31 :
+2 -2
View File
@@ -68,7 +68,7 @@ int8_t ret;
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG]; char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
if (systeme.generation_shipbase != GENERATION_SHIPBASE_V2) return; if (systeme.generation_shipbase == GENERATION_SHIPBASE_V1) return;
switch(g_bus.sequenceur.etat) switch(g_bus.sequenceur.etat)
{ {
@@ -446,7 +446,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
else g_bus.down.ptr_fin_buffer_cdes --; else g_bus.down.ptr_fin_buffer_cdes --;
// Message de débug : // Message de débug :
sprintf(tmp, "Buffer de commandes M-Bus plein. La demande de stockage d'une nouvelle commande a été rejetée..."); sprintf(tmp, "Buffer de commandes G-Bus plein. La demande de stockage d'une nouvelle commande a été rejetée...");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR); affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
// Enregistrement dans l'historique : // Enregistrement dans l'historique :
+1 -1
View File
@@ -61,7 +61,7 @@ uint16_t lg_cde;
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG]; char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
if (systeme.generation_shipbase != GENERATION_SHIPBASE_V2) return; if (systeme.generation_shipbase == GENERATION_SHIPBASE_V1) return;
switch(gnss.sequenceur.etat) switch(gnss.sequenceur.etat)
{ {
+1 -1
View File
@@ -122,7 +122,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
if (ret == 1) affichage_debug_bus(TYPE_BUS_DEBUG_M_BUS, "Rx", (char *) m_bus.down.reponse.reponse, __DEBUG_M_BUS); // Cas d'une réponse normale if (ret == 1) affichage_debug_bus(TYPE_BUS_DEBUG_M_BUS, "Rx", (char *) m_bus.down.reponse.reponse, __DEBUG_M_BUS); // Cas d'une réponse normale
else else
{ {
sprintf(tmp, "[%li data bytes]", strlen((const char *)m_bus.down.reponse.reponse)); sprintf(tmp, "[%zu data bytes]", strlen((const char *)m_bus.down.reponse.reponse));
affichage_debug_bus(TYPE_BUS_DEBUG_M_BUS, "Rx", tmp, __DEBUG_M_BUS); // Cas d'une réponse en mode binaire affichage_debug_bus(TYPE_BUS_DEBUG_M_BUS, "Rx", tmp, __DEBUG_M_BUS); // Cas d'une réponse en mode binaire
} }
#endif #endif
+48 -18
View File
@@ -10,7 +10,8 @@
// Prototypes : // Prototypes :
int8_t init(void); int8_t init(void);
void sigintHandler(int dummy); void sigintHandler(int32_t signal);
void sigfatalHandler(int32_t signal);
void lancement_reinit(uint16_t tempo); void lancement_reinit(uint16_t tempo);
int8_t analyse_signal(void); int8_t analyse_signal(void);
int8_t init_signaux(void); int8_t init_signaux(void);
@@ -323,6 +324,7 @@ int8_t retour = 0;
return(retour); return(retour);
} }
//================================================================================================================================================================== //==================================================================================================================================================================
// Fonction : Initialisation des handlers de signaux (vers une seule et même fonction). // Fonction : Initialisation des handlers de signaux (vers une seule et même fonction).
// Reçoit : Rien // Reçoit : Rien
@@ -332,40 +334,44 @@ int8_t init_signaux(void)
{ {
systeme.faucheuse.signal_recu = SYSTEME_SIGNAL_AUCUN; systeme.faucheuse.signal_recu = SYSTEME_SIGNAL_AUCUN;
signal(SIGHUP, sigintHandler); // 1 SIGHUP Instruction (HANG UP) - Fin de session // Signaux ne permettant pas de traitement à proprement parler (fatal) :
signal(SIGINT, sigintHandler); // 2 SIGINT Interruption // On utilise alors un gestionnaire de signaux dédié...
signal(SIGILL, sigfatalHandler); // 4 SIGILL Instruction illégale
signal(SIGTRAP, sigfatalHandler); // 5 SIGTRAP Trace trap
signal(SIGABRT, sigfatalHandler); // 6 SIGABRT (ANSI) Instruction (ABORT)
signal(SIGBUS, sigfatalHandler); // 7 SIGBUS Bus error
signal(SIGFPE, sigfatalHandler); // 8 SIGFPE Floating-point exception - Exception arithmétique
signal(SIGSEGV, sigfatalHandler); // 11 SIGSEGV Violation de mémoire
signal(SIGSYS, sigfatalHandler); // 31 SIGSYS Erreur d'appel système
// Signaux moins violents, permettant un traitement après réception :
signal(SIGHUP, sigintHandler); // 1 SIGHUP Instruction (HANG UP) - Fin de session
signal(SIGINT, sigintHandler); // 2 SIGINT Interruption
signal(SIGQUIT, sigintHandler); // 3 SIGQUIT Instruction (QUIT) signal(SIGQUIT, sigintHandler); // 3 SIGQUIT Instruction (QUIT)
signal(SIGILL, sigintHandler); // 4 SIGILL Instruction illégale signal(SIGIOT, sigintHandler); // 6 SIGIOT (BSD) IOT Trap
signal(SIGTRAP, sigintHandler); // 5 SIGTRAP Trace trap signal(SIGKILL, sigintHandler); // 9 SIGKILL Instruction (KILL) - termine le processus immédiatement. En pratique, inutile car toujours intercepté par le noyau...
signal(SIGABRT, sigintHandler); // 6 SIGABRT (ANSI) Instruction (ABORT)
signal(SIGIOT, sigintHandler); // 6 SIGIOT (BSD) IOT Trap
signal(SIGBUS, sigintHandler); // 7 SIGBUS Bus error
signal(SIGFPE, sigintHandler); // 8 SIGFPE Floating-point exception - Exception arithmétique
signal(SIGKILL, sigintHandler); // 9 SIGKILL Instruction (KILL) - termine le processus immédiatement
signal(SIGUSR1, sigintHandler); // 10 SIGUSR1 Signal utilisateur 1 signal(SIGUSR1, sigintHandler); // 10 SIGUSR1 Signal utilisateur 1
signal(SIGSEGV, sigintHandler); // 11 SIGSEGV Violation de mémoire
signal(SIGUSR2, sigintHandler); // 12 SIGUSR2 Signal utilisateur 2 signal(SIGUSR2, sigintHandler); // 12 SIGUSR2 Signal utilisateur 2
signal(SIGPIPE, sigintHandler); // 13 SIGPIPE Broken PIPE - Erreur PIPE sans lecteur signal(SIGPIPE, sigintHandler); // 13 SIGPIPE Broken PIPE - Erreur PIPE sans lecteur
signal(SIGALRM, sigintHandler); // 14 SIGALRM Alarme horloge signal(SIGALRM, sigintHandler); // 14 SIGALRM Alarme horloge
signal(SIGTERM, sigintHandler); // 15 SIGTERM Signal de terminaison signal(SIGTERM, sigintHandler); // 15 SIGTERM Signal de terminaison
signal(SIGSTKFLT, sigintHandler); // 16 SIGSTKFLT Stack Fault signal(SIGSTKFLT, sigintHandler); // 16 SIGSTKFLT Stack Fault
signal(SIGCHLD, sigintHandler); // 17 SIGCHLD ou SIGCLD modification du statut d'un processus fils signal(SIGCHLD, sigintHandler); // 17 SIGCHLD ou SIGCLD modification du statut d'un processus fils
signal(SIGCLD, sigintHandler); // 17 SIGCHLD ou SIGCLD modification du statut d'un processus fils signal(SIGCLD, sigintHandler); // 17 SIGCHLD ou SIGCLD modification du statut d'un processus fils
signal(SIGCONT, sigintHandler); // 18 SIGCONT Demande de reprise du processus signal(SIGCONT, sigintHandler); // 18 SIGCONT Demande de reprise du processus
signal(SIGSTOP, sigintHandler); // 19 SIGSTOP Demande de suspension imbloquable signal(SIGSTOP, sigintHandler); // 19 SIGSTOP Demande de suspension imbloquable. En pratique, inutile car toujours intercepté par le noyau...
signal(SIGTSTP, sigintHandler); // 20 SIGTSTP Demande de suspension depuis le clavier signal(SIGTSTP, sigintHandler); // 20 SIGTSTP Demande de suspension depuis le clavier
signal(SIGTTIN, sigintHandler); // 21 SIGTTIN lecture terminal en arrière-plan signal(SIGTTIN, sigintHandler); // 21 SIGTTIN lecture terminal en arrière-plan
signal(SIGTTOU, sigintHandler); // 22 SIGTTOU écriture terminal en arrière-plan signal(SIGTTOU, sigintHandler); // 22 SIGTTOU écriture terminal en arrière-plan
signal(SIGURG, sigintHandler); // 23 SIGURG évènement urgent sur socket signal(SIGURG, sigintHandler); // 23 SIGURG évènement urgent sur socket
signal(SIGXCPU, sigintHandler); // 24 SIGXCPU temps maximum CPU écoulé signal(SIGXCPU, sigintHandler); // 24 SIGXCPU temps maximum CPU écoulé
signal(SIGXFSZ, sigintHandler); // 25 SIGXFSZ taille maximale de fichier atteinte signal(SIGXFSZ, sigintHandler); // 25 SIGXFSZ taille maximale de fichier atteinte
signal(SIGVTALRM, sigintHandler); // 26 SIGVTALRM alarme horloge virtuelle signal(SIGVTALRM, sigintHandler); // 26 SIGVTALRM alarme horloge virtuelle
signal(SIGPROF, sigintHandler); // 27 SIGPROF Profiling alarm clock signal(SIGPROF, sigintHandler); // 27 SIGPROF Profiling alarm clock
signal(SIGWINCH, sigintHandler); // 28 SIGWINCH changement de taille de fenêtre signal(SIGWINCH, sigintHandler); // 28 SIGWINCH changement de taille de fenêtre
signal(SIGPOLL, sigintHandler); // 29 SIGPOLL (System V) occurence d'un évènement attendu signal(SIGPOLL, sigintHandler); // 29 SIGPOLL (System V) occurence d'un évènement attendu
signal(SIGIO, sigintHandler); // 29 SIGIO (BSD) I/O possible actuellement signal(SIGIO, sigintHandler); // 29 SIGIO (BSD) I/O possible actuellement
signal(SIGPWR, sigintHandler); // 30 SIGPWR Power failure restart signal(SIGPWR, sigintHandler); // 30 SIGPWR Power failure restart
signal(SIGSYS, sigintHandler); // 31 SIGSYS Erreur d'appel système
return(0); return(0);
} }
@@ -375,7 +381,7 @@ int8_t init_signaux(void)
// Fonction : Handler unique de tous les signaux. Récupére la valeur du signal et met à jour la variable globale correspondante. // Fonction : Handler unique de tous les signaux. Récupére la valeur du signal et met à jour la variable globale correspondante.
// ATTENTION : il ne faut PAS faire de printf (ou équivalent) ici car il y a des restrictions dans les signals handlers. // ATTENTION : il ne faut PAS faire de printf (ou équivalent) ici car il y a des restrictions dans les signals handlers.
// En l'occurence, le traitement en fonction du numéro de signal est fait dans la fonction 'analyse_signal()' ci-dessus. // En l'occurence, le traitement en fonction du numéro de signal est fait dans la fonction 'analyse_signal()' ci-dessus.
// Reçoit : Rien // Reçoit : Signal reçu
// Retour : Rien // Retour : Rien
//================================================================================================================================================================== //==================================================================================================================================================================
void sigintHandler(int32_t signal) void sigintHandler(int32_t signal)
@@ -385,3 +391,27 @@ void sigintHandler(int32_t signal)
} }
//==================================================================================================================================================================
// Fonction : Handler des signaux d'erreur fatale. Dans ce cas, un 'return' n'est pas acceptable car il ne débouchera, au mieux, que sur la répétition de
// l'erreur sans traitement possible.
// Reçoit : Signal reçu
// Retour : Rien
//==================================================================================================================================================================
void sigfatalHandler(int32_t signal)
{
// Uniquement des fonctions "async-signal-safe" ici : pas de sprintf/printf classiques, pas de mutex, pas de malloc. write() sur un fd est sûr :
const char msg[] = "/!\\ Signal fatal recu (SIGSEGV/SIGBUS/SIGILL/SIGFPE) - Arret immediat....\n"; // Pas d'accents...
write(STDERR_FILENO, msg, sizeof(msg) - 1);
// Optionnel : capturer une pile d'appel avant de sortir (backtrace() est généralement sûr en pratique même si pas garanti strictement async-signal-safe) :
void *tab[20];
int n = backtrace(tab, 20);
char buf[64];
int len = sprintf(buf, "La fontion backtrace() a retourne %d frame(s) :\n", n); // Pas d'accents...
write(STDERR_FILENO, buf, len);
if (n > 0) backtrace_symbols_fd(tab, n, STDERR_FILENO);
_exit(1); // JAMAIS return ici, et de préférence _exit() plutôt que exit() qui appelle des handlers atexit/flush non signal-safe
}
+15 -9
View File
@@ -19,10 +19,11 @@
#include <alsa/mixer.h> #include <alsa/mixer.h>
#include <ctype.h> #include <ctype.h>
#include <dirent.h> #include <dirent.h>
#include <execinfo.h>
#include <fcntl.h> #include <fcntl.h>
#include <float.h> #include <float.h>
#include <gpiod.h> // Nécessaire pour E/S GPIO sur CM5
#include <ifaddrs.h> #include <ifaddrs.h>
#include <inttypes.h>
#include </usr/include/json-c/json.h> #include </usr/include/json-c/json.h>
#include <math.h> #include <math.h>
#include </usr/include/mariadb/mysql.h> #include </usr/include/mariadb/mysql.h>
@@ -44,6 +45,10 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#ifdef CIBLE_CM5
#include <gpiod.h> // Nécessaire pour E/S GPIO sur CM5
#endif
#include "audio.h" #include "audio.h"
#include "batteries.h" #include "batteries.h"
#include "bdd.h" #include "bdd.h"
@@ -73,7 +78,6 @@
#include "usb.h" #include "usb.h"
// ********************************************************************************************************************************************************************************** // **********************************************************************************************************************************************************************************
// Define : // Define :
// ********************************************************************************************************************************************************************************** // **********************************************************************************************************************************************************************************
@@ -82,8 +86,12 @@
#define OFF 0 #define OFF 0
#define ON 1 #define ON 1
#define FALSE 0 #ifndef FALSE
#define TRUE 1 #define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define HIGH 1 #define HIGH 1
#define LOW 0 #define LOW 0
@@ -1089,10 +1097,6 @@ struct Struct_module_physique
uint8_t maj_soft_disponible; // Indique si une mise à jour de logiciel a été chargée dans la carte et est disponible pour être activée. Utilisée dans le séquenceur 'gestion_chargement_carte()' (auparavant était stocké en BDD mais retiré en 02/2022) uint8_t maj_soft_disponible; // Indique si une mise à jour de logiciel a été chargée dans la carte et est disponible pour être activée. Utilisée dans le séquenceur 'gestion_chargement_carte()' (auparavant était stocké en BDD mais retiré en 02/2022)
}; };
struct Struct_fichier_download struct Struct_fichier_download
{ {
char nom[MAX_LONGUEUR_NOM_FICHIER]; char nom[MAX_LONGUEUR_NOM_FICHIER];
@@ -1101,6 +1105,7 @@ struct Struct_fichier_download
bool flag_a_telecharger; bool flag_a_telecharger;
bool flag_a_supprimer; bool flag_a_supprimer;
}; };
struct Struct_download struct Struct_download
{ {
char nom_repertoire_destination[MAX_LONGUEUR_NOM_REPERTOIRE_LOCAL]; // Nom du répertoire sur lequel le fichier sera uploadé char nom_repertoire_destination[MAX_LONGUEUR_NOM_REPERTOIRE_LOCAL]; // Nom du répertoire sur lequel le fichier sera uploadé
@@ -1194,7 +1199,8 @@ struct Struct_compute_module
uint8_t otp_reading_allowed; uint8_t otp_reading_allowed;
uint8_t warranty_bit; uint8_t warranty_bit;
uint8_t new_style_revision; uint8_t new_style_revision;
uint8_t memory_size; uint8_t ram_size;
uint64_t flash_size;
uint8_t manufacturer; uint8_t manufacturer;
uint8_t processor; uint8_t processor;
uint8_t type; uint8_t type;
+42 -56
View File
@@ -981,10 +981,44 @@ sudo iwlist wlan0 scan | grep -i 'Address:\|Channel:\|ESSID:\|Quality='
//==================================================================================================================================================================
// Fonction : Recherche une interface réseau donnée par son nom dans la liste chaînée retournée par 'getifaddrs()', et récupère son adresse IPV4 si elle est
// active (bit IFF_RUNNING positionné). Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP, équivalent de
// 'ifconfig') mais ne pas être physiquement connecté.
// Reçoit : La liste des interfaces (issue de 'getifaddrs()'), le nom de l'interface recherchée (ex : "eth0") et le pointeur destination pour l'adresse IP
// Renvoit : Rien. La destination n'est modifiée que si l'interface est trouvée, active, et possède une adresse IPV4.
//==================================================================================================================================================================
static void extraire_ip_interface(struct ifaddrs *addresses, const char *nom_interface, char *destination)
{
struct ifaddrs *address;
char chaine_ip[TAILLE_ADRESSE_IP];
const uint32_t family_size = sizeof(struct sockaddr_in);
for (address = addresses; address != NULL; address = address->ifa_next)
{
if (address->ifa_addr == NULL) continue; // Protection : certaines interfaces (virtuelles, tunnels...) n'ont pas d'adresse assignée
if (address->ifa_addr->sa_family != AF_INET) continue; // On ne traite que les IPV4 pour le moment...
if (strcmp(address->ifa_name, nom_interface) != 0) continue; // Ce n'est pas l'interface recherchée
if ((address->ifa_flags & IFF_RUNNING) == 0) continue; // Interface non physiquement connectée
getnameinfo(address->ifa_addr, family_size, chaine_ip, TAILLE_ADRESSE_IP_V4, 0, 0, NI_NUMERICHOST);
strcpy(destination, chaine_ip);
#ifdef __DEBUG_RESEAUX
{
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
sprintf(tmp, "Adresse IP sur l'interface '%s' = %s [IFF_RUNNING=Oui]", nom_interface, destination);
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
}
#endif
return; // Trouvée : inutile de continuer à parcourir la liste pour cette interface
}
}
//================================================================================================================================================================== //==================================================================================================================================================================
// Fonction : Récupère l'adresse IP en cours // Fonction : Récupère l'adresse IP en cours
// Cette fonction a été trouvée ici : https://subscription.packtpub.com/book/cloud-and-networking/9781789349863/1/ch01lvl1sec22/listing-network-adapters-from-c // Cette fonction a été trouvée ici : https://subscription.packtpub.com/book/cloud-and-networking/9781789349863/1/ch01lvl1sec22/listing-network-adapters-from-c
// dans la partie Unix. // dans la partie Unix, puis factorisée via 'extraire_ip_interface()' pour éviter la répétition du parcours de liste pour chaque interface.
// Par défaut, elle retourne quelque chose comme : // Par défaut, elle retourne quelque chose comme :
// lo IPv4 127.0.0.1 // lo IPv4 127.0.0.1
// eth0 IPv4 192.168.1.31 // eth0 IPv4 192.168.1.31
@@ -1004,11 +1038,8 @@ sudo iwlist wlan0 scan | grep -i 'Address:\|Channel:\|ESSID:\|Quality='
//================================================================================================================================================================== //==================================================================================================================================================================
int8_t get_ip_address(void) int8_t get_ip_address(void)
{ {
struct ifaddrs *addresses; struct ifaddrs *addresses;
struct ifaddrs *address; char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
char chaine_ip[TAILLE_ADRESSE_IP];
const uint32_t family_size = sizeof(struct sockaddr_in);
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// Recherche de la liste de toutes les interfaces disponibles : // Recherche de la liste de toutes les interfaces disponibles :
if (getifaddrs(&addresses) == -1) if (getifaddrs(&addresses) == -1)
@@ -1023,58 +1054,13 @@ int8_t get_ip_address(void)
strcpy(reseaux.wifi.sta.adresse_ip, ADRESSE_IP_INCONNUE); strcpy(reseaux.wifi.sta.adresse_ip, ADRESSE_IP_INCONNUE);
strcpy(reseaux.wifi.ap.adresse_ip, ADRESSE_IP_INCONNUE); strcpy(reseaux.wifi.ap.adresse_ip, ADRESSE_IP_INCONNUE);
// Boucle sur toutes les interfaces reçues : // Recherche de l'adresse IP de chacune des 3 interfaces suivies :
address = addresses; extraire_ip_interface(addresses, "eth0", reseaux.ethernet.adresse_ip);
while(address) extraire_ip_interface(addresses, "wlan0", reseaux.wifi.sta.adresse_ip);
{ extraire_ip_interface(addresses, "uap0", reseaux.wifi.ap.adresse_ip);
int family = address->ifa_addr->sa_family;
// if (family == AF_INET || family == AF_INET6) // AF_INET correspond à IPV4 et AF_INET6 correspond à IPV6
if (family == AF_INET) // On ne traite que les IPV4 pour le moment...
{
getnameinfo(address->ifa_addr, family_size, chaine_ip, TAILLE_ADRESSE_IP_V4, 0, 0, NI_NUMERICHOST); // Permet de récupérer la
if (strstr(address->ifa_name, "eth0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.ethernet.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP sur le réseau Ethernet du bord = %s [IFF_RUNNING=%s]", reseaux.ethernet.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else if (strstr(address->ifa_name, "wlan0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.wifi.sta.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP sur le réseau Wifi du bord (connecté en mode STA) = %s [IFF_RUNNING=%s]", reseaux.wifi.sta.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
else if (strstr(address->ifa_name, "uap0") != NULL)
{
if ((address->ifa_flags & IFF_RUNNING) != 0) strcpy(reseaux.wifi.ap.adresse_ip, chaine_ip); // Le test du bit 'IFF_RUNNING' est nécessaire car le port peut être UP (visible via IFF_UP équivalent de 'ifconfig') mais ne pas être physiquement connecté...
#ifdef __DEBUG_RESEAUX
sprintf(tmp, "Adresse IP de ShipBase sur le réseau Wifi ShipHeart (mode AP) = %s [IFF_RUNNING=%s]", reseaux.wifi.ap.adresse_ip, ((address->ifa_flags & IFF_RUNNING) == 0 ? "Non" : "Oui") );
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_PAR_DEFAUT);
#endif
}
/*
printf("%s\t", address->ifa_name);
printf("%s\t", family == AF_INET ? "IPv4" : "IPv6");
getnameinfo(address->ifa_addr, family_size, chaine_ip, TAILLE_ADRESSE_IP_V4, 0, 0, NI_NUMERICHOST);
printf("\t%s\n", chaine_ip);*/
}
address = address->ifa_next;
}
freeifaddrs(addresses); freeifaddrs(addresses);
return 0; return 0;
} }
+1 -1
View File
@@ -346,7 +346,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//-------------------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------------------
// Finalisation du message de débug : // Finalisation du message de débug :
strcat(tmp, ")\t: OK"); strcat(tmp, ")\t\t: OK");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK); affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);
return(0); return(0);
+13
View File
@@ -17,8 +17,11 @@ int16_t sortie_no(uint8_t type, uint8_t module, uint8_t no);
// Variables globales : // Variables globales :
struct Struct_sorties sorties; struct Struct_sorties sorties;
#ifdef CIBLE_CM5
struct gpiod_chip *gpiod_chip0_sorties; // Nécessaire pour CM5 struct gpiod_chip *gpiod_chip0_sorties; // Nécessaire pour CM5
struct gpiod_line_request *gpiod_sorties_request; // Nécessaire pour CM5 struct gpiod_line_request *gpiod_sorties_request; // Nécessaire pour CM5
#endif
/********************************************************************************************************************************************************************************** /**********************************************************************************************************************************************************************************
@@ -220,6 +223,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//==================================================================================================== //====================================================================================================
if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3) if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3)
{ {
#ifdef CIBLE_CM5
unsigned int offsets[MAX_NOMBRE_SORTIES_GPIO]; unsigned int offsets[MAX_NOMBRE_SORTIES_GPIO];
uint8_t nb_lignes = 0; uint8_t nb_lignes = 0;
@@ -266,6 +270,13 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
} }
return(0); // On sort ici : la boucle V1/V2 ci-dessous ne doit pas s'exécuter pour V3 return(0); // On sort ici : la boucle V1/V2 ci-dessous ne doit pas s'exécuter pour V3
#else // Ne devrait jamais arriver ... :
sprintf(tmp, "GENERATION_SHIPBASE_V3 incompatible avec cette plateforme de compilation.");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
return(-1);
#endif
} }
//==================================================================================================== //====================================================================================================
@@ -346,6 +357,7 @@ int8_t on;
else on = ON; else on = ON;
#ifdef CIBLE_CM5
//-------------------------------------------------------- //--------------------------------------------------------
// V3 : // V3 :
if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3) if (systeme.generation_shipbase == GENERATION_SHIPBASE_V3)
@@ -354,6 +366,7 @@ int8_t on;
gpiod_line_request_set_value(gpiod_sorties_request, no, val); gpiod_line_request_set_value(gpiod_sorties_request, no, val);
return; return;
} }
#endif
//-------------------------------------------------------- //--------------------------------------------------------
// V1 & V2 : // V1 & V2 :
+74 -7
View File
@@ -1597,7 +1597,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
// Désactivation des sorties de commandes d'alimentations : // Désactivation des sorties de commandes d'alimentations :
// ecriture_sortie(TYPE_SORTIE_GPIO, 0, CM3P_DO_USBPWR_EN, OFF); // Coupure de l'alim des USB /!\ Il ne faut PAS couper en mode debuug ous peine de ne plus avoir accès au réseau Ethernet via le routeur USB/Ethernet....! // ecriture_sortie(TYPE_SORTIE_GPIO, 0, CM3P_DO_USBPWR_EN, OFF); // Coupure de l'alim des USB /!\ Il ne faut PAS couper en mode debuug ous peine de ne plus avoir accès au réseau Ethernet via le routeur USB/Ethernet....!
// ecriture_sortie(TYPE_SORTIE_GPIO, 0, audio.cle_primaire_sortie_cm_do_audio_sd, OFF); // Coupure du circuit audio ecriture_sortie(TYPE_SORTIE_GPIO, 0, audio.sortie_gpio_cm_do_audio_sd, OFF); // 0 est l'adresse de ShipBase// Coupure du circuit audio (évite les glitch désagréable après un CTR+C)
// ecriture_sortie(TYPE_SORTIE_GPIO, 0, ecran.cle_primaire_sortie_cm_pdown_hdmi_cmd_n, OFF); // Coupure de la sortie du flux HDMI // ecriture_sortie(TYPE_SORTIE_GPIO, 0, ecran.cle_primaire_sortie_cm_pdown_hdmi_cmd_n, OFF); // Coupure de la sortie du flux HDMI
// ecriture_sortie(TYPE_SORTIE_GPIO, 0, ecran.cle_primaire_sortie_cm_do_lcd_en_vgx, OFF); // Coupure de l'alim VGx // ecriture_sortie(TYPE_SORTIE_GPIO, 0, ecran.cle_primaire_sortie_cm_do_lcd_en_vgx, OFF); // Coupure de l'alim VGx
@@ -1792,6 +1792,8 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
printf("\n"); printf("\n");
} }
json_object_put(parsed_json); // Libère l'objet JSON racine (et, par cascade, tous ses sous-objets/champs internes)
return(json_version); return(json_version);
} }
@@ -1887,13 +1889,25 @@ int8_t version_compute_module(void)
FILE *fp; FILE *fp;
char revcode[32]; char revcode[32];
uint32_t code; uint32_t code;
unsigned long long nb_secteurs;
unsigned long long taille_octets;
double taille_go_reelle;
char chaine_valeur[300]; char chaine_valeur[300];
char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG]; char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//========================================================================================================
// Lecture des données système et extraction des données :
//========================================================================================================
//---------------------------------------------------------------
fp = popen("cat /proc/cpuinfo | awk '/Revision/ {print $3}'", "r"); // récupération du code de Révision via la commande "cat /proc/cpuinfo | awk '/Revision/ {print $3}'". Exemple de retour : "c03141" fp = popen("cat /proc/cpuinfo | awk '/Revision/ {print $3}'", "r"); // récupération du code de Révision via la commande "cat /proc/cpuinfo | awk '/Revision/ {print $3}'". Exemple de retour : "c03141"
if (fp == NULL) return(-1); // Cas où la commande n'a pas pu être exécutée correctement if (fp == NULL)
{
affichage_debug(__FILE__, __LINE__, "/!\\ La lecture du fichier 'cpuinfo' est impossible...!", TYPE_MESSAGE_DEBUG_ERREUR);
return(-1);
}
fgets(revcode, sizeof(revcode), fp); // Lecture de la ligne fgets(revcode, sizeof(revcode), fp); // Lecture de la ligne
pclose(fp); // Fermeturre du fichier pclose(fp); // Fermeturre du fichier
@@ -1905,13 +1919,41 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
systeme.cm.otp_reading_allowed = (code >> 29) & 0x1; systeme.cm.otp_reading_allowed = (code >> 29) & 0x1;
systeme.cm.warranty_bit = (code >> 25) & 0x1; systeme.cm.warranty_bit = (code >> 25) & 0x1;
systeme.cm.new_style_revision = (code >> 23) & 0x1; systeme.cm.new_style_revision = (code >> 23) & 0x1;
systeme.cm.memory_size = (code >> 20) & 0x7; systeme.cm.ram_size = (code >> 20) & 0x7;
systeme.cm.manufacturer = (code >> 16) & 0x0F; systeme.cm.manufacturer = (code >> 16) & 0x0F;
systeme.cm.processor = (code >> 12) & 0x0F; systeme.cm.processor = (code >> 12) & 0x0F;
systeme.cm.type = (code >> 4) & 0xFF; systeme.cm.type = (code >> 4) & 0xFF;
systeme.cm.revision = (code >> 0) & 0x0F; systeme.cm.revision = (code >> 0) & 0x0F;
if (systeme.cm.new_style_revision == 0) // Ce bit indique le format du code de révision. Le 'new' type est actif depuis le RaspberryPi2 donc on devrait toujours être dans ce cas...
//---------------------------------------------------------------
fp = fopen("/sys/block/mmcblk0/size", "r");
if (fp == NULL)
{
affichage_debug(__FILE__, __LINE__, "/!\\ La lecture du fichier 'cpuinfo' est impossible...!", TYPE_MESSAGE_DEBUG_ERREUR);
return(-1);
}
if (fscanf(fp, "%llu", &nb_secteurs) != 1)
{
affichage_debug(__FILE__, __LINE__, "/!\\ La lecture du nombre de secteurs de flash est impossible...!", TYPE_MESSAGE_DEBUG_ERREUR);
return(-1);
}
fclose(fp);
taille_octets = nb_secteurs * 512ULL; // /sys/block/<dev>/size est toujours exprimé en secteurs de 512 octets, quelle que soit la taille physique du secteur
taille_go_reelle = (double)taille_octets / 1000000000.0; // Go décimaux (norme fabricants eMMC), pas Gio
systeme.cm.flash_size = taille_octets;
//========================================================================================================
// Traitement de l'affichage de debug et génération de la ligne 'Version_cm" de TB_Systeme :
//========================================================================================================
if (systeme.cm.new_style_revision == 0) // Ce bit indique le format du code de révision. Le 'new' type est actif depuis le RaspberryPi2 donc on devrait toujours être dans ce cas...
{ {
sprintf(tmp, "/!\\ Le bit de style de révision indique un ancien style de révision qui ne peut pas être lu...!"); sprintf(tmp, "/!\\ Le bit de style de révision indique un ancien style de révision qui ne peut pas être lu...!");
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR); affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_ERREUR);
@@ -1948,7 +1990,12 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
case 0x13 : { strcpy(chaine_valeur, "400"); break; } case 0x13 : { strcpy(chaine_valeur, "400"); break; }
case 0x14 : { strcpy(chaine_valeur, "CM4"); break; } case 0x14 : { strcpy(chaine_valeur, "CM4"); break; }
case 0x15 : { strcpy(chaine_valeur, "CM4S"); break; } case 0x15 : { strcpy(chaine_valeur, "CM4S"); break; }
case 0x16 : { strcpy(chaine_valeur, "Internal Use only"); break; }
case 0x17 : { strcpy(chaine_valeur, "5"); break; }
case 0x18 : { strcpy(chaine_valeur, "CM5"); break; } case 0x18 : { strcpy(chaine_valeur, "CM5"); break; }
case 0x19 : { strcpy(chaine_valeur, "500/500+"); break; }
case 0x1A : { strcpy(chaine_valeur, "CM5 Lite"); break; }
case 0x1B : { strcpy(chaine_valeur, "CM0"); break; }
case 0x07 : case 0x07 :
case 0x0B : case 0x0B :
@@ -1964,7 +2011,7 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
//--------------------------------------------------------------- //---------------------------------------------------------------
switch (systeme.cm.memory_size) switch (systeme.cm.ram_size)
{ {
case 0 : { strcpy(chaine_valeur, "256Mo"); break; } case 0 : { strcpy(chaine_valeur, "256Mo"); break; }
case 1 : { strcpy(chaine_valeur, "512Mo"); break; } case 1 : { strcpy(chaine_valeur, "512Mo"); break; }
@@ -1972,9 +2019,11 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
case 3 : { strcpy(chaine_valeur, "2Go"); break; } case 3 : { strcpy(chaine_valeur, "2Go"); break; }
case 4 : { strcpy(chaine_valeur, "4Go"); break; } case 4 : { strcpy(chaine_valeur, "4Go"); break; }
case 5 : { strcpy(chaine_valeur, "8Go"); break; } case 5 : { strcpy(chaine_valeur, "8Go"); break; }
case 6 : { strcpy(chaine_valeur, "16Go"); break; }
case 7 : { strcpy(chaine_valeur, ">16Go"); break; }
default : default :
{ {
sprintf(chaine_valeur, "Inconnue [code = %i]", systeme.cm.memory_size); sprintf(chaine_valeur, "Inconnue [code = %i]", systeme.cm.ram_size);
break; break;
} }
} }
@@ -1982,6 +2031,25 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
strcat(systeme.cm.chaine_version, "-"); strcat(systeme.cm.chaine_version, "-");
strcat(systeme.cm.chaine_version, chaine_valeur); strcat(systeme.cm.chaine_version, chaine_valeur);
strcat(systeme.cm.chaine_version, "[RAM]");
//---------------------------------------------------------------
// Arrondi à la taille commerciale la plus proche (la capacité réelle exposée est toujours < capacité nominale, à cause du sur-provisionnement)
if (taille_go_reelle <= 9.0) strcpy(chaine_valeur, "8Go");
else if (taille_go_reelle <= 18.0) strcpy(chaine_valeur, "16Go");
else if (taille_go_reelle <= 36.0) strcpy(chaine_valeur, "32Go");
else if (taille_go_reelle <= 72.0) strcpy(chaine_valeur, "64Go");
else if (taille_go_reelle <= 144.0) strcpy(chaine_valeur, "128Go");
else sprintf(chaine_valeur, "%.1fGo", taille_go_reelle);
affichage_ligne_version_compute_module(tmp, "Taille Flash", chaine_valeur);
strcat(systeme.cm.chaine_version, "-");
strcat(systeme.cm.chaine_version, chaine_valeur);
strcat(systeme.cm.chaine_version, "[FLASH]");
//--------------------------------------------------------------- //---------------------------------------------------------------
@@ -2064,7 +2132,6 @@ char tmp[MAX_LONGUEUR_BUFFER_TEMPORAIRE_DEBUG];
} }
affichage_ligne_version_compute_module(tmp, "Processeur", chaine_valeur); affichage_ligne_version_compute_module(tmp, "Processeur", chaine_valeur);
//--------------------------------------------------------------- //---------------------------------------------------------------
affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK); affichage_debug(__FILE__, __LINE__, tmp, TYPE_MESSAGE_DEBUG_OK);