jeudi 17 septembre 2009
Projet ADS-B: Problème de performance sur PIC18
Cela fait maintenant plusieurs soirées que je me bats pour tenter de faire tenir le code d'acquisition des trames dans un microcontrôleur.
Le problème est simple:
- L'acquisition du préambule nécessite d'échantillonner le signal au moins toutes les 500ns et ceci sur une durée de 8µs. La 'signature' de l'entête en hexadécimal est alors C100.
- L'acquisition du reste de la trame impose aussi d'échantillonner le signal à la même cadence bien que la durée d'un état soit de 1µs. Le codage utilisé impose en effet, si l'on veut travailler proprement, d'échantillonner une première fois puis de contrôler que l'état du signal a bien changé 500ns après. Et c'est ici que le bât blesse, du moins si l'on veut obtenir un code proprement structuré.
La lecture des données, hors le préambule , peut se faire par bloc de 8 bits, 7 dans le cas d'une trame courte, et 14 dans le cas d'une trame longue. Le tout premier bit de la trame indiquera si l'on est en présence d'une trame longue (112µs) ou courte (56µs). De ce bit dépendra donc le nombre d'itérations de la boucle d'acquisition.
Qui dit boucle, dit instructions de contrôle et instructions de stockage dans un tampon, et donc perte de quelques précieux cycles.
Avec un cycle d'échantillonnage à 500ns, il est hors de question de travailler sous interruption même avec les dernières générations de microprocesseurs. Si l'on prend un PIC18 cadencé à 48MHz facile à approvisionner, le cycle d'une instruction est de 83.33ns autorisant au plus 6 instructions pour acquérir et traiter un échantillon. Il me faut donc trouver une optimisation du code permettant:
- à t+000: d'acquérir le signal et de stocker son état dans un registre indexé ceci en tout au plus 6 cycles.
- à t+500: d'acquérir de nouveau de le signal, de vérifier qu'il s'est inversé, si ce n'est pas le cas, de repartir au debut du code, et si l'on est en fin de boucle, d'incrémenter l'index du registre de stockage, de tester le compteur et de repartir en début de boucle, ici encore en moins de 6 cycles.
Avec les instructions du PIC, cela 'passe' dans le cas du préambule mais pas pour le reste de la trame, les instructions de contrôle et de gestion du stockage venant tout perturber.
Sauf à considérer que je n'ai pas encore vu l'assemblage d'instructions qui me fera gagner les 3 cycles manquants sur les 2*6 cycles (acquisition et vérification), je n'ai plus guère d'options:
1- je fais sauter le contrôle de la transition d'état, ou je le reporte en fin de réception d'une trame complête,
2- je travaille de manière linéaire, sans boucle, mettant bout à bout 14 fois 8 blocs élémentaires de code, chaque bloc utilisant 12 instructions (1µs). Soit 1344 instructions, 14 fois plus qu'une programmation structurée,
3- je passe à la vitesse supérieure avec les dernières générations PIC18 à 16MIPS, soit un temps de 50ns par instruction au lieu des 83.33ns, m'offrant ainsi les 3 instructions manquantes,
4- je passe à l'ennemi en utilisant un micro-controlleur ATMEL autorisant un temps de cycle de 50ns et bien plus facile à approvisionner que les PIC18F1xK22,
5- Je passe encore à vitesse supérieure avec un FPGA, mais là il me faut tout apprendre ou presque, étant resté au PAL22V10...
L'option 3 me satisferait pleinement si MicroChip n'avait complexifié à l'extrême la procédure de commande d'échantillons, et même d'achat en direct, les références qui m'intéressent (PIC18F13K22 et PIC18F14K22 en PDIP), pourtant annoncées disponibles sur le site principal, n'étant pas livrables sur commande avant décembre.
Une bonne nouvelle toutefois, les AD8310 commandés chez Analog Devices sont arrivés. Le temps de faire un adaptateur SOIC vers DIP8, et je pourrais vérifier ce week end que ce modèle me permet d'obtenir de bien meilleurs fronts sur le signal.
Le problème est simple:
- L'acquisition du préambule nécessite d'échantillonner le signal au moins toutes les 500ns et ceci sur une durée de 8µs. La 'signature' de l'entête en hexadécimal est alors C100.
- L'acquisition du reste de la trame impose aussi d'échantillonner le signal à la même cadence bien que la durée d'un état soit de 1µs. Le codage utilisé impose en effet, si l'on veut travailler proprement, d'échantillonner une première fois puis de contrôler que l'état du signal a bien changé 500ns après. Et c'est ici que le bât blesse, du moins si l'on veut obtenir un code proprement structuré.
La lecture des données, hors le préambule , peut se faire par bloc de 8 bits, 7 dans le cas d'une trame courte, et 14 dans le cas d'une trame longue. Le tout premier bit de la trame indiquera si l'on est en présence d'une trame longue (112µs) ou courte (56µs). De ce bit dépendra donc le nombre d'itérations de la boucle d'acquisition.
Qui dit boucle, dit instructions de contrôle et instructions de stockage dans un tampon, et donc perte de quelques précieux cycles.
Avec un cycle d'échantillonnage à 500ns, il est hors de question de travailler sous interruption même avec les dernières générations de microprocesseurs. Si l'on prend un PIC18 cadencé à 48MHz facile à approvisionner, le cycle d'une instruction est de 83.33ns autorisant au plus 6 instructions pour acquérir et traiter un échantillon. Il me faut donc trouver une optimisation du code permettant:
- à t+000: d'acquérir le signal et de stocker son état dans un registre indexé ceci en tout au plus 6 cycles.
- à t+500: d'acquérir de nouveau de le signal, de vérifier qu'il s'est inversé, si ce n'est pas le cas, de repartir au debut du code, et si l'on est en fin de boucle, d'incrémenter l'index du registre de stockage, de tester le compteur et de repartir en début de boucle, ici encore en moins de 6 cycles.
Avec les instructions du PIC, cela 'passe' dans le cas du préambule mais pas pour le reste de la trame, les instructions de contrôle et de gestion du stockage venant tout perturber.
Sauf à considérer que je n'ai pas encore vu l'assemblage d'instructions qui me fera gagner les 3 cycles manquants sur les 2*6 cycles (acquisition et vérification), je n'ai plus guère d'options:
1- je fais sauter le contrôle de la transition d'état, ou je le reporte en fin de réception d'une trame complête,
2- je travaille de manière linéaire, sans boucle, mettant bout à bout 14 fois 8 blocs élémentaires de code, chaque bloc utilisant 12 instructions (1µs). Soit 1344 instructions, 14 fois plus qu'une programmation structurée,
3- je passe à la vitesse supérieure avec les dernières générations PIC18 à 16MIPS, soit un temps de 50ns par instruction au lieu des 83.33ns, m'offrant ainsi les 3 instructions manquantes,
4- je passe à l'ennemi en utilisant un micro-controlleur ATMEL autorisant un temps de cycle de 50ns et bien plus facile à approvisionner que les PIC18F1xK22,
5- Je passe encore à vitesse supérieure avec un FPGA, mais là il me faut tout apprendre ou presque, étant resté au PAL22V10...
L'option 3 me satisferait pleinement si MicroChip n'avait complexifié à l'extrême la procédure de commande d'échantillons, et même d'achat en direct, les références qui m'intéressent (PIC18F13K22 et PIC18F14K22 en PDIP), pourtant annoncées disponibles sur le site principal, n'étant pas livrables sur commande avant décembre.
Une bonne nouvelle toutefois, les AD8310 commandés chez Analog Devices sont arrivés. Le temps de faire un adaptateur SOIC vers DIP8, et je pourrais vérifier ce week end que ce modèle me permet d'obtenir de bien meilleurs fronts sur le signal.
Libellés :
ADS-B,
ADS-B Decoder
Inscription à :
Publier les commentaires (Atom)
Aucun commentaire:
Enregistrer un commentaire