RPiPico-Holonome2023/Log.c

99 lines
3.4 KiB
C

#include "Log.h"
#include "string.h"
#include <stdio.h>
#include <stdlib.h>
#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);
}