Autor Tema: Sistemas operativos en PIC  (Leído 124776 veces)

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

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: Sistemas operativos en PIC
« Respuesta #45 en: 15 de Febrero de 2007, 22:26:01 »
hola reinelt, pues realmente estoy empezando a usar el RTOs de CCS. el que estas explicando. Y pues serian preguntas ya un poco mas especificas, ya que las enfocaria al proyecto que estoy desarrollando.

Saludos!

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Sistemas operativos en PIC
« Respuesta #46 en: 16 de Febrero de 2007, 10:30:24 »
Teniendo en cuenta el post anterior y el hecho de que diseñar aplicaciones con el uso de RTOS no es lo mismo que recibir un curso acerca de como utilizar un RTOS, ni el propio diseño y programación de un RTOS es que abrí el hilo: Discusión sobre RTOS

A los foreros que quieran hacer preguntas, sobre el diseño de aplicaciones con RTOS, les pido de favor que se dirijan al nuevo hilo para hacer sus preguntas. La razón es sencilla, tener lo más aseado posible este hilo, de modo que los que nos visiten con la intención de aprender algo, no tengan que leerse un montón de posts, que no vienen al caso.

Nos vemos el lunes con la próxima entrega, ya tengo pensado como enfocar el tema

Saludos Reinier
« Última modificación: 16 de Febrero de 2007, 10:33:02 por reiniertl »

Desconectado Darukur

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 464
    • Informacion, recursos y ejemplos para desarrollos con microcontroladores
Re: Sistemas operativos en PIC
« Respuesta #47 en: 18 de Febrero de 2007, 02:50:17 »
Mi pequeño aporte a este post:

"Libro Sistemas Operativos - Tanenbaum"

Es el "must have" de todos los libros relacionados a los sistemas operativos.
Este es el punto de partida.

Saludos

Editado por Nocturno: Darukur, he borrado el link
« Última modificación: 18 de Febrero de 2007, 03:50:36 por Nocturno »
El que no sabe lo que busca no entiende lo que encuentra.
Mi Pagina Web:  http://www.sistemasembebidos.com.ar
Mi foro:             http://www.sistemasembebidos.com.ar/foro/

Desconectado Darukur

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 464
    • Informacion, recursos y ejemplos para desarrollos con microcontroladores
Re: Sistemas operativos en PIC
« Respuesta #48 en: 19 de Febrero de 2007, 09:28:47 »
Esta bien, disculpas. Entiendo.

Saludos.
El que no sabe lo que busca no entiende lo que encuentra.
Mi Pagina Web:  http://www.sistemasembebidos.com.ar
Mi foro:             http://www.sistemasembebidos.com.ar/foro/

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Sistemas operativos en PIC
« Respuesta #49 en: 19 de Febrero de 2007, 14:28:15 »
Coordinar para no dañar

Hasta ahora hemos visto al RTOS como un elemento que nos ayuda a “simplificar” el código de nuestra aplicación. Por una parte, dejándole parte de la temporización de las tareas que debe realizar nuestra aplicación y por otra utilizando el tiempo de las demoras ocupadas para hacer que otras tareas ejecuten su código en ese tiempo. Sin embargo esas ventajas no son nada comparado con dos herramientas fundamentales que nos ofrecen los SO: la coordinación y la sincronización, de ellas hoy vamos a ver solamente una de ellas la coordinación.

La coordinación es un término en la programación para SO, que se basa en la protección de recursos compartidos, es un concepto orientado a evitar que diferentes tareas puedan acceder a los datos o recursos y poner al sistema en un estado inestable o inseguro.

Ejemplos que ponen de manifiesto el problema de la coordinación hay muchísimos pero en aras de mantener el curso lo más sencillo posible y adecuarlo un poco más a las aplicaciones que normalmente se nos presentan yo utilizaré un problema más cercano a nuestro entorno.

