Realización de un programa multitarea con interrupciones de temporizador

3

Este es mi intento de realizar multitareas (bueno, casi) a través de interrupciones. En este ejemplo, la Tarea 1 es: el LED de alternancia conectado a PB1 a 2Hz (se usa el temporizador 1, OCR1 puede contener valores hasta 65535), la tarea 2 es: el LED de alternancia se conectó a PB3 a 61Hz (ya que el Timer2 OCR2 es de 8 bits). Parece que también está funcionando.

  • ¿Entendí el concepto de multitarea, verdad?
  • ¿Cómo puedo asignar segmentos de tiempo para una "Tarea" o no es posible en este caso?
  • ¿Puedo reemplazar la "Tarea" de cambiar el LED al ADC medir o recibir bytes en USART? ¿O sería eso realizado de manera diferente?

Aquí está mi programa:

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define COMP_REG_VAL 61250

void timer1_init()
{
    DDRB   |= 1<<PB1;        // Set PortB Pin1 as output
    TIFR1  |= 1<<OCF1A;     // Clear Output compare flag
    TIMSK1 |= 1<<OCIE1A;    // Enable Interrupt on Output compare match  
    TCCR1B |= ( (1<<CS12) | (1<<WGM12) );     // Prescaler Fosc/256 ===> 62500
}

void timer2_init()
{
    DDRB   |= 1<<PB3;        // Set Port B pin3 as Output 
    TIFR2  |= 1<<OCF2A;     // Clear Output compare flag
    TIMSK2 |= 1<<OCIE2A;    // Enable Interrupt on Output compare match  
    TCCR2A |= (  (1<<WGM20) | (1<<WGM21) );     //FAST PWM mode
    TCCR2B |= ( (1<<WGM22) | (1<<CS22) |  (1<<CS21) | (1<<CS20) );  //Fast PWM MOde, Prescaler=fosc/1024
}

int main (void)
{
  sei();
  timer1_init();
  timer2_init();
  OCR1A = COMP_REG_VAL/2;
  OCR2A = 255;

  while(1) 
  {

  }
}

ISR(TIMER1_COMPA_vect)
{
   PORTB ^= (1<<PB1);       // Toggle Pin when overflow occurs
}


ISR(TIMER2_COMPA_vect)
{
   PORTB ^= (1<<PB3);       // Toggle Pin when overflow occurs

}
    
pregunta Abel Tom

2 respuestas

5
  

¿Entendí el concepto de multitarea, verdad?

hay diferentes sabores de "multitarea", algunos más sofisticados que otros. en pocas palabras, es tiempo de compartir para proporcionar la percepción de concurrencia.

  

¿Cómo puedo asignar segmentos de tiempo para una "Tarea" o no es posible en este caso?

su enfoque a la multitarea es menos convencional. por lo general, es un programador que alterna dentro y fuera de las tareas periódicamente. por lo que el "intervalo de tiempo" es fijo.

  

¿Puedo reemplazar la "Tarea" de cambiar el LED al ADC medir o recibir bytes en USART? ¿O sería eso realizado de manera diferente?

Eso puede ser complicado. El desafío clave es interrumpir una transmisión UART en el medio y solo ejecutar la misma transmisión UART en el ISR. No todos los microcontroladores son capaces de eso, e incluso si lo son, se debe abordar con precaución.

    
respondido por el dannyf
2

Ha programado multitarea preventiva sin un conmutador central de tareas. Esto significa que sus procesos individuales no tienen control sobre cuándo se interrumpen. Sería mucho, mucho más fácil implementar multitarea cooperativa donde cada proceso abandona su tiempo cuando se realiza con algunos "atómicos". "poco de trabajo.

Claro, a primera vista, hacerlo preventivo parece prometedor, pero, tarde o temprano, se encontrará con casos graves de condiciones de carrera. Por ejemplo, si llama a algún módulo desde su código que puede esperar por condiciones externas (es decir, I2C o USB), entonces está atornillado. Incluso solo imprimiendo algunos resultados de depuración en una conexión en serie lenta (lo que lleva más tiempo que la duración del temporizador de una de sus interrupciones) le ocasionará graves problemas.

Un sistema operativo real también usaría un conmutador de tareas central A.K.A. programador, pero eso no es un gran problema aquí, ya que sabe exactamente qué procesos se están ejecutando en su µC.

Si quieres darle un giro a la cooperativa multitarea, y te invito mucho a que sea un muy poderoso concepto para µC, mira coroutines . Son como bucles pero "de adentro hacia afuera", es decir, son bucles que "renuncian a su parte de tiempo" con frecuencia. Resuelven el problema de las condiciones de carrera inducidas de forma preventiva (es decir, que las cosas se interrumpen cuando no deberían), son bastante fáciles de implementar y simplemente divertidas.

    
respondido por el AnoE

Lea otras preguntas en las etiquetas