Software temporizadores e interrupciones en un microcontrolador

4

Tengo algunas preguntas sobre los temporizadores de software e interrupciones en un microcontrolador. Solo para información, uso un microcontrolador dsPIC33E.

El objetivo final es implementar un protocolo de comunicación en serie: RS485 con Modbus. Logré transmitir y recibir un mensaje, y ahora tengo que hacer una parte de procesamiento de mensajes.

Dado que necesito un montón de temporizadores para todo tipo de tareas diferentes (por ejemplo, 3.5 caracteres de retardo necesarios para la comunicación en serie, algo de retardo necesario para los botones de rebote, etc.), planeo implementar los temporizadores en un software usando un solo temporizador de hardware . Por ejemplo, el período del temporizador de hardware se establece en 100 us, y se genera una interrupción en cada "desbordamiento", es decir, cada 100 us. En el ISR acabo de actualizar los contadores globales, que básicamente son temporizadores de software con una resolución de 100, mientras que el ISR del temporizador de hardware tiene la máxima prioridad. ¿Es esta una buena manera de hacer esto o hay alguna mejor manera?

Cada contador (es decir, un temporizador de software) ha definido su propio período, y una vez que el contador alcanza su "valor de período", quiero llamar a alguna función. Ahora no es una buena idea llamar a esta función desde dentro del ISR del temporizador de hardware, porque esa función se procesará con la mayor prioridad ya que la rutina de llamada es el ISR del temporizador de hardware. Lo que quiero es definir alguna función, digamos:

void Modbus_Protocol(void);

y poder definirlo como una interrupción, que no será de la más alta prioridad. Solo el temporizador de hardware principal tiene la mayor prioridad en este concepto. De esa manera, una vez que el contador en el temporizador de hardware ISR alcanza su valor de período, no llamará a su función, sino que simplemente establecerá un indicador para activar una interrupción (por ejemplo, void Modbus_Protocol (void) ), que se activará después de que el ISR principal regrese, dependiendo de su prioridad. ¿Se puede hacer algo como esto, es decir, puedo definir interrupciones de software?

Sé que existe la posibilidad de usar interrupciones de hardware que no se usan, y simplemente establecer un indicador de interrupción desde dentro del software. Pero no creo que esta sea una forma elegante de implementar interrupciones si las interrupciones de software definidas por el usuario son posibles.

    
pregunta Marko Gulin

2 respuestas

3

No necesita "interrupciones de software" especiales. Echa un vistazo al siguiente código. Olvidé algunas cosas técnicas como la declaración de variables para mayor claridad.

Use su ISR para contar solo un temporizador (marca). En el main () estás esperando para sincronizar con este temporizador. Use un temporizador dedicado para cada tarea que tenga que procesar. Todos estos temporizadores se incrementan en cada marca ISR.

Si el temporizador de la tarea caduca, la tarea dedicada se procesa. Hay algunas características especiales en este tipo de implementación. Cuando restas el tiempo EXPITADO de tu temporizador en lugar de configurarlo como 0, tu software es más robusto si cualquiera de las tareas toma más tiempo que 100µs. Es un tipo de criterio suave en tiempo real.

Obtienes un sistema de pseudo multitarea.

isr() //100µs
{
    tick++;
}

main()
{    
  while(true)
  {
    while(tick == last_tick);
    last_tick = tick;

    modbus_timer++;
    task1_timer++;
    task2_timer++;

    if(modbus_timer >= MODEBUS_TIMER_EXPIRED)
    {
      modbus_timer -= MODEBUS_TIMER_EXPIRED;
      Modbus_Protocol();
    }

    if(task1_timer >= TASK1_TIMER_EXPIRED)
    {
      task1_timer -= TASK1_TIMER_EXPIRED;
      Task1();
    }

    if(task2_timer >= TASK2_TIMER_EXPIRED)
    {
      task2_timer -= TASK2_TIMER_EXPIRED;
      Task2();
    }
  }//forever-loop
}// main()
    
respondido por el Batuu
0

Después de un poco de Google y discusión, me di cuenta de que intenté lograr tareas priorizadas, que es básicamente un RTOS (sistema operativo en tiempo real). Aunque un RTOS se puede implementar en un microcontrolador, requiere una gran cantidad de recursos (RAM, etc.).

La otra opción es usar un planificador como explicó Batuu. De esa manera, las tareas no pueden ser priorizadas (no hay multitarea), y todas las tareas deben finalizar dentro de un solo tick.

    
respondido por el Marko Gulin

Lea otras preguntas en las etiquetas