#include "Log.h" #include "string.h" #include #include struct log_message_storage{ struct Log_message_data message; struct log_message_storage * next; } * log_message_envoi, log_message_storage_premier, *log_message_storage_courant; uint log_error = 0; enum Log_level log_level_reference; 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_envoi = &log_message_storage_premier; log_level_reference = TELEPLOT; } /// @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){ // On vérifie que le message a une urgence suffisante pour être enregistrée if(log_level >= log_level_reference){ /// Création de la structure de données struct Log_message_data message_container; if(strlen(message) > LOG_MAX_MESSAGE_SIZE){ strcpy(message_container.message, "MSG TOO LONG"); }else{ strcpy(message_container.message, message); } message_container.log_level = log_level; message_container.timestamp = time_us_32() / 1000; /// Insertion de la structure dans la liste chaînée struct log_message_storage* tmp_message_storage; tmp_message_storage = (struct log_message_storage*) malloc(sizeof(struct log_message_storage)); if(tmp_message_storage != NULL){ tmp_message_storage->message = message_container; tmp_message_storage->next = NULL; log_message_storage_courant->next = tmp_message_storage; log_message_storage_courant = log_message_storage_courant->next; }else{ log_error |= LOG_ERROR_MEMORY_FULL; } } } /// @brief Read messages in cache, store them and send them through the serial connection void Log_gestion(){ // Envoi 1 message par la liaison série if(log_message_envoi->next != NULL){ log_message_envoi = log_message_envoi->next; envoi_message(log_message_envoi->message); // Si on est à la fin des messages, en envoie le statut de la fonction Log if(log_message_envoi->next == NULL){ if(log_error & LOG_ERROR_MEMORY_FULL){ printf("LOG ERROR : Memoire pleine !\n"); } } } } /// @brief Renvoie l'intégralité du journal de log. La fonction Log_gestion() doit être appelée continuellement pour que cette fonction fonctionne. void Log_get_full_log(){ log_message_envoi = &log_message_storage_premier; } void envoi_message(struct Log_message_data message_data){ if(message_data.log_level == TELEPLOT){ printf("%s\n", message_data.message); }else{ printf("%u ms:%s\n", message_data.timestamp, message_data.message); } }