7
votes

Multithreading en utilisant c sur pic18

Comment créer des threads qui se déroulent en parallèle lors de la programmation PIC18 , puisque là n'est pas un système d'exploitation?


4 commentaires

Quel compilateur utilisez-vous? Certains ont des caractéristiques à cette fin.


Un contexte d'exécution séparé est possible sans OS, en utilisant des tours comme des interruptions de minuterie ou d'autres interruptions basées sur des événements, mais threads : non possible sans OS.


Vous utilisez une faible empreinte de pas.


Cette question est vraiment ouverte.


13 Réponses :


6
votes

Vous pouvez mettre un RTO là-bas (il y a Un port UCOS non officiel , ou vous pouvez consulter PORT PIC18 de Freertos ).

Sinon, vous pouvez essayer d'implémenter Coroutines en C en utilisant SetJMP et longjmp .


0 commentaires

9
votes

Vous pouvez essayer multitâche coopérative .

Pour les types de problèmes que les photos résolvent, vous seriez probablement mieux si vous essayez une conception différente qui utilise des interruptions ou des interrogations au lieu de plusieurs threads.


1 commentaires

FYI, je viens de poster un certain code pour illustrer la simplicité de multitâche coopérative. Je ne l'ai pas fait sur la PIC18, mais je l'ai fait sur le 8051 et sur une plate-forme TI DSP.



5
votes

S'il n'y a pas de système d'exploitation du tout, vous devez (évidemment) de recréer vous-même les fonctionnalités nécessaires.

Le moyen le plus simple de suivre serait probablement d'installer une interruption de la minuterie fonctionnant à une fréquence appropriée (dépend probablement de votre vitesse d'horloge actuelle, mais peut-être dans la plage 100-1000 Hz). Dans le gestionnaire d'interruptions, vous devez inspecter l'état du fil de courant et décider si un commutateur devrait se produire.

L'astuce consiste alors à faire le commutateur si nécessaire et à revenir du gestionnaire d'interruption dans un fil différent . .

Bien sûr, obtenir cela pour travailler lorsque les threads eux-mêmes peuvent utiliser des interruptions, ne seront pas nécessairement faciles.

Vous pouvez également examiner le noyau, peut-être Contiki .

ici est un exemple de "Protothreads" pour la PIC18, ressemble à une quantité raisonnable de code. Pas sûr de la sémantique, cependant.

Mise à jour : Cela nécessitera probablement de faire partie du code de niveau le plus bas de l'assembleur (je ne suis pas sûr, je n'ai pas travaillé en C sur la photo, donc je ne sais pas exactement combien de contrôle vous obtenez). Vous aurez besoin de contrôle sur les registres du compteur de programme, et ce ne sont pas des concepts C.


0 commentaires

12
votes

N'utilisez pas de threads, utilisez une boucle d'événement.

Le PIC18 est un petit processeur et un style basé sur la boucle d'événement signifie que vous n'avez pas à garder de nombreuses piles profondes suspendues. Vous devez écrire votre code en termes de boucle d'événement, mais c'est probablement raisonnable.

Si vous avez des tâches longues en cours d'exécution, utilisez les chronomètres des priorités d'interruption différents pour permettre aux boucles d'événements de priorité plus élevées de préempter les boucles d'événement prioritaires à faible priorité et de mettre des types de travail appropriés dans la file d'attente d'événement appropriée.


12 commentaires

D'accord. Si cela répond à vos besoins, gardez-le simple.


Notez que cela suppose des E / S asynchrones. Cela n'aide pas si votre programme principal est bloqué sur certains E / S. Avec des threads, et une tâche simple basée sur la mainte Robine, vous découplez diverses tâches, ce qui leur garantit une petite quantité de temps.


Il s'agit d'une puce PIC18 et de files doivent être implémentées quelque part et leur état doit être stocké. À peu près tous les E / S que vous pouvez faire peuvent être faites de manière asynchrone d'une manière ou d'une autre; Si vous commencez à faire des E / S synchrones, vous devez désactiver les interruptions pour la fiabilité, puis vous ne serez pas préempté de toute façon. Vous pouvez implémenter une bibliothèque de threading et un planificateur en haut des fonctionnalités ASYNC de la puce, mais pourquoi vous déranger? Vous avez probablement moins de 4 Ko de RAM et que les opérations critiques sont susceptibles d'être i / O entraînées. Il suffit de considérer pic18 comme un système d'exploitation très simple.


Je comprends pourquoi les gens disent que ce n'est pas quelque chose que vous le feriez, mais les RTO augmentent considérablement la qualité de la programmation en utilisant un RTO pour isoler des threads. Dans un code critique de sécurité complexe, un RTO peut économiser plusieurs mois de temps pour une équipe d'ingénieurs, cela peut dépasser 6 chiffres en économies pour utiliser un RTO qui est certifié critique de sécurité.