El problemas de la coordinación también se conoce como el problema de la concurrencia o acceso concurrente a recursos, a mi me gusta llamarlo “coordinación” para establecer una mejor diferencia con respecto al otro mecanismo; el de la “sincronización” que veremos en la próxima entrega.

Destripando un poco más a la coordinación diremos que: la coordinación es el mecanismo que debe implementar un SO para asegurar el acceso seguro a recursos compartidos del sistema, y que no tiene en cuenta restricciones temporales. Con esto queda claro que proteger a los recursos de un acceso no seguro es lo más importante en la coordinación, no importa durante que tiempo alguien (una tarea) esté utilizando el recurso, hasta que no lo libere nadie más podrá utilizarlo.
Hay mecanismos de coordinación que implementan también el problema de la sincronización, que si tiene en cuenta el factor tiempo, pero el RTOS de CCS no los implementa. Esto puede considerarse una limitante o una ventaja, según el tipo de aplicación en que se vaya a utilizar.

Un RTOS que implementa un mecanismo de coordinación con sincronización es el LMOS de Darukur, que veremos dentro de algún tiempo en este foro, debidamente documentado gracias a un proyecto que Darukur y un servidor, llevaremos a ustedes. Por el momento este simple cursillo es un buen método (no el único) para acercarse al mundo de los RTOS.
Veamos la coordinación con un ejemplo sencillo pero bien claro.

Supongamos que una madre ha comprado una camisa muy bonita, ella quería comprar dos, pero en la tienda solo había una así que decidió comprarla de todas formas. Cuando llegó a casa llama a sus hijos (ambos usan la misma talla de camisa), y les dice: “he comprado esta camisa, pero en la tienda solamente había una, así que deben compartirla como buenos hermanos”.

Las palabras de la madre no son alentadoras porque a ambos les gusta mucho la camisa y sin embargo deben compartirla, entonces la decisión de ambos es colocar la camisa en una percha, y cada vez que uno de los dos decida utilizarla se la ponga (dejando el perchero vacío). Pero hay una regla adicional, si cuando uno de los dos va a utilizar la camisa el otro ya se la llevó dejará una marca para indicarle al otro hermano que no podrá utilizar la camisa hasta que el que la marcó haya hecho uso de ella.

Este es un mecanismo en que los hermanos se han puesto de acuerdo para utilizar un recurso (la camisa), de manera compartida (porque es la única), de forma coordinada (para eso se pusieron de acuerdo e hicieron unas reglas simples).
Para implementar las reglas mostradas en el ejemplo anterior, el RTOS de CCS tiene dos funciones rtos_wait() y rtos_signal().

Para utilizar estas funciones primero hay que crear una variable entera que hará las funciones de percha y, que hablando con propiedad, se llama semáforo. El semáforo es el elemento que le permite a la tarea reclamar el recurso compartido o esperar por él si ya está en uso. Las funciones rtos_wait() y rtos_signal() se utilizan para marcar el momento de inicio y fin del código que utiliza el recurso compartido. A la sección de código que utiliza el recurso compartido se le conoce como sección crítica.

Veamos como funciona esto en términos de programación:
Usted crea una variable entera que será su semáforo o marcador de uso del recurso compartido.
El recurso compartido puede ser una o varias variables del sistema, en este caso el recurso compartido es un recurso de memoria. O puede ser un periférico del sistema, como es el caso del puerto serie o la memoria EEPROM, o cualquier otro.
rtos_wait() y rtos_signal() son los marcadores de inicio y fin del código que hace uso de nuestro recurso compartido.

Cuando se inicia el programa usted inicializa el semáforo en algún valor positivo que determina la cantidad de tareas que pueden utilizar el recurso al mismo tiempo, normalmente es uno para las tareas que modificarán el recurso compartido, mientras que para tareas que solamente leen datos puede que no se usen secciones críticas o se permita más de una tarea que acceda simultáneamente al recurso compartido.

