Salut,
J'utilise la même méthode que toi pour piloter un appareil de notre conception.
Il se trouve qu'il existe une centaine de commande chez nous. Chaque commande est représenté par une chaine de caractères et possède possède 0 ou 1 ou plusieurs paramètre.
Après avoir beaucoup bossé sur le sujet j'ai trouvé que la méthode la plus élégante pour gérer le truc est la suivante:
Commence par créer la liste exhaustive des commandes par un type énumérée:
1 2 3 4 5 6 7 8
| /* Enumere les commandes de mon systeme*/
typedef enum
{
CMD_NULL = 0,
CMD_BOOTSECTOR,
/* */
N_CMDS
}cmd_e; |
Définit une structure commande et une structure liste de commande
1 2 3 4 5 6 7 8 9 10 11
| /* une commande est représentée uniquement par une chaine de caractère*/
typedef struct
{
const char * frmt; /**the ASCII string that defines de the command*/
size_t len; /**the length ASCII string that defines de the command*/
}cmd_t;
/* la liste des commandes du system*/
typedef struct
{
cmd_t cmd[N_CMDS]; /** the commands are listed in a table*/
}cmd_list_t; |
Définit ta règle de gestion de paramètres
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| /**
*\return True quand un commande contient 1 ou plusieurs paramètres
*/
static inline bool cmd_has_args(const cmd_t * const this)
{ /* cmd has args when it ends with a space character */
return (this->frmt[this->len-1] == ' ');
}
/**
*\return un pointer sur le premier caractère des paramètres de la commande,
* NULL si la commande n'a pas de paramètres
*/
static inline const char * cmd_get_args(const cmd_t * const this,const char * buff)
{ /* return the char after ' ', else NULL*/
return cmd_has_args(this)?&buff[this->len-1]:NULL;
} |
Définit une méthode pour créer a liste des commandes au démarrage du système
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| /**
*\return La chaine de caractère qui représente la commande
*/
static const char * cmd2str(const cmd_e cmd)
{
switch(cmd)
{
case CMD_NULL : return "\r\n";break;
case CMD_BOOTSECTOR : return "boot_sector ";break;
default :
{
printf("WARNING: Debug Command %"PRIu32" has no format\n",(uint32_t)cmd);
return "";
}
}/* end switch*/
}/*end cmd2str*/
/**
*\return this
*/
cmd_list_t * init_cmd_list(cmd_list_t * const this)
{
if(this)
{
for(cmd_e i = 0 ; i < N_CMDS ; i++)
{
this->cmd[i].frmt = cmd2str(i);
this->cmd[i].len = strlen(this->cmd[i].frmt);
}
}
return this;
} |
Il reste a implémenter une méthode qui recherche une ou des commandes dans une chaine de caractère et l'exécute sur le système
size_t search_and_exe_cmd(my_System_t * const this,const char * const asciiCmds, const size_t asciiCmdsLen)
Le but de cette organisation est de de pouvoir la liste des actions a effectuer pour chaque commande dans un switch case:
1 2 3 4 5 6 7 8 9 10
| static void system_cmd_execute(mySystem_t * const this,const cmd_e cmd,const char * const args)
{
/* execute te appropriate cmd*/
switch(cmd)
{
case CMD_NULL : printf("\r\nCOUCOU\n");break;
case CMD_BOOTSECTOR : changer_secteur de boot(this,strtol(args,(char **)NULL,10))break;
default : printf("\r\nUNKONWN!!\n");
}
} |
Partager