@Kortuk sûr, dans un code critique complexe et de sécurité, il existe des facteurs au-delà "Comment puis-je faire des threads?" Une équipe d'ingénieurs travaillant sur un projet critique de sécurité a tendance à ne pas demander "Comment puis-je faire des threads", mais demandez-vous, comme vous l'avez fait sur l'électronique, "Pouvez-vous me parler de vos expériences de RTO sur ces dimensions?" Cela dit, j'ai mis en œuvre un code critique de sécurité sur un périphérique certifié à l'aide d'une structure de boucle d'événement et était satisfaite du résultat. Toutefois, cette décision dépend de nombreux facteurs non seulement "x bon, y mauvais".


@janm, j'ai donné un exemple simple, veuillez me pardonner de sous-évaluer votre expérience. La principale raison pour laquelle je veux qu'un RTO soit due à découplage. En découplant des sous-traitements, la quantité nette de travail que les besoins du projet diminueront considérablement.


@Kortuuk pas de problème, je sais que ce n'était pas votre intention. Je conviens que le découplage est bon, mais vous pouvez découpler votre exigence de découplage d'un RTO! Si vous choisissez un RTO dépend de nombreux facteurs, y compris l'expérience des développeurs, le problème à résoudre, le temps, l'argent, etc. La séparation des préoccupations est quelque chose de bons développeurs considérons et font tout au long de leur propre code, pas seulement à travers une frontière. au code tiers.


@janm, la plupart des gens que j'ai vus faire cela soient tout à fait finalement mettre en œuvre les bases d'une RTO et avoir à déboguer le code qu'ils écrivent, pourquoi ne pas payer pour cela.


@janm, je ne dis pas que vous avez tort cependant, il n'y a pas de règle claire sur quoi faire!


@janm, sur cette note, je pense que l'utilisateur a choisi qu'ils veulent faire des threads, je pense qu'une réponse qui les aidant à s'infiltrer est de valeur. Maintenant, j'ai rencontré beaucoup qui pensent vraiment que le filetage va être quelque chose comme appel à la fourchette () sur une pic18


@Kortuk Nous convenons que la réponse varie selon la situation. Lorsque nous examinons la situation de la question, un développeur de logiciels arrivant à une PIC18 à partir d'une plate-forme générale et de poser des questions sur les "threads" devrait être introduite sur le concept de boucle d'événement et de faire face aux événements asynchrones. La puce prend en charge que le modèle de programmation est bien meilleur qu'un modèle de filetage, et il s'agit d'un modèle intéressant en soi, souvent préférable, même lorsque des threads à usage général sont disponibles. Une réponse séparée couvrait l'affaire "Utiliser un RTO pour obtenir des threads"! :-)


@janm, maintenant si l'astucieux accepterait une réponse que vous pourriez savoir ce qu'ils veulent. Merci pour la discussion, je l'ai assez apprécié.



2
votes

Sachez que sur les microcontrôleurs, certains "threads" peuvent également être traités par un seul gestionnaire d'interruptions spécifique et fonctionnent donc dans "Parallèle" à votre boucle d'événement principale de toute façon.

E.g. Si vous avez un événement externe déclencher une conversion ADC, votre gestionnaire de conversion ADC peut prendre cette valeur, faire quelques calculs, puis définir certains bits de sortie pour adapter la sortie de contrôle en fonction de la valeur ADC. Tout ce qui peut arriver dans le gestionnaire d'interruption et ainsi parallèle à tout le reste.

Selon les choses que vous devez faire en parallèle, vous pouvez choisir une combinaison de techniques multiples pour faire fonctionner des objets en parallèle comme prévu.


0 commentaires

2
votes

Vous voudrez peut-être lire cet article de la programmation système intégrée: Construire un Tascher Super Simple


0 commentaires

1
votes

Le compilateur CCS comprend un RTO. Je ne l'ai pas utilisé, mais depuis le Manuel du compilateur :

Le système d'exploitation en temps réel CCS (RTOS) permet à un micro contrôleur PIC Pour exécuter des tâches régulièrement planifiées Sans la nécessité d'interruption. Cette est accompli par une fonction (Rtos_run ()) qui agit en tant que Dispatchers. Quand une tâche est prévue Pour exécuter, la fonction d'expédition donne contrôle du processeur à cette tâche. Lorsque la tâche est effectuée en cours d'exécution ou n'a plus besoin du processeur, Le contrôle du processeur est renvoyé à la fonction d'expédition qui puis donnera le contrôle du processeur à la prochaine tâche prévue à exécuter au moment opportun. Cette processus s'appelle la coopérative multi-tâches.

Juste un mot d'avertissement - Vérifiez leurs forums d'informations sur les fonctionnalités spécifiques que vous recherchez. Apparemment, CCS a l'habitude de libérer de nouvelles fonctionnalités avant qu'ils ne soient pleinement testés. C'est une raison pour laquelle j'utilise toujours la version ancienne (V3.249).


0 commentaires

0
votes