Cuando una tarea llegue a la sección de código que hace uso del recurso compartido, debe, primero que nada, ejecutar la función rtos_wait(sem). Si el semáforo es mayor que cero, el RTOS decrementará la variable y permitirá que la tarea continúe su ejecución, sin embargo si el semáforo está en cero, el RTOS le quitará el procesador a la tarea y se lo cederá a otra que le toque ejecutarse. Cuando le corresponda nuevamente a la tarea que pidió el acceso al recurso compartido, el RTOS comprobará el estado del semáforo, si éste es mayor que cero, lo decrementará y le dará el procesador a la tarea para que se siga ejecutando, si no, volverá a dormir a la tarea hasta el próximo turno y así sucesivamente.

Al final del código de la sección crítica hay que colocar un rtos_signal(sem) para que el RTOS incremente el semáforo permitiendo que otra tarea pueda utilizar el recurso compartido.

El ejemplo de hoy es el siguiente:
Elabore un programa para un PIC16F877 que permita mantener actualizada la cantidad de botellas que hay en un tramo de cinta transportadora en una embotelladora. La cinta es alimentada desde un almacén de botellas que tiene un robot que incrementa la variable Cantidad cada vez que coloca una botella en la cinta, mientras que dos robots llenadores de cajas, decrementan en 12 la variable cantidad cada vez que toman 12 botellas de la cinta transportadora. Como es de suponer el robot despachador debe llenar la cinta más rápido de lo que los robots llenadores la vacían. En la próxima entrega utilizaremos la sincronización para resolver el problema de que la cinta se quede vacía o se llene demasiado rápido. Como datos adicionales suponga que el robot despachador despacha una botella cada 250ms y que los robots llenadores llenan una caja cada 6 segundos. El robot despachador está conectado a RB0 y cada vez que pone una botella en la cinta transportadora le da un pulso al microcontrolador para indicárselo. Los robots llenadores están conectados uno a RB1 y el otro a RB2 e igualmente dan un pulso al microcontrolador cada vez que despachan una caja. La duración del pulso es de 100ms.

Como es de suponer este problema lo podemos resolver de muchas maneras y lógicamente sin el uso de los RTOS, pero eso se los dejo de tarea. Además el mecanismo de notificación de cada robot es un poco deficiente, pero ese no es el tema de este curso, aunque en su momento pondremos un ejemplo mejor al respecto, cuando rescatemos a las interrupciones del olvido.

Analicemos un poco en detalle el problema: Supongamos que la tarea asociada al robot despachador comienza a ejecutarse, lee el valor de la variable Cantidad, 100 botellas, y se va adormir esperando que el robot le notifique que ha puesto una botella en la cinta, en ese momento el RTOS le da permiso a la tarea del robot llenador 1 para que ejecute su código, ésta se da cuenta que el robot llenó una caja por lo que lee la variable Cantidad y le resta 12 botellas, quedando Cantidad = 88 botellas. Ahora le toca de nuevo a la tarea del robot despachador ejecutarse y como ya se despachó una botella le suma uno al valor previamente leído y actualiza la variable Cantidad, quedando 101 botellas, lo cual es falso.

Este ejemplo puede mejorarse semánticamente y evitarnos el uso de la sección crítica, todo ello gracias a que nuestro RTOS es cooperativo y en este caso, mientras la tarea esté ejecutándose tiene todos los recursos para ella sola hasta que entregue el procesador.

Por lo tanto podemos escribir el código de modo que no haya ningún rtos_yield() intercalado con el código que accede a un recurso compartido, de esta forma la tarea se asegura el uso exclusivo del recurso compartido… a no ser que aparezcan las interrupciones en la palestra y las cosa se complique. Sin embargo en un sistema de tiempo compartido (los hay para PIC, ejemplo de ellos es el FreeRTOS), donde no sabemos cuando el RTOS nos quitará el procesador el uso de secciones críticas es OBLIGATORIO, para evitar problemas como los mostrados, y por eso es importante que dominemos esta técnica.

