3 votes

Comment exécuter un thread périodique en haute fréquence (> 100kHz) dans un microcontrôleur Cortex-M3 dans un RTOS ?

J'implémente un système d'acquisition de données haute fréquence (>100kHz) avec un microcontrôleur STM32F107VC. Il utilise le périphérique spi pour communiquer avec une puce ADC haute fréquence. Je dois utiliser un RTOS. Comment puis-je le faire ?

J'ai essayé FreeRTOS mais sa fréquence de tic maximum est de 1000Hz donc je ne peux pas lancer un thread par exemple toutes les 1us avec FreeRTOS. J'ai également essayé Keil RTX5 et sa fréquence de tic-tac peut aller jusqu'à 1MHz mais j'ai étudié quelque part qu'il n'est pas recommandé de fixer une fréquence de tic-tac élevée car cela augmente le temps global de commutation de contexte. Alors que dois-je faire ? Merci.

5voto

ElderBug Points 4334

Vous ne souhaitez pas exécuter une tâche à cette fréquence. Comme vous l'avez mentionné, les changements de contexte vont tuer les performances. C'est terriblement inefficace.

Au lieu de cela, vous voulez utiliser la mise en mémoire tampon, les interruptions et le DMA. Puisqu'il s'agit d'une puce ADC haute fréquence, elle dispose probablement d'un tampon interne qui lui est propre. Vérifiez la fiche technique à ce sujet. Si la puce possède un tampon de 16 échantillons, un échantillonnage de 100 kHz ne nécessitera qu'un traitement à 6,25 kHz. N'utilisez pas une tâche pour traiter les échantillons à 6,25 kHz. Faites la réception dans une interruption (timer ou un signal quelconque), et l'interruption devrait seulement remplir un tampon, et réveiller une tâche pour le traitement quand le tampon est plein (et passer à un autre tampon jusqu'à ce que la tâche soit terminée). Ainsi, vous pouvez avoir une tâche qui ne s'exécute que toutes les 10 ms environ. Une interruption n'est pas un changement de contexte. Sur un Cortex-M3, elle aura une latence d'environ 12 cycles, ce qui est suffisamment faible pour être négligeable à 6,25 kHz.
Si votre puce ADC n'a pas de tampon (mais j'en doute), vous pouvez vous contenter d'une interruption de 100 kHz, mais mettez le moins de code possible à l'intérieur.

Une meilleure solution est d'utiliser un DMA si votre MCU le supporte. Par exemple, vous pouvez configurer un DMA pour recevoir du SPI en utilisant un timer comme générateur de requête. Selon votre cas, cela peut être impossible ou délicat à configurer, mais un DMA fonctionnel signifie que vous pouvez recevoir un grand tampon d'échantillons sans qu'aucun code ne soit exécuté sur votre MCU.

3voto

berendi Points 3531

Je dois utiliser un RTOS.

Pas du tout. Si c'est une exigence de votre patron ou de votre client, fuyez rapidement le projet. Si ce n'est pas possible, faites part de vos préoccupations. par écrit maintenant pour sauver votre postérieur lorsque les raisons de l'échec seront discutées. Si c'est votre idée, alors reconsidérez-la maintenant.

La vitesse maximale de l'horloge système du STM32F107 est de 36 MHz (72 s'il y a un quartz HSE externe), ce qui signifie qu'il n'y a que 360 à 720 cycles d'horloge système entre les ticks venant à 100 kHz. L'avertissement de RTX5 est juste, une partie importante de ce temps serait nécessaire pour la commutation des tâches.

Il est possible d'avoir une interruption de timer à 100 kHz, et de faire quelques traitements simples dans le gestionnaire d'interruption ( ne pensez même pas à utiliser HAL ), mais je recommanderais d'examiner d'abord s'il est vraiment nécessaire d'exécuter du code toutes les 10 s, ou s'il est possible de décharger quelque chose qu'il ferait sur le matériel DMA ou timer.

2voto

Comme vous ne disposez que de quelques centaines de cycles (instructions) entre les entrées, la solution typique consiste à utiliser une interruption pour être averti que des données sont disponibles, puis le gestionnaire d'interruption place les données quelque part pour que vous puissiez les traiter à votre guise. Bien entendu, si les données arrivent en continu à ce rythme, vous risquez d'avoir des problèmes, car vous n'aurez pas le temps de les traiter. Selon la quantité de données qui arrivent et leur fréquence, un simple tampon rond peut suffire. Si la quantité de données est relativement importante (qu'entend-on par "importante" ? Considérez qu'il faut plus d'un cycle CPU pour effectuer un accès à la mémoire, et qu'il faut 2 accès à la mémoire pour chaque donnée entrante), alors l'utilisation du DMA comme @Elderbug l'a suggéré est une excellente solution car elle consomme le minimum de cycles CPU.

2voto

Clifford Points 29933

Il n'est pas nécessaire de régler le tic-tac du RTOS pour qu'il corresponde à la vitesse d'acquisition des données - les deux sont sans rapport. Et le faire serait une solution très pauvre et peu judicieuse.

Le STM32 possède une capacité DMA pour la plupart des périphériques, y compris SPI. Vous devez configurer le DMA et le SPI pour transférer une séquence d'échantillons directement en mémoire. Le contrôleur DMA a complet et moitié des interruptions de transfert, et peut faire tourner un tampon fourni de telle sorte que lorsqu'il est plein, il recommence depuis le début. Cela peut être utilisé pour "doubler le tampon" des blocs d'échantillons.

Par exemple, si vous utilisez un tampon DMA de 256 échantillons et que vous échantillonnez à 100Ksps, vous obtiendrez une interruption DMA toutes les 1,28ms. indépendant du RTOS tick interrupt et scheduling. Sur l'interruption de demi-transfert, les 128 premiers échantillons sont prêts à être traités, sur le transfert complet, les 128 seconds échantillons peuvent être traités, et dans l'intervalle de 1,28 ms, le processeur est libre de faire un travail utile.

Dans le gestionnaire d'interruption, plutôt que de traiter toutes les données du bloc dans le gestionnaire d'interruption - ce qui ne serait de toute façon pas possible si le traitement était non déterministe ou bloquant, comme l'écriture dans un système de fichiers - vous pourriez par exemple envoyer les échantillons en blocs via une file d'attente de messages à un contexte de tâches qui effectue le traitement moins déterministe.

Notez que rien de tout cela ne dépend du tic-tac du RTOS - le planificateur sera exécuté après tout si cette interruption appelle une fonction d'ordonnancement telle que l'enregistrement dans une file d'attente de messages. La synchronisation des actions à une horloge RTOS fonctionnant de manière asynchrone par rapport à l'événement déclencheur (c'est-à-dire l'interrogation) n'est pas un bon moyen d'obtenir une réponse en temps réel hautement déterministe et constitue une méthode particulièrement mauvaise pour l'acquisition de signaux, qui nécessite un intervalle d'échantillonnage sans gigue pour éviter les faux artefacts dans le signal provenant d'un échantillonnage apériodique.

Votre hypothèse selon laquelle vous devez résoudre ce problème par une fréquence de tic-tac du RTOS trop élevée est une mauvaise compréhension du fonctionnement du RTOS, et ne fonctionnera probablement que si votre processeur ne fait rien d'autre que d'échantillonner des données - dans ce cas, vous n'avez peut-être pas besoin du tout d'un RTOS, mais ce ne serait pas une utilisation très efficace du processeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X