Mod_Communication/messagerie_applicative.c

131 lines
4.1 KiB
C

#include <string.h>
#include "messagerie_applicative.h"
#define TAILLE_MEMOIRE_ECHANGE 0xFF
#define NB_BANK 10
//uint8_t mémoire_échange[NB_BANK][TAILLE_MEMOIRE_ECHANGE];
/// @brief Meta-données de la mémoire
/// modifications: un bit par octet pour indiquer si la donnée a été modifiée.
struct bank_mémoire_t{
uint8_t mémoire_id;
uint8_t mémoire_échange[TAILLE_MEMOIRE_ECHANGE];
uint32_t modifications[4];
} list_memoire_echange[NB_BANK];
bool mise_a_jour_position = false;
bool mise_a_jour_mode = false;
bool mise_a_jour_pwm = false;
bool mise_a_jour_vitesse_roues = false;
bool mise_a_jour_vitesse_robot = false;
bool mise_a_jour_trajectoire = false;
bool mise_a_jour_config_trajet = false;
bool mise_a_jour_cde_inv_traj = false;
void message_applicatif_init(){
for(uint8_t i=0; i<NB_BANK; i++){
list_memoire_echange[i].mémoire_id = 0;
}
}
struct bank_mémoire_t * assigner_bank_mémoire(uint8_t bank_id){
for(uint8_t i=0; i<NB_BANK; i++){
if(list_memoire_echange[i].mémoire_id == 0){
list_memoire_echange[i].mémoire_id = bank_id;
return &(list_memoire_echange[i]);
}
}
return NULL;
}
/// @brief Renvoi la banque mémoire avec l'identifiant bank_id.
/// Si aucune banque ne correspond, la fonction trouve une banque vide et
/// lui assigne l'identifiant. Si toutes les banques sont prises, renvoie NULL
/// @param bank_id identifiant de la banque
struct bank_mémoire_t * get_bank_mémoire(uint8_t bank_id){
for (uint8_t i = 0; i< NB_BANK ; i++){
if(list_memoire_echange[i].mémoire_id == bank_id){
return &(list_memoire_echange[i]);
}
}
return assigner_bank_mémoire(bank_id);
}
uint8_t * get_mémoire_modifiée(uint8_t bank_id, uint8_t registre){
struct bank_mémoire_t * bank_memoire;
bank_memoire = get_bank_mémoire(bank_id);
if(bank_memoire == NULL){
return false;
}
if(bank_memoire->modifications[registre / 32] & (1 << (registre % 32))){
return &(bank_memoire->mémoire_échange[registre]);
}
return false;
}
void set_mémoire_modifiée(struct bank_mémoire_t * bank_memoire, uint8_t registre){
bank_memoire->modifications[registre / 32] |= 1 << registre % 32;
}
void reset_mémoire_modifiée(struct bank_mémoire_t * bank_memoire, uint8_t registre){
for(int i=0; i< 4; i++){
bank_memoire->modifications[1] = 0;
}
}
uint8_t * get_memoire_echange(uint8_t bank_id){
struct bank_mémoire_t * bank = get_bank_mémoire(bank_id);
if (bank){
return bank->mémoire_échange;
}
return NULL;
}
uint8_t * get_données_reçues(uint8_t registre, uint8_t bank_id){
uint8_t * ma_memoire_echange = get_memoire_echange(bank_id);
if(ma_memoire_echange)
return &(ma_memoire_echange[registre]);
return NULL;
}
void mise_données_dans_échange(uint8_t * source, uint8_t taille, uint8_t registre, uint8_t bank_id){
uint8_t * ma_memoire_echange = get_memoire_echange(bank_id);
if(ma_memoire_echange)
memcpy(&(ma_memoire_echange[registre]), source, taille);
}
/// @brief Copie le message dans la mémoire d'échange
/// @param message_applicatif message reçu
void réception_données(struct message_applicatif_t message_applicatif){
struct bank_mémoire_t * bank_memoire = get_bank_mémoire(message_applicatif.id_carte);
uint8_t * ma_memoire_echange = bank_memoire->mémoire_échange;
for (int num_octet=0; num_octet<message_applicatif.taille_donnees; num_octet++){
uint32_t adresse = num_octet + message_applicatif.adresse_registre;
if(bank_memoire != NULL){
if(adresse < TAILLE_MEMOIRE_ECHANGE){
ma_memoire_echange[adresse] = message_applicatif.donnees_applicative.donnees[num_octet];
set_mémoire_modifiée(bank_memoire, adresse);
}
}
}
}
/// @brief Appelle la fonction callback si la mémoire d'échange au registre en question a été modifiée.
/// Dans ce cas l'adresse du registre est envoyée à la fonction callback
/// @param id_carte Adresse de la bank / carte_id
/// @param registre Registre écrit
/// @param callback Fonction à appeler.
void messagerie_applicative_callback(uint8_t id_carte, uint8_t registre, void (*callback) (uint8_t *)){
uint8_t * mémoire = get_mémoire_modifiée(id_carte, registre);
if(mémoire){
(*callback)(mémoire);
}
}