Por otro lado el uso de Periféricos puede complicar más las cosas que el uso simple de la memoria y puede ocurrir que para ser eficientes estemos obligados a poner un rtos_yield() dentro del código de la sección crítica. Moraleja: aprenda a programar con secciones críticas o no programe con RTOS.

El código:
Código: C
  1. #include "D:\Documentos\Projects\RTOS\RTOS.h"
  2. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
  3. #use RTOS(timer=0, minor_cycle=10ms)
  4. int8 semaphore; //Este es nuestro semáforo
  5. int16 iCantidad; //Esta es la cantidad de botellas en la estera
  6.                  //constituye nuestro recurso compartido
  7.  
  8. #task (rate=50ms, max=10ms)
  9. void R_Despachador();
  10.  
  11. #task (rate=50ms, max=10ms)
  12. void R_Llenador1();
  13.  
  14. #task (rate=50ms, max=10ms)
  15. void R_Llenador2();
  16.  
  17. void main()
  18. {  
  19.    semaphore = 1; //Solo una tarea puede utilizar el recurso cada vez
  20.    iCantidad = 100; //Inicializamos esta variable para tener algunas botellas en
  21.                     //la estera.
  22.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  23.    rtos_run();
  24.  
  25. }
  26.  
  27.  
  28. void R_Despachador()
  29. {
  30.  int Botellas;
  31.  rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc crítica
  32.  Botellas = iCantidad; //Leemos la cantidad de botellas a una variable temporal
  33.  
  34.  if(input(PIN_B0)==1)
  35.       {
  36.         Botellas++;           //Ya sabemos que este código no es eficiente pero
  37.         iCantidad = Botellas;  //sí es didáctico y por eso lo he utilizado así.
  38.       }
  39.  
  40.  rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica
  41.  
  42.  rtos_yield(); // A dormir por otros 100ms para evitar poner dos veces la misma botella
  43. }
  44.  
  45.  
  46. void R_Llenador1()
  47. {
  48.  rtos_wait(semaphore);
  49.  if(input(PIN_B1)==1)
  50.     iCantidad -= 12; //Este sí es un código lógico, pero entonces el despachador
  51.                        //no nos daría problemas aunque nos vayamos a dormir dentro de
  52.                        //la sección crítica.
  53.      
  54.  rtos_signal(semaphore);
  55.  rtos_yield();
  56. }
  57.  
  58. void R_Llenador2()
  59. {
  60.  rtos_wait(semaphore);
  61.  if(input(PIN_B2)==1)
  62.      iCantidad -= 12;
  63.      
  64.  rtos_signal(semaphore);
  65.  rtos_yield();
  66. }

Este programa lo simulé en Proteus poniendo en RB0 una fuente digital de tipo pattern con los siguientes parámetros:
First Edge at (Secs)=1
Desmarcar el check mark: Equal Mark/Space Timing?
‘Mark’ Time (Secs) = 100m
‘Sapce’ Time(Secs) = 150m
Marcar el check mark: Continuos Secuence of Pulses
Marcar el check mark: Standard Hig-Low Pulse Train
Para RB1 y RB2 se utiliza una fuente del mismo tipo con los siguientes parárametros cambiados
Para RB1:
First Edge at (Secs)=5
‘Mark’ Time (Secs) = 100m
‘Sapce’ Time(Secs) = 5.9
Para RB2:
First Edge at (Secs)=7
‘Mark’ Time (Secs) = 100m
‘Sapce’ Time(Secs) = 5.9
Simulen y vean como cada vez que se pasa por rtos_wait() y si el semáforo es mayor que cero, se decrementa y se entra en la sección crítica, si el semáforo es 0 entonces la tarea espera a que esté disponible el recurso (semáforo>0) para ejecutar el código de la sección crítica.
Espero que lo disfruten.
Saludos Reinier

