diff --git a/CMakeLists.txt b/CMakeLists.txt index 8b5c4b0..c10d2e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ gyro_ADXRS453.c i2c_maitre.c i2c_annexe.c Localisation.c +Log.c Moteurs.c Monitoring.c Robot_config.c @@ -34,6 +35,7 @@ Strategie_prise_cerises.c Strategie_pousse_gateau.c Temps.c Test.c +Test_log.c Test_strategie.c Trajet.c Trajectoire.c diff --git a/Holonome2023.c b/Holonome2023.c index f2795ce..151766a 100644 --- a/Holonome2023.c +++ b/Holonome2023.c @@ -41,6 +41,12 @@ uint temps_cycle; int mode_test(); +void init_led(uint Numero_de_la_led, uint etat){ + gpio_init(Numero_de_la_led); + gpio_set_dir(Numero_de_la_led, GPIO_OUT); + gpio_put(Numero_de_la_led, etat); +} + int main() { bi_decl(bi_program_description("This is a test binary.")); bi_decl(bi_1pin_with_name(LED_PIN, "On-board LED")); @@ -54,13 +60,8 @@ int main() { stdio_init_all(); - gpio_init(LED_PIN); - gpio_set_dir(LED_PIN, GPIO_OUT); - gpio_put(LED_PIN, 1); - - gpio_init(LED_PIN_ROUGE); - gpio_set_dir(LED_PIN_ROUGE, GPIO_OUT); - gpio_put(LED_PIN_ROUGE, 0); + init_led(LED_PIN, 1); + init_led(LED_PIN_ROUGE, 0); gpio_init(COULEUR); gpio_init(TIRETTE); @@ -85,7 +86,7 @@ int main() { AsserMoteur_Init(); Localisation_init(); - //while(mode_test()); + while(mode_test()); i2c_maitre_init(); Trajet_init(); Balise_VL53L1X_init(); @@ -161,7 +162,7 @@ int main() { break; case MATCH_EN_COURS: - if (timer_match_ms > 98000){ + if (timer_match_ms > 98000){ // 98 secondes printf("MATCH_ARRET_EN_COURS\n"); statu_match = MATCH_ARRET_EN_COURS; } @@ -176,7 +177,7 @@ int main() { Score_set_pieds_dans_plat(); } - if (timer_match_ms > 100000){ + if (timer_match_ms > 100000){ // 100 secondes statu_match = MATCH_TERMINEE; } diff --git a/Log.c b/Log.c new file mode 100644 index 0000000..77773f3 --- /dev/null +++ b/Log.c @@ -0,0 +1,98 @@ +#include "Log.h" +#include "string.h" +#include +#include + +#define LOG_CACHE_SIZE 10 + +struct log_message_storage{ + struct Log_message_data message; + struct log_message_storage * next; +} * log_message_storage_envoi, log_message_storage_premier, *log_message_storage_courant; + +struct Log_message_data log_cache[LOG_CACHE_SIZE]; +uint log_cache_index_entry = 0; +uint log_cache_index_stored = 0; +uint log_error = 0; + +void increment_cache_index(uint * index); +int store_new_message(struct Log_message_data message, struct log_message_storage * stockage); +void envoi_message(struct Log_message_data message); + +void Log_init(void){ + log_message_storage_premier.message.log_level = INFO; + strcpy(log_message_storage_premier.message.message,"Debut du programme"); + log_message_storage_premier.message.timestamp = time_us_32() / 1000; + log_message_storage_premier.next = NULL; + + log_message_storage_courant = &log_message_storage_premier; + log_message_storage_envoi = &log_message_storage_premier; + +} + + +/// @brief Add one log message to local cache. Should be quick +/// @param message : string, without '\n' at the end. +/// @param log_level : can be in TELEPLOT, TRACE, DEBUG, INFO, WARN, ERROR, FATAL +void Log_message(char * message, enum Log_level log_level){ + uint temps0, temps1; + temps0 = time_us_32(); + if(strlen(message) > LOG_MAX_MESSAGE_SIZE){ + strcpy(log_cache[log_cache_index_entry].message, "MSG TOO LONG"); + }else{ + strcpy(log_cache[log_cache_index_entry].message, message); + } + log_cache[log_cache_index_entry].log_level = log_level; + log_cache[log_cache_index_entry].timestamp = time_us_32() / 1000; + + increment_cache_index(&log_cache_index_entry); + temps1 = time_us_32(); + + printf("temps tableau : %u us\n", temps1 - temps0); + + // Cache overflow - est-ce pertinent ? Ne faudrait-il pas réaliser ce test avant d'incrémenter cache_index_entry ? + /*if(log_cache_index_entry == log_cache_index_stored){ + log_error |= LOG_ERROR_CACHE_OVERFLOW; + }*/ +} + +/// @brief Read messages in cache, store them and send them through the serial connection +void Log_gestion(){ + // Store all message from the cache + + while(log_cache_index_entry != log_cache_index_stored){ + store_new_message(log_cache[log_cache_index_stored], log_message_storage_courant); + increment_cache_index(&log_cache_index_stored); + log_message_storage_courant = log_message_storage_courant->next; + } + + // Envoi 1 message par la liaison série + + if(log_message_storage_envoi->next != NULL){ + log_message_storage_envoi = log_message_storage_envoi->next; + envoi_message(log_message_storage_envoi->message); + } +} + +void increment_cache_index(uint * index){ + *index = *index +1; + if(*index >= LOG_CACHE_SIZE){ + *index = 0; + } +} + +/// @brief Alloue l'espace pour stocker un nouveau message +/// @return 0 en cas de succès, 1 si la mémoire est pleine +int store_new_message(struct Log_message_data message, struct log_message_storage * stockage){ + stockage->next = (struct log_message_storage*) malloc(sizeof(struct log_message_storage)); + if(stockage->next != NULL){ + stockage->next->message = message; + stockage->next->next = NULL; + return 0; + } + return 1; +} + +void envoi_message(struct Log_message_data message){ + printf("%u ms:%s\n", message.timestamp, message.message); +} diff --git a/Log.h b/Log.h new file mode 100644 index 0000000..303bdc3 --- /dev/null +++ b/Log.h @@ -0,0 +1,20 @@ +#include "pico/stdlib.h" + +#define LOG_MAX_MESSAGE_SIZE 64 + +#define LOG_ERROR_MEMORY_FULL 1 +#define LOG_ERROR_CACHE_OVERFLOW 2 + +enum Log_level{ + TELEPLOT, TRACE, DEBUG, INFO, WARN, ERROR, FATAL +}; + +struct Log_message_data{ + char message[LOG_MAX_MESSAGE_SIZE]; + enum Log_level log_level; + uint32_t timestamp; +}; + +void Log_init(void); +void Log_gestion(void); +void Log_message(char * message, enum Log_level log_level); \ No newline at end of file diff --git a/Test.c b/Test.c index fce97bf..50d74cb 100644 --- a/Test.c +++ b/Test.c @@ -28,6 +28,7 @@ #include "Trajectoire.h" #include "Trajet.h" +#include "Test_log.h" #include "Test_strategie.h" #include "Test.h" @@ -86,6 +87,7 @@ int mode_test(){ printf("O - Analyse obstacle\n"); printf("P - Asser Position - perturbation\n"); printf("Q - Asser Position - transition Gyro -> Pas gyro\n"); + printf("R - Test des logs\n"); printf("T - Trajectoire\n"); printf("U - Scan du bus i2c\n"); printf("V - APDS_9960\n"); @@ -181,6 +183,11 @@ int mode_test(){ case 'q': while(test_transition_gyro_pas_gyro()); break; + + case 'R': + case 'r': + while(test_log()); + break; case 'T': case 't': diff --git a/Test_log.c b/Test_log.c new file mode 100644 index 0000000..45207b4 --- /dev/null +++ b/Test_log.c @@ -0,0 +1,73 @@ +#include "Log.h" +#include "pico/multicore.h" +#include + +#define TEST_TIMEOUT_US 10000000 + +void log_core1_routine(){ + while(1){ + Log_gestion(); + } +} + + +/// @brief Fonction pour testes les fonctions Log +/// @param +/// @return 1 si la doit être ré-appelée, 0 si l'utilisateur quitte. +int test_log(void){ + int lettre; + char message[50]; + + Log_init(); + + multicore_launch_core1(log_core1_routine); + + while(1){ + + do{ + printf("A : 1 message\n"); + printf("B : 9 messages d'affilés\n"); + printf("C : 100 messages à 100 µs d'intervalle\n"); + printf("Q : Quitter\n"); + lettre = getchar_timeout_us(TEST_TIMEOUT_US); + stdio_flush(); + }while(lettre == PICO_ERROR_TIMEOUT ||lettre == 0); + + + + switch(lettre){ + case 'A': + case 'a': + printf("A : 1 message\n"); + Log_message("Test 1 message", DEBUG); + break; + + case 'B': + case 'b': + printf("B : 9 messages d'affilés\n"); + for(int i=0; i<9; i++){ + sprintf(message, "Test message %d/9", i); + Log_message(message, DEBUG); + } + break; + + case 'C': + case 'c': + printf("C : 100 messages à 100 µs d'intervalle\n"); + for(int i=0; i<100; i++){ + sprintf(message, "Test message %d/100", i); + Log_message(message, DEBUG); + sleep_us(100); + } + break; + + case 'Q': + case 'q': + printf("Q : Quitter\n"); + multicore_reset_core1(); + return 0; + break; + } + } +} + diff --git a/Test_log.h b/Test_log.h new file mode 100644 index 0000000..d8aff7b --- /dev/null +++ b/Test_log.h @@ -0,0 +1 @@ +int test_log(void); \ No newline at end of file diff --git a/gyro.c b/gyro.c index 659f7c0..6759c1b 100644 --- a/gyro.c +++ b/gyro.c @@ -77,6 +77,7 @@ void Gyro_Init(void){ Monitoring_Error("Gyroscope non trouve"); while(1){ puts("Gyroscope non trouve"); + sleep_ms(500); }; // On s'arrête là ! }else{ //puts("Gyroscope trouve"); @@ -86,6 +87,7 @@ void Gyro_Init(void){ Monitoring_Error("gyro_config FAILED !"); while(1){ puts("gyro_config FAILED !"); + sleep_ms(500); }; // On s'arrête là ! }