Cela fait cette chose même, une boucle de tâche, ainsi que des priorités de réservations de tâches et ce que j'aime le codage simple de briser de longues fonctions de course dans des tranches.

http://www.mculabs.com/drivers/qtask.html


0 commentaires

0
votes

Je suis d'accord avec NDIM - vous pouvez penser à chaque gestionnaire d'interruption comme quelque chose comme un "fil". Parfois, toutes les tâches que vous devez faire peuvent être gérées par interruption des gestionnaires déclenchés par des événements externes et internes - la "boucle principale" est une boucle inactive qui ne fait rien.

Je ne sais pas où certains commentateurs ont l'idée qu'il n'y a "aucun système d'exploitation" pour la PIC18. Il existe de nombreuses bibliothèques multithreading spécifiques à une photo et «noyaux de système d'exploitation multitâche» pour la PIC18, beaucoup d'entre elles libres et open source. Voir PICLIST: "Méthodes multitâches spécifiques de microcontrôleur Photo" .


0 commentaires

1
votes

sur le 8051, j'ai fait dual-tâtonnage en utilisant un simple commutateur de pile. Je m'attendrais à ce que la même chose puisse être faite sur la photo, à condition que chaque tâche n'a utilisé que 16 niveaux de pile. Le code serait quelque chose comme ça (suppose _altsp est dans la banque commune) xxx

La tâche principale doit appeler _InitTask2 pour démarrer la deuxième tâche. La deuxième tâche sera exécutée jusqu'à ce qu'il appelle _taskswitch, où la tâche principale reprendra l'exécution après l'instruction appelée _InitTask2. De là, chaque fois qu'une tâche appelle _taskswitch, l'autre tâche reprendra l'exécution de la dernière place qu'elle a appelée _taskswitch.

Si vous utilisez cette approche, votre compilateur devra être informé que tous les registres peuvent être détruit par des appels vers _InitTask2 ou _taskswitch. Il faudrait également dire que _task2start et fonctions Les appels informatiques doivent être alloués espace variable distinct de la tâche principale.

Je ne sais pas ce que vous devez dire au compilateur de le rendre heureux, mais je Dirons que la double tâche coopérative peut faire de certaines choses vraiment bien.


2 commentaires

Cette NOTE DE L'application indique qu'il n'est pas possible d'accéder au pointeur de pile si Le noyau n'est pas pic18. Je ne connais pas l'assemblée et j'essaie d'en apprendre davantage sur les commutateurs de classement simples (s). Cela signifie-t-il que mes espoirs sur la création d'un simple commutateur de tâches avec PIC12 et PIC16 sont un non-sens?


@AbDullahkahraman: Le seul moyen de trouver un code multitâche sur la PIC12 ou PIC16 est d'exiger que seule une des tâches puisse effectuer un commutateur de tâche dans un sous-programme imbriqué. Incidemment, j'ai fait une belle application commutée par tâche une fois sur une puce basée sur PIC165X où les deux tâches étaient presque identiques, à l'exception des missions d'E / S. Chaque tâche a utilisé un ensemble de registres bancaires. A travaillé vraiment slick.



1
votes

J'aimerais partager mon petit noyau en C Langage de programmation C pour gérer les tâches sur un microcontrôleur. Vous pouvez créer une tâche avec une période, suspendre, reprendre et modifier une période de tâche à tout moment. Ce noyau peut supprimer toute tâche pour créer un autre séquenceur que vous le souhaitez. Une fonction TickGet est fournie par le noyau pour gérer toutes les minuteries que vous le souhaitez. Vous devez créer une seule fonction d'interruption et remplacer la minuterie de fonction () pour obtenir votre minuscule-noyau pour votre propre application. Pour reprendre ce noyau est basé sur une liste liée circulaire, pour changer de tâche sur la tâche. Il est volontairement écrit de manière générale d'aider les personnes à personnaliser pour leurs propres applications. Il n'y a aucune priorité entre tâche comme une planification de tâche rond-robine. Et j'ai écrit ce code source à l'égard des directives MISRA (NORMATION AUTOMOTIVE) Vous pouvez le télécharger ici < / a>

J'espère aider les gens à gérer les tâches sur le microcontrôleur.


0 commentaires

0
votes

Je le fais, je le fais (multitâche de coopération à proprement parler à la profondeur de pile d'appel fixe).

Cela fonctionne, mais le compilateur Hitec-C fonctionne contre moi - il réutilise des emplacements de mémoire pour des variables temporaires à partir de fonctions qu'il ne semble jamais courir en même temps. Essentiellement des threads se corrompre. Si je trouve un moyen de contourner cela, je mettrai à jour cette réponse avec un code d'exemple.


0 commentaires

0
votes

La bibliothèque de ProTothreads est simple de manière simple pour multi-tâches multi-plate-forme: http://dunkels.com/adam / pt /

Exemple de planificateur minimal pour PT avec la synchronisation des tâches, les minuteries et les données utilisateur: https: // github. com / edartuz / c-ptx


0 commentaires