Desconectado lous

  • PIC10
  • *
  • Mensajes: 5
Re: Sistemas operativos en PIC
« Respuesta #50 en: 19 de Febrero de 2007, 18:59:22 »
MUUY INTERESANTE

Por fin veo aplicaciones practicas de lo que me enseñan en clase de SO.

Desconectado Darukur

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 464
    • Informacion, recursos y ejemplos para desarrollos con microcontroladores
Re: Sistemas operativos en PIC
« Respuesta #51 en: 19 de Febrero de 2007, 20:41:38 »
Muy buena la explicacion de semaforos y recursos compartidos.
Todavia no he utilizado mucho los RTOS preemptivos asi que no conozco mucho (salvo en windows con las secciones criticas  :mrgreen:)
En un RTOS cooperativo, la parte critica del codigo es manejada directamente por la misma tarea, con lo que puede haber problemas de reversion de prioridades (una tarea de baja prioridad gana el procesador pero como no lo relega a tiempo, una tarea mas prioritaria no se esta ejecutando en tiempo y forma)

Saludos
El que no sabe lo que busca no entiende lo que encuentra.
Mi Pagina Web:  http://www.sistemasembebidos.com.ar
Mi foro:             http://www.sistemasembebidos.com.ar/foro/

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Sistemas operativos en PIC
« Respuesta #52 en: 20 de Febrero de 2007, 10:18:38 »
Es cierto que el problema de los recursos compartidos en el los SO cooperativos no es gran problema, porque cada tarea tiene que ceder el procesador y eso le permite al programador programar su código con una semántica que evite tener secciones críticas. No ocurre así  con los SO preentivos o de tiempo compartido, donde el SO es quién le quita el procesador a las tareas si estas se están haciendo las listas y quieren apoderarse del procesador por mucho tiempo.

Lo de las secciones críticas en los SO cooperativos, se cumple, al menos en teoría. Ya que cuando decidimos utilizar un periféricos lento,  ejemplo de ese tipo es la EEPROM que demora 10ms en hacer una escritura, y que valiosos pueden ser esos 10 ms; lo lógico es que después de mandar a escribir un datos pongamos a dormir a la tarea hasta que la escritura esté completada y no podemos permitir BAJO NINGÚN CONCEPTO que otra tarea acceda a la memoria EEPROM.

Otro caso en el que estamos casi obligados a utilizar las secciones críticas es cuando utilizamos las interrupciones para atender a procesos o dispositivos rápidos, aquí la interrupción provoca un cambio de contexto de cualquier tarea que esté en ejecución, y si nuestros recursos no están debidamente protegidos, podemos tener problemas.

Por supuesto lo mejor es no confiarse y si hace falta utilizar una sección crítica para proteger recursos compartidos es una buena práctica.

Saludos Reinier

Desconectado SimonMG

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 172
Re: Sistemas operativos en PIC
« Respuesta #53 en: 20 de Febrero de 2007, 11:05:28 »
http://www.uclinux.org/

me gusto mucho esta paguina, espero que los ayude tambien a ustedes con su proyecto
"La politica es para ahora, una ecuacion es para siempre"
Albert Einstein

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Sistemas operativos en PIC
« Respuesta #54 en: 22 de Febrero de 2007, 18:45:25 »
Hola, por problemas con retrasos en unas tareas y un examen que debo de la maestría no podré postear la próxima entrega hasta después del martes, pero no se desanimen que no los voy a dejar a medias.

Reinier

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18269
    • MicroPIC
Re: Sistemas operativos en PIC
« Respuesta #55 en: 22 de Febrero de 2007, 18:48:49 »
Será larga la espera, pero seguro que merece la pena. Por aquí te esperamos.

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
Re: Sistemas operativos en PIC
« Respuesta #56 en: 26 de Febrero de 2007, 17:46:28 »
Hola amigos:

