Autor Tema: Programación multitarea?  (Leído 4385 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado arcachofo

  • PIC16
  • ***
  • Mensajes: 126
    • Foro para usuarios Linux.
Programación multitarea?
« en: 07 de Febrero de 2009, 07:23:57 »
Pues como andaba experimentando con programación con bases de tiempo y abrí el tema del delay "no bloqueante" al final no me aclaro bién de cual sería la terminología correcta para todo esto.

Entiendo que una cosa es un Sistema Operativo, que corre independientemente al programa en sí y que gestiona todas las posibles "tareas" según su nivel de prioridad y su estado.

Otra cosa es programar con bases de tiempo, que puede ser utilizado para muchas cosas.

Y otra cosa es hacer funciones o rutinas que no se queden esperando por respuestas del hardware, sino que dejen libre al procesador hasta que la respuesta esté disponible.

Combinando estas dos últimas se consigue realizar varias "tareas" en paralelo, entendiendo por tareas un conjunto de acciones simples que se van realizando a medida que los recursos necesarios van estando disponibles, si una acción no se puede realizar en ese momento, queda postpuesta y otras acciónes de otras tareas se van realizando mientras tanto.

Abro este hilo con la intención de aclarar y definir conceptos en lo posible; aunque también con la idea de aprender de otros usuarios estrategias, rutinas o lo que sea orientadas en este sentido.

¿Que entendeis por multitarea? ¿como lo haceis para aprobechar el procesador?...


Saludos.

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Programación multitarea?
« Respuesta #1 en: 08 de Febrero de 2009, 15:09:57 »
Bueno, tu preguntas y tu mismo te respondes y está bien asi como lo planteas, parece que todo ya está aclarado.

Javicho.

Desconectado arcachofo

  • PIC16
  • ***
  • Mensajes: 126
    • Foro para usuarios Linux.
Re: Programación multitarea?
« Respuesta #2 en: 08 de Febrero de 2009, 20:27:58 »
Citar
Bueno, tu preguntas y tu mismo te respondes y está bien asi como lo planteas, parece que todo ya está aclarado.

Javicho.

No sé que quieres decir con eso... pero mi intención era más o menos esta:


Citar
Abro este hilo con la intención de aclarar y definir conceptos en lo posible; aunque también con la idea de aprender de otros usuarios estrategias, rutinas o lo que sea orientadas en este sentido.

¿Que entendeis por multitarea? ¿como lo haceis para aprobechar el procesador?...


Si no te interesa el tema pues nada...


Saludos.

Desconectado vtasco

  • PIC12
  • **
  • Mensajes: 72
Re: Programación multitarea?
« Respuesta #3 en: 08 de Febrero de 2009, 22:08:45 »
Hola, en el libro "Learn Firmware And Hardware Design", hay un capítulo que explica lo que estás planteando, lo acabo de ver ayer en la tarde, creo, no estoy seguro, que viene con algún ejemplo.

saludos!

Desconectado horacioe

  • PIC10
  • *
  • Mensajes: 7
Re: Programación multitarea?
« Respuesta #4 en: 10 de Febrero de 2009, 22:51:44 »
puedo pensar que casi todo lo que programo en los pics, lo realizo en forma de multitarea.

para que te hagas una idea, el codigo resumido seria asi:



   list p=16F877A
   processor 16F877A
   include   P16F877A.INC
   __CONFIG  _CP_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC & _BODEN_OFF & _LVP_OFF
   errorlevel  -302

;________________________________________________________________________________
   cblock   0x20

; aqui pongo todas los registros que necesita mi programa
   endc
;________________________________________________________________________________

      ORG   00      
      goto   INICIO

      ORG   04
      goto   Serv_Interrupc      ;aqui salta las interrupciones

;********************************************************************************


;###########################################################################################




INICIO
   call   InicioHardware   ;aqui inicio el hardware, pongo salidas digitales o analogicas, seteo los tris de los puertos,
                                         ; seteo las transmision de la USART, seteo los timer, etc
LOOP
   goto   LOOP      ; de este loop no sale nunca



mis programas funcionan casi al 100% a base de interrupciones, puedo programar los timer para que corran ciertas rutinas de chequeo de pines cada tantos milisegundos, etc

para un simulador que he diseñado, logre realizar que el pic estudiara la imagen de una cámara (con un pequeño hardware en el medio), consultara el estado de 5 dispositivos, habilitandolos o no para actuar, asimismo transmitiendo toda la información a una computadora, y recibiendo de esta que dispositivo habilitar y actuando en consecuencia, todo esto unas 50 veces por segundo.
asimismo como tareas secundarias chequea el sensado de temperatura en 5 lugares distintos, y en caso de sobretemperatura, avisa a la pc, y en caso de demasiada sobretemperatura, tiene el poder de apagar todo el sistema

y lo mas ironico que el codigo esta como puse arriba, jeje. Trabaja todo a base de interrupciones y puedo agregarle mas taresas si es necesario.

INICIO
   call   InicioHardware   ;aqui inicio el hardware, pongo salidas digitales o analogicas, seteo los tris de los puertos,
                                         ; seteo las transmision de la USART, seteo los timer, etc
LOOP
   goto   LOOP      ; de este loop no sale nunca
   

Desconectado arcachofo

  • PIC16
  • ***
  • Mensajes: 126
    • Foro para usuarios Linux.
Re: Programación multitarea?
« Respuesta #5 en: 11 de Febrero de 2009, 05:53:17 »
Ok horacioe... a ese tipo de cosas me refreía.

si tuvieras algún pequeño ejemplo a mano sería estupendo, al fin y al cabo lo que importa son los detalles.
Por ejemplo sueles usar preferentemente timer0 o usas uno cualquiera?
En la rutina de interrupciones solo llevas los contadores o tambien compruebas si es hora de hacer alguna tarea?
Que base de tiempo sueles usar?
usas semáforos o algo por el estilo?

Hay muchas posibles maneras de hacer las cosas y encontrar una combinación sencilla y eficiente es lo más dificil.



Gracias por las respuestas y hasta la próxima...

Desconectado Javicho

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 570
Re: Programación multitarea?
« Respuesta #6 en: 11 de Febrero de 2009, 12:45:15 »
Hola:

Lo que te ha comentado horacioe es la idea de como llevar a cabo varias tareas "a la vez", en mi caso mis programas no tienen un .. loop    goto loop, sino mas bien en ese loop hay bastante código al igual que en el RSI, yo prefiero colocar lo mas importante en el RSI, todo depende del sistema y cada uno suele ser diferente del otro asi que no se puede pedir una regla general de cómo se debe hacer esto, siempre dependerá del sistema en particular que estes diseñando.

Te sugiero que te plantees un par de ejemplos y busques hacerlo, por ejemplo, unos leds parpadeando a diferente frecuencia, un teclado leido desde el programa principal y RX/TX por USART a la PC, con eso será mas que suficiente para que encuentres tu mejor técnica, incluso lo puedes hacer de varias formas.

En mi caso cuando inicio el programa cargo con un valor adecuado el timer0 a fin de que este me interrumpa el RSI por ejemplo cada 2mS, si el sistema no requiere tanta velocidad puedo apoyarme en un registro a fin de que las interrupciones sean cada 200ms, en este punto no es que las interrupciones ocurren cada 200mS sino que las tareas que se encuentran en el RSI se ejecutan cada 200mS a pesar de que el RSI se interrumpe cada 2mS. Recuerda que antes de salir del RSI siempre debes volver a cargar el valor del timer0.

Javicho.

Desconectado reiniertl

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Programación multitarea?
« Respuesta #7 en: 11 de Febrero de 2009, 16:12:49 »
Busca en el foro por el tema de los RTOS

Desconectado arcachofo

  • PIC16
  • ***
  • Mensajes: 126
    • Foro para usuarios Linux.
Re: Programación multitarea?
« Respuesta #8 en: 11 de Febrero de 2009, 20:34:43 »
Hola javicho.

Citar
Lo que te ha comentado horacioe es la idea de como llevar a cabo varias tareas "a la vez"

Si... la idea era comentar, discutir, debatir, comparar distintas maneras de conseguir esto...

Citar
, en mi caso mis programas no tienen un .. loop    goto loop, sino mas bien en ese loop hay bastante código al igual que en el RSI, yo prefiero colocar lo mas importante en el RSI, todo depende del sistema y cada uno suele ser diferente del otro asi que no se puede pedir una regla general de cómo se debe hacer esto, siempre dependerá del sistema en particular que estes diseñando.

Por ejemplo tu no usas un bucle en el sentido que lo hace horacioe (y yo también),... por lo que entiendo es una "combinación" de programación "secuencial" con algunas cosas por interrupciones con una base de tiempo.

Ciertamente todo depende del caso concreto,... puede darse el caso de que el programa esté normalmente esperando una entrada pero que a la vez haga algunas cosas cada cierto tiempo, o que cierta entrada ponga en funcionamiento una tarea que se realiza cada cierto tiempo hasta que se dé otra entrada.... las combinaciones son infinitas.

Citar
Te sugiero que te plantees un par de ejemplos y busques hacerlo, por ejemplo, unos leds parpadeando a diferente frecuencia, un teclado leido desde el programa principal y RX/TX por USART a la PC, con eso será mas que suficiente para que encuentres tu mejor técnica, incluso lo puedes hacer de varias formas.

Si... ya he hecho varias pruebas de ese tipo y ahora trato de aplicar todo esto a un caso concreto algo más complejo; pero son muchas las posibles combinaciones y las posibles estrategias y a veces tengo resultados extraños según como organice las cosas... hay maneras que resultan muy inestables, incluso el pic se "cuelga" igual que un PC... puede estar varios minutos funcionando  hasta que se "congela" y no hace más nada, todavía no tengo claro donde está el punto flaco.

Por ejemplo según los tiempos que le dé a cada tarea... a veces todas las tareas se activan en el mismo ciclo, ya que suele haber un múltiplo común. He probado por ejemplo a "desfasar" algunas, si dos tareas se realizan cada 100 ms, una de ellas la inicio con el contador a 50 y entonces no deberían coincidir... aunque según aprendí de reiniertl, en estos casos  nunca se debe presuponer el momento en que se vá a ejecutar cada tarea.

El caso es que para las pruebas una cosa que hago es mandar por Uart al PC los tiempos que duran algunas de ellas y representar graficamente esos datos... si todo funciona bién se vé una linea más o menos recta, ejemplo:



Pero hay veces que la linea parece un peine destrozado... totalmente irregular y con saltos arriba y abajo, entonces suele acabar quedándose colgado, ejemplo:




Creo que esto me pasa sobre todo si uso bases de tiempo muy cortas, al principio llegué a probar hasta con 100 us, por ver cual era el límite, pero cuantas más tareas iba añadiendo tenía que subir el tiempo para que me funcionara.
Ahora estoy probando con 1 ms, que es una medida facil de utilizar.

La manera como lo estaba haciendo era con un bucle principal donde están todas las tareas, cada tarea activada por un flag, que se controla desde RSI, poniéndolo a 1 cuando su contador correspondiente llega al tiempo estipulado.
Yo, al contrario que javicho me preocupaba de cargar lo menos posible la RSI y dejar todo lo gordo en el bucle principal; pero veo que esto no tiene porqué ser lo mejor, sobre todo si se alarga la base de tiempo lo suficiente como para que no haya otra interrupción del timer mientras todavía está en RSI...

Y el saber cuales son las estrategias de otros me abre otras posiblidades que no se me habían ocurrido...

Saludos y gracias por las respuestas.

Desconectado horacioe

  • PIC10
  • *
  • Mensajes: 7
Re: Programación multitarea?
« Respuesta #9 en: 12 de Febrero de 2009, 01:32:55 »
Bue, otra de las cosas que acostumbro hacer son bloques cerrados, que un bloque de codigo no salte a la mitad de otro ni que nadie salte en medio de este bloque. por ejemplo:



;calculo un timer para que pase por aca cada milisegundo

;BLOQUE1 aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

;BLOQUE2 aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

;BLOQUE3 aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

   decf  contador,F
   btfss  STATUS,Z
   goto   fin_interrupcion
   movlw  .100
   movwf   contador

; por aca va a pasar siempre cada 100 milisegundos, y queda casi independiente de los bloques que haya puesto anteriormente


;BLOQUE_A aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

;BLOQUE_B aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

;BLOQUE_C aqui pongo el codigo que quiera que se ejecute a cada milisegundo, en todas las partes que quiero terminar, simplemente salto al final de este bloque.

     goto    fin_interrupcion





de esta forma, puedo poner bloques de programa que no me va a afectar practicamente el funcionamiento del resto del sistema, un bloque puede ser un codigo que me prenda y apague un led,  otro bloque puede estar tomando una señal en algun pin y actuar en consecuencia, sea lo que sea, siempre que termino de ejecutar la tarea en el bloque, siempre salto al final del bloque, nunca salto a terminar la interrupción, por ejemplo en el BLOQUE_C es lo mismo saltar al final del bloque o saltar a terminar la interrupción,   pero nunca voy a saltar a terminar la interrupcion, entonces nunca voy a estar cuidandome si pongo otro bloque después, si muevo ese bloque para otro lado o lo elimino, entonces queda un codigo multitarea y muy facil de trabajar





 

anything