2 votes

Commutation de contexte dans uC/OS (systèmes embarqués)

J'aimerais savoir s'il est possible d'avoir une interruption qui force le planificateur à changer de contexte pour une tâche spécifique dans un RTOS. Je travaille avec le système d'exploitation microCOS

Voici la tâche qui effectue le keyscan et envoie le caractère dans une boîte aux lettres. Je dois ajouter d'autres fonctions à ce code, comme le débordement et la répétition automatique, mais je dois trouver un mécanisme de déclenchement pour le faire fonctionner correctement.

Je ne suis pas sûr de savoir comment utiliser l'interrogation ou les interruptions pour y parvenir.

        static  void  AppTaskKeyscan (void *p_arg)
    {
        CPU_INT08U debouncing = 1;
        CPU_INT16U key;
        key_t button={0,0,0};

        (void)p_arg;

         while (DEF_TRUE) 
         {
            static CPU_INT08U pattern;
            key=P10;

            OSTimeDlyHMSM(0, 0, 0, 50);
            P10=0x0E;
            if ((pattern=P10)==0xee)
                {button.data='1', button.live=1;}       
            else if (pattern==0xde)
                {button.data='4', button.live=1;}
            else if (pattern==0xbe)
                {button.data='7', button.live=1;}
            else if (pattern==0x7e)
                {button.data='*', button.live=1;}
            else
            {
                P10=0x0d;
                if ((pattern=P10)==0xed)
                    {button.data='2', button.live=1;}
                else if (pattern==0xdd)
                    {button.data='5', button.live=1;}
                else if (pattern==0xbd)
                    {button.data='8', button.live=1;}
                else if (pattern==0x7d)
                    {button.data='0', button.live=1;}
                else
                {
                    P10=0x0b;
                    if ((pattern=P10)==0xeb)
                        {button.data='3', button.live=1;}
                    else if (pattern==0xdb)
                        {button.data='6', button.live=1;}
                    else if (pattern==0xbb)
                        {button.data='9', button.live=1;}
                    else if (pattern==0x7b)
                        {button.data='#', button.live=1;}
                    else
                    {
                        P10=0x07;
                        if ((pattern=P10)==0xe7)
                            {button.data='A', button.live=1;}
                        else if (pattern==0xd7)
                            {button.data='B', button.live=1;}
                        else if (pattern==0xb7)
                            {button.data='C', button.live=1;}
                        else if (pattern==0x77)
                            {button.data='D', button.live=1;}
                        else
                            button.live=0;
                    }
                }
            }

            P10=pattern; 

            if (button.live==0)
                OSTimeDlyHMSM(0, 0, 0, 50);
            else
            {
                if (P10==pattern)
                OSTimeDlyHMSM(0, 0, 0, 50);
                else
                button.live=0;
            }

            P10=0x00;              
            if (button.live)        //if button live, set unread flag to 1 and start count down
            {
                button.unread=1;
            }

            if(button.unread&&button.data!='X')
            {
                key=button.data;
                OSMboxPost(KeyMbox, (void *) &key);
                button.live=0;
                button.unread=0;
            }

             OSTimeDlyHMSM(0, 0, 0, 200); 
         } // End of While
    }

2voto

TJD Points 7208

La façon typique de faire cela serait d'avoir une tâche de traitement du clavier qui a une boucle où elle dépend d'un sémaphore. Le gestionnaire d'interruption du clavier affiche le sémaphore, ce qui fait que la tâche de traitement devient prête et s'exécute.

0voto

Adrian Points 2320

Le programmateur s'en charge normalement. C'est son travail de savoir quand faire le changement de contexte basé sur les priorités des processus/threads (avec un planificateur conscient des threads/processus).

Edit :

Une raison pour laquelle cela n'est pas fait

Imaginons qu'un intrus génère une tâche de faible priorité, forçant le CPU à changer de contexte (d'une tâche de plus haute priorité, par exemple) pour exécuter une charge utile malveillante.

0voto

Clifford Points 29933

Vous devez utiliser un mécanisme IPC compatible avec les interruptions (c'est-à-dire non bloquant) pour signaler une tâche. La méthode la plus simple pour gérer un clavier est que l'ISR place le code de la touche dans une file d'attente. Toute tâche désirant une entrée utilisateur lira cette file d'attente.

Alternativement, vous pouvez simplement demander à l'ISR d'incrémenter un sémaphore de comptage, et de reporter le décodage du clavier à une tâche, qui peut alors placer les caractères dans une file d'attente qui peut être lue par n'importe quelle tâche lisant l'entrée utilisateur. Ceci peut être préférable si le décodage est long ou variable en temps d'exécution.

Spécifiquement dans uC/OS-II, une ISR qui requiert l'exécution du planificateur doit utiliser les appels OSIntEnter() et OSIntExit(). C'est OSIntExit() qui provoque l'exécution de l'ordonnanceur lorsque la dernière interruption imbriquée est terminée. Les tâches seront alors planifiées en fonction de la politique d'ordonnancement. Il n'est pas possible de contourner la politique afin de forcer une tâche spécifique à s'exécuter contre la politique d'ordonnancement, et vous ne devriez pas le vouloir ! Si une tâche spécifique doit être exécutée, il faut lui donner la plus haute priorité.

Normalement, les fonctions prologue/épilogue de l'ISR ne sont nécessaires que pour les ISR qui font des appels au système d'exploitation, puisqu'un ISR qui ne le fait pas ne nécessitera pas l'exécution de l'ordonnanceur.

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