Mañana martes 27 tengo mi examen de SO por la mañana, así que espero que por la tarde o el miércoles tenga listo el post sobre la sincronización, disculpen que no haya posteado antes pero es que esta tarea requiere concentración y tiempo para que quede bien. Así que a preparar los compiladores y los sesos que lo que traigo es "coquito con mortadella". Un saludo freternal

Reinier

Desconectado reiniertl

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 1187
En sus marcas, listos, ¡FUERA!
« Respuesta #57 en: 28 de Febrero de 2007, 15:39:39 »
En sus marcas, listos, ¡FUERA!
Un momento, un momento, no tan rápido que, hay una salida en falso del corredor del carril No. 2.

En un caso como el anterior diríamos que ha fallado la sincronización de los corredores en el arranque, y la sincronización es el tema que vamos a tratar hoy en nuestro cursillo de los RTOS para uC.

En el mundo de los uC es frecuente la utilización de demoras para esperar a que ocurran ciertos hechos o eventos, para en consecuencia hacer algo. La duración de estas demoras puede ser conocida, como en el caso de esperar a que una LCD coloque los datos en determinados registros antes de enviarle otro dato, o esperar a que la USART saque un dato que está transmitiendo antes de poder escribir nuevamente en el registro de transmisión; sin embargo también son frecuentes aquellas esperas en las que no sabemos cuanto podemos demorarnos.

En los casos en que no conocemos cuanto debemos esperar se pueden utilizar las interrupciones, pero en los uC no tenemos interrupciones ilimitadas ni tampoco existe una biblioteca de mecanismos de interrupción disponibles para todos los casos que se nos presentan. Es por estas razones que muchas veces esperamos a la ocurrencia de estos eventos haciendo suposiciones y blandiendo demoras.

Para la implementación de demoras existen varios mecanismos más o menos eficientes, sin embargo un SO no nos ofrece este tipo de mecanismos que podemos llamar un poco primitivos. Para la implementación de demoras eficientes los SO han creado los mecanismos de sincronización de procesos.

En la entrega anterior vimos la coordinación, en realidad los autores de los libros más reconocidos en el tema de los SO, han llamado a estos mecanismos y al que veremos hoy, “mecanismos de sincronización de procesos”, pero a mi me gusta distinguir entre aquellos que se dedican especialmente a implementar esperas eficientes para la protección de recursos, de aquellos que se dedican a implementar esperas eficientes para eventos por los cuales un proceso debe esperar antes de continuar su ejecución. Notemos que en ambos casos la tarea o proceso debe esperar, pero no en todos los casos la espera tiene la misma naturaleza, en uno esperamos por un recurso físico al que queremos acceder y que no está disponible, en el otro esperamos a que se produzcan ciertos hechos que determinan el “estado” del sistema.

Vamos a utilizar como referencia el problema anterior para ver el mecanismo de la sincronización en ejecución. Supongamos ahora que le hemos colocado a nuestros robots una entrada que cuando está en nivel bajo le indica al robot que no coloque o extraiga botellas de la cinta transportadora. Con este mecanismo simple vamos a tratar, por un lado, de evitar que el robot despachador de botellas llene demasiado la cinta y por el otro que los robots llenadores de cajas traten de llenar las cajas cuando no hay suficientes botellas en la cinta transportadora. Es decir, vamos sincronizar el proceso de llenado/vaciado de la cinta transportadora. Las ventajas de esto son evidentes, por ejemplo: si el robot llenador no tiene botellas que poner en la cinta los robots llenadores trabajarán hasta que la cantidad de botellas se lo permita; si los robots llenadores dejan de trabajar, entonces el robot despachador trabajará hasta que llene la cinta transportadora.

