Comment puis-je créer une table de recherche dans un microcontrôleur en utilisant C? Jai une entrée et une sortie et je veux implémenter une table de recherche en C.
Réponse
Je vais donner un général réponse car la question manque dinformations:
Supposons que vous ayez un uint8_t
en entrée et un uint8_t
en sortie et vous voulez créer une table de recherche complète (cest-à-dire que chaque entrée a une sortie). Vous avez besoin de 256 valeurs, car lentrée peut avoir 256 valeurs différentes. Vous pouvez maintenant créer une table avec:
const uint8_t the_table[256] = { ... }
Le mot-clé const
est de stocker la table dans la mémoire flash , pas dans la RAM. Cest parce que la RAM est rare dans les microcontrôleurs, comme le souligne jippie dans les commentaires.
Dans les accolades, les valeurs devraient aller. Vous pouvez maintenant rechercher facilement une valeur dentrée avec the_table[input_value]
.
En général, nous pourrions dire quune table de recherche ressemblerait à ceci:
const OutputType the_table[CountOfInputValues] = { ... };
Un petit exemple de table de recherche pour effectuer cette conversion (à partir du code Gray , merci à Anindo Ghosh ):
input -> output 0b000 0b000 0b001 0b001 0b010 0b011 0b011 0b010 0b100 0b110 0b101 0b111 0b110 0b101 0b111 0b100
Peut être implémenté comme suit, en utilisant uint8_t
, ou un octet, comme type de sortie:
const uint8_t gray_code[8] = {0b000, 0b001, 0b011, 0b010, 0b110, 0b111, 0b101, 0b100};
Vous pouvez rechercher une valeur avec:
some_var = gray_code[input];
Commentaires
Réponse
Voici un exemple de la façon dont je créerais une table de recherche pour certaines valeurs précalculées. Jutiliserai un exemple de permutation de bits davant en arrière dans un octet. est parfois utile pour les algorithmes FFT ou les périphériques SPI qui veulent le mauvais ordre.
Tout dabord, je crée un programme qui crée la table. La maintenance de la table à la main est une corvée et sujette aux erreurs, donc ce travail devrait être confié à lordinateur.
#!/usr/bin/python def swapbits(x): ret=0 for i in range(8): if x&(1<<i): ret |= 1<<(7-i) return ret print "const uint8_t bitswap[] = {", print ", ".join("0x%02x"%swapbits(x) for x in range(256)), print "}"
Jappelle ce fichier « bitend.py ». Remarquez que jai utilisé un langage de script au lieu dun programme C pour cela. Générer le tableau est fondamentalement un problème de traitement de chaînes, et C est une douleur à traiter. Parce que la table nest nécessaire quau moment de la compilation, je peux utiliser un algorithme simple dhomme des cavernes qui est plus évidemment correct t quun optimisé.
Maintenant, pour intégrer ceci dans la construction. Dans mon Makefile, jai mis une section comme celle-ci:
generated_swapbits.c: bitend.py echo "/* generated by bitend.py, do not edit */" > generated_swapbits.c python bitend.py >> generated_swapbits.c
Ici, jai fait une dépendance sur le script python, de sorte que si jédite le script, le C fichier sera régénéré automatiquement.
Dans mon code C principal, jinclus juste le fichier généré:
#include <stdio.h> #include "generated_swapbits.c" int main(void) { printf("Swapped 0x0f is %0x\n", swapbits[0x0f]); }
Maintenant dans mon Makefile, Je dois inclure le fichier généré en tant que dépendance du code C:
a.out: main.c generated_swapbits.c $(CC) $(CFLAGS) main.c
Et la dernière chose est dajouter « generated_swapbits.c » au Makefile » s cible « clean », donc le fichier sera supprimé lors de « make clean ».
Si vous utilisez un IDE au lieu de make, vous devrez consulter sa documentation sur lexécution de scripts pour satisfaire les dépendances. (Si lEDI ne prend pas en charge cela, choisissez un autre IDE.)
uint32_t gray( uint32_t number ) { return number ^= ( number >> 1 ); }
Don ' Jai besoin dun tableau pour cela.EOR Rn,Rn,Rn,LSR 1
, aucune table de recherche ne peut battre cela.