Para lograr lo anterior, vamos a poner que la cantidad máxima de botellas que pueden estar en la cinta es de 100 y que la cantidad mínima de botellas es 24, por lo que cada una de las tareas que atiende a los robots deberá, además de llevar la actualización del total de botellas en la cinta, indicarle a los robots que se detengan cuando la cantidad de botellas en la cinta esté fuera del rango especificado. Además vamos a utilizar el puerto serie para Tx la cantidad de botellas que hay en la cinta en cada momento.

Las entradas a los robots (salidas de nuestro PIC) las hemos colocado en los pines RB3..RB5, en RB3 al robot despachador, en RB4 al robot llenador1 y en RB5 al robot llenador2

Para hacer la sincronización de tareas el RTOS de CCS nos ofrece una sola función, aunque parezca poco esta función es bien poderosa, vamos a verla con más detenimiento. La función se llama rtos_await(expr) lo que tienes que pasarle es una expresión lógica que la función evaluará, si esta resulta verdadera entonces continúas la ejecución normal de tu programa, si te devuelve falso, entonces rtos_await() le cederá el procesador al RTOS y la tarea quedará bloqueada hasta que exp se cumpla para entonces continuar en la línea siguiente a la llamada a la función.

Ahora bien, es cierto que esta función es poderosa y simple, pero eso implica que tenemos que saber donde ponerla, ya que si no evaluamos bien nuestras expresiones o no colocamos la función en el lugar adecuado, estaremos sometiéndonos a riesgos durante la ejecución de nuestro código. Por ejemplo puede ocurrir que alguna tarea se quede bloqueada esperando por siempre a que la expresión lógica se evalúe de verdadera y esto nunca ocurra o que la expresión esté mal diseñada y la tarea no se bloquee cuando haga falta. Bien todos esos problemas los veremos más adelante cuando la señorita Némesis (diosa griega de la venganza y la fortuna) haga acto de presencia para echarnos a perder toda la dicha que los RTOS traen al mundo de la programación con uC.

He puesto el código fuente y la simulación con Proteus en la siguiente dirección: Código fuente y simulación cuando corran el ejemplo noten como la cantidad de botellas en la cinta va descendiendo hasta que al llegar a las 24 botellas, después la cantidad de botellas en la cinta se mantendrá más o menos sobre las 20 y nunca por debajo de 12. Las compuertas AND de conjunto con las formas de onda hacen la función de los robots.

Código: C++
  1. #include "D:\Documentos\Projects\RTOS\RTOS.h"
  2. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
  3. #use RTOS(timer=0, minor_cycle=10ms)
  4. int8 semaphore; //Este es nuestro semáforo
  5. int16 iCantidad; //Esta es la cantidad de botellas en la estera
  6.                  //constituye nuestro recurso compartido
  7.  
  8. #task (rate=50ms, max=10ms)
  9. void R_Despachador();
  10.  
  11. #task (rate=50ms, max=10ms)
  12. void R_Llenador1();
  13.  
  14. #task (rate=50ms, max=10ms)
  15. void R_Llenador2();
  16.  
  17. void main()
  18. {
  19.    semaphore = 1; //Solo una tarea puede utilizar el recurso cada vez
  20.    iCantidad = 120; //Inicializamos esta variable para tener algunas botellas en
  21.                     //la estera, normalmente deberiamos tener un sensor que nos reporte
  22.                     //en algun momento el total de botellas en la cinta, ya que un
  23.                     //robot revisor de llenado o una persona puede retirar botellas
  24.                     //de la cinta
  25.  
  26.    //Al comenzar todos los robots estan deshabilitados
  27.    output_bit( PIN_B3, 0);
  28.    output_bit( PIN_B4, 0);
  29.    output_bit( PIN_B5, 0);
  30.  
  31.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  32.    rtos_run();
  33.  
  34. }
  35.  
  36.  
  37. void R_Despachador()
  38. {
  39.  //Note como hacemos la sincronizacion fuera de la seccion critica, mas adelante veremos
  40.  //que esto no siempre es posible hacerlo o que las cosas se complican un poco mas
  41.  //de lo que hemos visto hasta ahora.
  42.  rtos_await(iCantidad<100); //Esperemos a que se vacie un poco la cinta
  43.  
  44.  output_bit( PIN_B3, 1); //A partir de aqui, si no se podia antes,  poner botellas
  45.  
  46.  rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc crítica
  47.  
  48.    if(input(PIN_B0)==1)
  49.         iCantidad++;  //sí es didáctico y por eso lo he utilizado así.
  50.  
  51.    if(iCantidad >= 100)
  52.        output_bit( PIN_B3, 0); //Le decimos al robot despachador que no ponga mas botellas
  53.  
  54.  rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica
  55.  
  56.  printf("%3.0w \r",iCantidad);
  57.  rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella
  58. }
  59.  
  60.  
  61. void R_Llenador1()
  62. {
  63.   //El robot debe esperar a que la cinta tenga suficientes botellas para sacar antes
  64.   //de comenzar a trabajar.
  65.   rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta
  66.   output_bit( PIN_B4, 1); //A partir de aqui, si no se podia antes, sacar botellas
  67.  
  68.  rtos_wait(semaphore);
  69.  
  70.  if(input(PIN_B1)==1)
  71.     iCantidad -= 12;
  72.  
  73.  if(iCantidad <= 24)
  74.     output_bit( PIN_B4, 0); //Le decimos al robot que no saque mas botellas
  75.  
  76.  rtos_signal(semaphore);
  77.  
  78.  printf("%3.0w \r",iCantidad);
  79.  rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella
  80.  
  81. }
  82.  
  83. void R_Llenador2()
  84. {
  85.  rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta
  86.  output_bit( PIN_B5, 1); //A partir de aqui, si no se podia antes, sacar botellas
  87.  
  88.  rtos_wait(semaphore);
  89.  
  90.  if(input(PIN_B2)==1)
  91.      iCantidad -= 12;
  92.  
  93.  if(iCantidad <= 24)
  94.     output_bit( PIN_B5, 0); //Le decimos al robot que no saque mas botellas
  95.  
  96.  rtos_signal(semaphore);
  97.  
  98.  printf("%3.0w \r",iCantidad);
  99.  rtos_yield();
  100. }

Hasta ahora solamente hemos visto ventajas del uso de los RTOS, sin embargo el uso de estas herramientas presupone un montón de complicaciones que he tratado de no mostrar hasta el momento, en aras de mostrar lo útil que puede ser un RTOS, pero aún con esas complicaciones el uso de los RTOS sigue siendo una bendición para cualquier desarrollador de sistemas con uC. Simplemente tendremos que ser un poco más cuidadosos con la semántica de nuestros programas y pensar un poco más en la concepción y modelación de las soluciones a nuestros problemas.

En la próxima entrega vamos a ver el uso de las funciones para el paso de mensajes entre tareas, que es otra de las ventajas que los RTOS traen al mundo de la programación para uC y cuando terminemos de ver todas esas cosas buenas comenzaremos a estudiar las desgracias y cómo enfrentarlas.

Un saludo y espero que lo disfruten.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18269
    • MicroPIC
Re: Sistemas operativos en PIC
« Respuesta #58 en: 28 de Febrero de 2007, 15:48:36 »
Un saludo y espero que lo disfruten.

Yo estoy disfrutando sólo con la lectura de tus artículos. Espero gozar probando los RTOS cuando acabe este cursillo, siempre que haya finalizado mi proyecto actual.

Me sorprende lo simple de los conceptos, por la potencia que ofrecen cuando están bien combinados.

Nuevamente gracias, Reinier.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5470
    • Electrónica Didacta
Re: Sistemas operativos en PIC
« Respuesta #59 en: 28 de Febrero de 2007, 15:51:28 »
voy a tener que imprimir estos articulos, sale mejor que leerlos directo desde el monitor.  :lol:

¡Gracias por tu empeño  reiniertl !

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek