sistema operativo micro control adores pic rtos

22
1 de 22 Ultima actualización: 07/03/2007 Sistemas Operativos para microcontroladores RTOS para PIC INTRODUCCIÓN: Gracias a la labor del amigo Reinier Torres Labrada , del foro sobre microcontroladores TODOPIC , ponemos en uControl esta Introducción a los Sistemas Operativos para Microcontroladores. Realmente, Reinier esta haciendo un muy buen trabajo con este tema, y debido a que no hay demasiada información sobre RTOS para PIC en español, es que vamos a ir recopilando en esta pagina sus post sobre el tema . Como podrán ver, abundan los ejemplos, y sus explicaciones son muy claras. ÍNDICE: > Introducción > Presentación de la guía > Un poco de teoría sobre los Sistemas Operativos (SO) > Diferencias entre usar un SO o usar las librerías del compilador de turno > ¿Qué es un Sistema Operativo? > Clasificación de los SO > Introducción al RTOS de CCS > Funciones del RTOS > Controlando la ejecución de las tareas > Yield vs delay > Coordinar para no dañar > En sus marcas, listos, ¡FUERA! > RTOS mail > Datos de Contacto > Bibliografía > Presentación de la guía: Las siguientes son palabras de Reinier, presentando en el foro su idea de armar esta Introducción a los Sistemas Operativos para Microcontroladores: "Hola amigos He visto que en el hilo "RTOS para PIC GNU " ha aparecido una interesante controversia sobre los RTOS, sin embargo lo que más curioso me resulta es que muchos no conocen prácticamente nada sobre el tema, y como aquí todos estamos para aprender y compartir lo poco que sabemos, quisiera comenzar por explicar algunos de los principios básicos de los SO y como podemos aplicarlos al campo de los microcontroladores. Espero que esta nueva idea sea de utilidad y despierte el interés en muchos de ustedes. Yo soy muy nuevo en este campo de los SO y los microcontroladores, pero con la ayuda de ustedes podremos hacer muchas cosas interesantes y beneficiosas para todos. De hecho todavía no he comenzado a utilizar ningún RTOS o algo parecido para meter en un PIC, ni siquiera me he metido con el código de ningún SO, pero en la maestría que estoy cursando tengo los SO (desde la óptica del diseño) como asignatura obligada y no quisiera que después de un montón de horas delante de un profesor que produce más sueño que interés por su asignatura (aunque el tema es interesantísimo), todo ese conocimiento se quedara en la nota al final del semestre. Bueno amigos... sin más muela (preámbulo) comencemos a trabajar" [Volver al Índice] > Un poco de teoría sobre los Sistemas Operativos (SO) Haciendo un poco de historia, y los más añejaditos lo saben mejor que yo que soy un niño de 26, los SO aparecieron más o menos por allá por los 60. Lo que ocurrió por aquel entonces, cuando las computadoras, eran tan “poderosas” como nuestros PIC’s (algunos de gama alta son hasta más poderosos que aquellas computadoras), era que muchos programadores (matemáticos locos la mayoría), no estaban interesados en conocer los detalles de las interfaces, controladores

Upload: nereu-oliveira

Post on 26-Jun-2015

372 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Sistema Operativo Micro Control Adores Pic Rtos

1 de 22

Ultima actualización:07/03/2007

Sistemas Operativos paramicrocontroladores

RTOS para

PIC

INTRODUCCIÓN:Gracias a la labor del amigo Reinier Torres Labrada, del foro sobremicrocontroladores TODOPIC, ponemos en uControl estaIntroducción a los Sistemas Operativos paraMicrocontroladores.

Realmente, Reinier esta haciendo un muy buen trabajo con estetema, y debido a que no hay demasiada información sobre RTOS paraPIC en español, es que vamos a ir recopilando en esta pagina sus postsobre el tema. Como podrán ver, abundan los ejemplos, y susexplicaciones son muy claras.

ÍNDICE:> Introducción> Presentación de la guía> Un poco de teoría sobre los Sistemas Operativos (SO)> Diferencias entre usar un SO o usar las librerías del compilador de turno> ¿Qué es un Sistema Operativo?> Clasificación de los SO> Introducción al RTOS de CCS> Funciones del RTOS> Controlando la ejecución de las tareas> Yield vs delay> Coordinar para no dañar> En sus marcas, listos, ¡FUERA!> RTOS mail

> Datos de Contacto> Bibliografía

> Presentación de la guía:Las siguientes son palabras de Reinier, presentando en el foro su idea de armar esta Introducción a losSistemas Operativos para Microcontroladores:

"Hola amigos

He visto que en el hilo "RTOS para PIC GNU" ha aparecido una interesante controversia sobre los RTOS, sinembargo lo que más curioso me resulta es que muchos no conocen prácticamente nada sobre el tema, y comoaquí todos estamos para aprender y compartir lo poco que sabemos, quisiera comenzar por explicar algunos delos principios básicos de los SO y como podemos aplicarlos al campo de los microcontroladores.

Espero que esta nueva idea sea de utilidad y despierte el interés en muchos de ustedes. Yo soy muy nuevo eneste campo de los SO y los microcontroladores, pero con la ayuda de ustedes podremos hacer muchas cosasinteresantes y beneficiosas para todos.

De hecho todavía no he comenzado a utilizar ningún RTOS o algo parecido para meter en un PIC, ni siquierame he metido con el código de ningún SO, pero en la maestría que estoy cursando tengo los SO (desde laóptica del diseño) como asignatura obligada y no quisiera que después de un montón de horas delante de unprofesor que produce más sueño que interés por su asignatura (aunque el tema es interesantísimo), todo eseconocimiento se quedara en la nota al final del semestre.

Bueno amigos... sin más muela (preámbulo) comencemos a trabajar"

[Volver al Índice]

> Un poco de teoría sobre los Sistemas Operativos (SO)Haciendo un poco de historia, y los más añejaditos lo saben mejor que yo que soy un niño de 26, los SOaparecieron más o menos por allá por los 60.

Lo que ocurrió por aquel entonces, cuando las computadoras, eran tan “poderosas” como nuestros PIC’s(algunos de gama alta son hasta más poderosos que aquellas computadoras), era que muchos programadores(matemáticos locos la mayoría), no estaban interesados en conocer los detalles de las interfaces, controladores

Page 2: Sistema Operativo Micro Control Adores Pic Rtos

2 de 22

(matemáticos locos la mayoría), no estaban interesados en conocer los detalles de las interfaces, controladoresy demás cacharros electrónicos que adornan a una computadora, y por otro lado algunos programadores yahabían escrito controladores para esos dispositivos y por tanto los que venían detrás simplemente queríanutilizarlos y ya (algo parecido a lo que hacemos en el foro).

Pues bien, con el tiempo se acumularon programas útiles para manejar dispositivos y tareas complejas quedebían programar personas no interesadas en la electrónica, entonces la gente, que trabajaba en equipo,organizó todo aquello de manera que los programadores, los programas y el hardware (HW) pudieran coexistirsin que se produjera una guerra hubiteana (guerra en la que los hombres y los bits se pelean hasta que loshombres se mueren de alguna clase de infarto o pierden a la mujer). Surgieron así los primeros intentos decrear un SO y los hombres mantuvieron la Paz sobre la tierra y también la guerra “fría”, aunque las cosas secalentaran a intervalos.

Pasó el tiempo y llegó Bill Gates con DOS y luego Windows y Steve Jobs con su Mac, unos tipos más listos ycabrones que ingenieros o programadores…. y después también apareció Linus Torvalds con Linux, uno queestaba más loco que El Quijote y entonces las personas corrientes creyeron que en el mundo solo existen a losumo tres SO (Windows, Mac, y Linux), pero no es así hay un montón de SO, algunos muy poderosos y otrosno tanto, dependiendo de en que lugar y para que se hayan diseñado.

Como es lógico suponer, en la parte de la historia que les acabo de contar está el por qué los SO son útiles,pero eso lo iremos viendo poco a poco porque hay muchas formas en las que un SO nos puede servir. Vamos aver algunas:

1) Un SO convierte a las computadoras en equipos útiles.Pone una o varias capas de Software (SW) sobre el HW, y con eso podemos escribir programas y utilizarprogramas ya escritos por otros para hacer otros programas escritos por nosotros mismos, sin tener quemeternos en detalles tales como “bueno ahora mi procesador de textos ya trabaja ¿y como guardo eldocumento?”. Seguramente si usted le dice al programador del procesador de texto que para guardar eldocumento tiene que tirarse meses escribiendo las rutinas que guardan el doc. seguramente le da un ataque.

2) Un SO es una herramienta poderosa en la gestión de procesos. Nosotros mismos cuando programamos los PIC´s tenemos que leer el puerto serie, escribir en una LCD,controlar el motor y todas esas cosas “las hacemos a la vez”. Pero cada una de esas tareas podemosconsiderarla un proceso, y un SO puede ayudarnos a gestionarlos eficientemente, aprovechando al máximo elprocesador. Por ejemplo en vez de poner al PIC a esperara a que el motor se mueva un poco poniendo unademora, podemos utilizar ese tiempo en ir escribiendo un poco en la LCD y después volver a donde nosquedamos con el motor.

3) Un SO nos ayuda a diseñar más rápido sistemas mas complejos. Imagínense ahora una aplicación donde tengamos que hacer cálculos, encender y apagar cosas, comunicarnoscon otros dispositivos y otras tareas más, y que además tengamos que hacerlo rápido y trabajando con otraspersonas. Entonces el concepto de divide y vencerás nos pude ser útil y un SO es el arma que podemos utilizarpara derrotar a nuestros enemigos: el tiempo y la complejidad. Pues sí nos auxiliamos del SO para dividir ygestionar los procesos, y con ello no eliminamos la complejidad pero le damos una vuelta elegante, y nomatamos al tiempo pero le damos menos oportunidad de que sea él el que nos mate y si no que el jefe nosbote.

4) Un SO nos puede ayudar a hacer sistemas más estables. Ahora tenemos unas rutinas que demoran cierto tiempo en hacer unos cálculos y como somos listos, hemosactivado el WatchDog (WD) para que si la cosa se cuelga en el campo se reinicie el sistema. Pero ¿que pasa sila rutina demora más de lo debido y el WatchDog nos reinicia sin que haya ningún problema real?. Otra vez lagestión de recursos nos puede ayudar en eso, ya que si nuestra tarea demora más de lo debido el SO puedequitarle el procesador para atender al WatchDog y darle el procesador a otra tarea que también lo necesita poralgún tiempo. Este caso también sirve cuando aún sin el WD ponemos una llamada a una función que se quedaesperando indefinidamente por que ocurra algo que no ocurre y el código que le sigue no se ejecuta en lostiempos establecidos.

Bueno amigos, hasta aquí hemos visto algunas de las cosas en que puede ayudarnos un SO, y seríamaravilloso poder contar con esas herramientas para programar nuestros PIC. Más adelante seguiremosaprendiendo un poco sobre la teoría de los SO, para después meterle el cuerpo a los programas.

Hay algunos libros interesantes sobre los SO, les recomiendo uno que puede ayudarles mucho en esta primeraparte: Sistemas Operativos Diseño e Implementación. Andrew S. Tanenbaum.

[Volver al Índice]

> Diferencias entre usar un SO o usar las librerías del compilador de turno.

Nocturno, un integrante del foro, le plantea a Reinier la siguiente pregunta, que es aprovechada para avanzaren la explicación de los SO:

Page 3: Sistema Operativo Micro Control Adores Pic Rtos

3 de 22

en la explicación de los SO:

"Por lo que leo en el capítulo 1 de tu artículo, no veo diferencias entre usar un SO o usar las librerías dellenguaje que estés utilizando en cada momento. No me cabe duda que un SO tendrá muchas más aportacionesque las librerías, ¿pero cuál es la principal ventaja que los diferencia?"

Desde el punto de vista de la programación no estás haciendo otra cosa que utilizar las librerías del lenguaje uotras creadas por tí o por un buen amigo que te las haya cedido. De hecho si revisamos, por ejemplo, el RTOSde CCS y las funciones que brinda el lenguaje para desarrollar aplicaciones utilizando esta potencialidad dellenguaje, nos damos cuenta, que por ejemplo, la directiva #use RTOS lo que hace es indicarle al compiladorque ponga en el programa final, creado por el compilador, el código del dispatcher (luego vamos a ver que es)del RTOS, y luego nos ofrece unas funciones de librería como por ejemplo RTOS_WAIT( ), RTOS_ENABLE( ),RTOS_RUN( ), etc, que nos ayudan a gestionar nuestras tareas (también veremos el concepto y laimplementación en el futuro). Bien hasta ahora nada nuevo, ninguna ventaja, y una desventaja: consumo dememoria de programa para el dispatcher y complicaciones de la vida del programador.

Sin embargo la ventaja del SO radica en que le permite al programador contar con una herramienta paragestionar varias cosas fundamentales en el sistema: el procesador, la memoria, y los periféricos, en nuestrocaso eso sería todo nuestro flamante PIC. De todos ellos el más importante es el procesador, ya que es quiénhace la mayor parte del trabajo, el objetivo de nuestro SO es mantener ocupado al procesador con trabajo útil,por ejemplo una demora por SW es hacer trabajar al procesador con trabajo inútil y ese tiempo que se la pasasaltando de aquí para allá lo podemos utilizar en hacer otras cosas y la memoria de programas también,después veremos como hacer eso.

Supongamos ahora que estamos atendiendo un teclado, que no está conectado a ninguna fuente deinterrupción, no queda más remedio que encuestar a nuestro teclado para saber si han oprimido o soltado unatecla, si es así, entonces tenemos que hacernos cargo de los rebotes, etc. Hay muchas formas de hacer eso,una de ellas sería:

1-Espera que se oprima o suelte una tecla2-Espera un tiempo a que termine el rebote3-Lee el teclado4-Procesa la tecla5-Hacer algo con el código del teclado6-Regresa al punto 1

Pero una forma sencilla utilizando un SO tendría la siguiente forma:

1-Espera que se oprima o suelte una tecla2-Me dormiré hasta que termine el rebote3-Lee el teclado4-Procesa la tecla5-Manda un mensaje (el código del teclado) a la función adecuada6-Regresa al punto 1.

Ahora vemos que la cosa cambió ligeramente porque le hemos dicho a alguien, me voy a dormir un tiempo,despiértame cuando pase ese tiempo, y cuando tengo el dato o código de la tecla, le mando un mensaje aalguien (una función), no llamo directamente a la función, pongo el dato en algún lugar e indico que hay undato, es asunto de ese alguien tomarlo, procesarlo y notificarlo. Esas dos acciones las hago sirviéndome del SOy le dejo a él el problema de despertarme, y poner el mensaje donde corresponde, sin embargo en esteproblema el SO puede hacer algo más que en principio no está bajo nuestro control.

Como vemos nuestro programa se queda siempre haciendo lo mismo en un lazo infinito, entonces podemosdecirle al SO: "Oye, este código debe ejecutarse todo en tal tiempo". Entonces, cuando se cumpla el plazoestablecido, el SO le quita el procesador a ese que se lo quiere coger todo para él solo y se lo da a otra funciónque hace algo parecido o para que se atienda una interrupción, etc. cuando todo el mundo haya recibido supoco de tiempo de procesador, le dice a la función que atiende el teclado: toma el procesador por el tiempoque te corresponde y así todo el mundo puede tener el procesador para el solo durante un tiempo, es decirponemos a un vigilante a que reparta equitativamente el tiempo del procesador.

Hasta aquí hemos visto algunas de las ventajas, más adelante veremos muchas más, sin embargo todavía nohemos terminado con la introducción teórica a los SO, pero para los más aventajados esto puede aclararalgunas de sus dudas. Yo se que cosas como esta se pueden hacer blandiendo interrupciones a derecha eizquierda, y con otras técnicas, pero como veremos más adelante los SO nos ayudan en otras cosas, mientrasaprovechamos al máximo nuestros preciados recursos del PIC.

[Volver al Índice]

> ¿Qué es un Sistema Operativo?Según Tanenbaum, una de las personalidades más reconocidas en el mundo académico de los SO, no es fácil

Page 4: Sistema Operativo Micro Control Adores Pic Rtos

4 de 22

Según Tanenbaum, una de las personalidades más reconocidas en el mundo académico de los SO, no es fácildar una definición definitiva de lo que es un SO. El problema consiste en que los SO tienen la característica decomportarse para el usuario (que puede ser una persona cualquiera, un programador, o un programa decomputadora), como un tipo con "doble personalidad".Veamos esto con más detenimiento:

1) El SO como máquina extendida:En esta faceta de la personalidad del SO, la característica destacable es simplificar al programador los detallesdel funcionamiento de los dispositivos conectados al sistema.

Esta característica se pone también de manifiesto en aplicaciones donde no se usan los SO, un ejemplo típicoson las funciones output_x() e input_x() del compilador CCS. Un programador puede utilizar estas funcionessin conocer que para que los datos se pongan en los pines o se lean, hay que cambiar varios registros en eluC. Se dice que estas funciones son una abstracción del proceso de E/S en puerto. Esto es bueno porqueayuda a los programadores a desarrollar soluciones más rápidamente y con menor probabilidad de errores yaque si la función está bien escrita es poco probable que falle.

La función de la máquina extendida es ofrecer al programador una "interfaz" gracias a la cual se utilizan losrecursos del sistema, sin tener que profundizar demasiado en los detalles del funcionamiento de sus diferentescomponentes. Esta interfaz que el SO ofrece al programador o el usuario, se conoce comúnmente comoLlamadas al Sistema o API (Aplication Programmer Interface).

Sin embargo esta visión de los sistemas operativos es poco aplicable a nuestro entorno, en el sentido en quehoy se clasifican a las llamadas al sistema, ya que en nuestro mundo todo es pequeño en cuanto a capacidad yel crear una máquina extendida poderosa consume recursos que usualmente no tendremos. Entonces en estecaso la máquina extendida queda limitada a algunas llamadas a funciones del SO y al uso de las librerías quehasta el momento hemos utilizado habitualmente.

2) El SO como administrador de recursos:En este caso el SO, se comporta como un administrador de nuestros recursos. La ventaja de tener alguien queadministre eficientemente los recursos consiste en que el SO ofrezca al usuario un conjunto de reglas paracompartir y hacer uso de los recursos disponibles con eficacia y eficiencia.

Un ejemplo de administración de los recursos es el uso de la CPU, en un sistema sin SO, el programador tieneque estar muy pendiente de la implementación de su sistema, porque puede que determinados requisitostemporales en la ejecución de algunas funciones tengan que cumplirse.

En nuestro caso lo usual es que nos rompamos el coco manipulando interrupciones, poniendo demoras,cambiando contadores y chequeando banderas… ¡Uf solo de pensarlo me dan ganas de llorar! Sin embargo unSO puede hacerse cargo de todos esos temas de manera eficaz y eficiente, incluso ahorrando memoria ytiempo, y nosotros los programadores concentrarnos en la implementación de la solución, más que en lagestión eficiente de nuestros recursos.

Por supuesto que el SO no es mago ni adivino, para ello debe ofrecernos un conjunto de mecanismos,relativamente sencillos, que nos ayuden a "indicarle" o "pedirle" que es lo que queremos hacer.

En el caso de los uC, las implementaciones de los SO, se caracterizan por potenciar la administración derecursos del SO, por lo que es esta la faceta de personalidad que más a menudo encontraremos en los RTOS.

[Volver al Índice]

> Clasificación de los SO.:A continuación veremos como se clasifican los SO en cuanto a dos características esenciales: la administracióndel recurso fundamental (el procesador) y el destino del SO.

Los SO se pueden clasificar de distintas maneras, pero para abreviar lo más posible, solamente me voy areferir a las ya mencionadas.

En cuanto a la administración del procesador existen dos clasificaciones:

1) SO cooperativo (no preemptive): En este caso es el programador quién tiene la responsabilidad de entregarle el procesador al núcleo del SO,para que éste lo entregue a la próxima tarea que esté solicitándolo o programada para ejecutarse. Esentonces, muy importante, que las llamadas a funciones que ejecutemos nunca se queden esperando muchotiempo por determinados eventos, evitar los lazos infinitos y entregar el procesador cuando no lo necesitemos,para que otra tarea o proceso pueda utilizarlo.

2) SO de tiempo compartido (preemptive): En este caso el programador debe contar con los mismos mecanismos que en el anterior, pero el SO tiene lafacultad de quitarle el procesador y dárselo a otro si usted se ha excedido en su tiempo o hay alguien que tiene

Page 5: Sistema Operativo Micro Control Adores Pic Rtos

5 de 22

facultad de quitarle el procesador y dárselo a otro si usted se ha excedido en su tiempo o hay alguien que tienemayor prioridad.

En cuanto al destino hay unas cuantas clasificaciones pero me voy a concentrar en los RTOS. Un RTOS(Sistema Operativo de Tiempo Real) es un sistema operativo concebido para dispositivos pequeños como losuC. Aunque el concepto de "tiempo real" es muy controversial, la idea es ejecutar determinadas tareas deforma que parece que cada tarea se está ejecutando en un sistema independiente, donde el procesador y elresto de los recursos son sólo para ella.

Los RTOS pueden ser utilizados también para computadoras grandes, pero la idea sigue siendo la misma,ejecutar las tareas cumpliendo estrictamente con los requisitos temporales de cada una, sin violaciones deninguna índole. Otro caso de SO, son los de propósito general como UNIX, LINUX, Windows, en este caso adiferencia de los RTOS, las tareas cambian de prioridades en función de satisfacer las exigencias de loshumanos que actúan como usuarios, no importa si algunas cosas se ejecutan o no cumpliendo tiemposestrictos.

En la próxima entrega ya tendremos código para ejecutar y ver como funciona un RTOS.

[Volver al Índice]

> Introducción al RTOS de CCSDespués de teorizar un poco sobre los Sistemas Operativos, vamos a introducirnos en la programación deaplicaciones empleando un RTOS.

En nuestro caso, para comenzar, utilizaremos el RTOS que viene con el compilador de CCS. Las razones de mielección las expongo a continuación:

- Sencillez en la implementación de aplicaciones.- El RTOS está integrado en el propio compilador de CCS.- Abundante experiencia en el foro con este compilador.- Gran cantidad de dispositivos soportados por el compilador de CCS.

La versión del compilador que tengo instalada en estos momentos es la 3.249, así que si en versionesposteriores han aparecido nuevas características, les ruego que lo informen para tomar las debidasprovidencias en el momento oportuno, y comenzar a utilizar esas nuevas características.

El RTOS de CCS es un Sistema Operativo de Tiempo Real que implementa la técnica de multiprocesamientocooperativo (non preemptive), por lo que es responsabilidad del programador asegurarse de que el control delprocesador retorna al planificador de tareas en algún momento. Así que cuando programemos nuestraaplicación, tenemos que asegurarnos de que no llamamos a una función que se queda esperando por algúnevento largo como es el caso de gets(), o dentro de un lazo infinito o demasiado extenso.

Planificador de tareasUno de los elementos fundamentales de cualquier SO es el planificador de tareas, éste señor es eladministrador de nuestros recursos. Su misión fundamental es determinar dentro de las tareas que están listaspara ejecutarse, a cuál de ellas le entrega el procesador. La política de planificación empleada por CCS no laconozco, pero eso no importa porque el RTOS funciona y para lo que queremos hacer, nos sirve bien.

Directivas del preprocesadorExisten dos directivas del preprocesador para el uso del RTOS, ellas son:

#USE RTOS: Se utiliza para indicarle al compilador que se va a utilizar el RTOS#TASK: Se utiliza para indicarle al compilador se la función definida a continuación es una tarea a ejecutar porel RTOS

Vamos a ver más detenidamente cada una de las directivas, así como sus parámetros de configuración:

#USE RTOS : Opciones del RTOS:

timer: especifica que temporizador, de los disponibles, es el que se utilizará para la ejecución de las tareas.Este temporizador solamente debe ser utilizado por el RTOS y típicamente se escoge Timer0.

minor_cycle: especifica la cantidad de tiempo mínima que una tarea tendrá para ejecutarse, y los tiempos deejecución de cada tarea deben ser múltiplos de esta cantidad. Si por ejemplo decimos que el tiempo mínimo deejecución para todas las tareas es de 1ms, debemos conocer que cada tarea se ejecutará, en menos tiempoque este. Lo realmente importante de este dato es que ayuda a establecer la frecuencia con que se ejecutanlas tareas, luego veremos un ejemplo de esto. Este parámetro, si no se especifica, es calculado por elcompilador en el momento de la compilación.

statistics: le indica al compilador que lleve las estadísticas de las tareas, esto sirve para conocer que tiempo

Page 6: Sistema Operativo Micro Control Adores Pic Rtos

6 de 22

statistics: le indica al compilador que lleve las estadísticas de las tareas, esto sirve para conocer que tiempoconsume cada tarea en ejecutarse, sin embargo como veremos más adelante, la estadística realmenteimportante es la que nos indica si nuestra tarea se ha sobrepasado en su tiempo mínimo de ejecución.

#TASK: Opciones para las tareas:

rate: especifica con que frecuencia se ejecuta la tarea, este parámetro debe ser igual a minor_cycle de#use_rtos o un múltiplo de este valor.

max: especifica que cantidad de tiempo debe consumir esta tarea en su ejecución, si se sobrepasa este tiempoy están activadas las estadísticas, entonces esta tarea es marcada con el valor overrun. Este parámetro es útilpara informar al programador que una tarea se ha pasado de su tiempo de ejecución, y si el RTOS fuera detiempo compartido seguramente especificaría el tiempo en que el planificador le retira el procesador paradárselo a otra tarea.

queue: especifica el tamaño de la cola de mensajes de la tarea. Si la tarea no recibe mensajes, entonces debedejarse en blanco para no consumir memoria RAM innecesariamente.

Hasta aquí hemos visto una pequeña explicación de las directivas para utilizar el RTOS. Sin embargo, lautilidad de esto es mejor verla con un ejemplo.

[Volver al Índice]

> Funciones del RTOSEL RTOS de CCS ofrece un conjunto de funciones que veremos cada una en su momento y con sus debidosejemplos. Sin embargo hoy utilizaremos solamente la función rtos_run(), que le indica al planificador quecomience a ejecutar las tareas.

El ejemplo:Se quiere implementar una aplicación en un PIC16F877, donde se utilice el RTOS para transmitir por el puertoserie de este uC, tres cadenas de caracteres. Cada cadena será transmitida desde dentro de una tarea delRTOS y tendrán el formato “Ejecutada tarea #”. Las especificaciones de tiempo del sistema y de cada tareason las siguientes:

Temporizador para el RTOS: Timer0Tiempo mínimo en que debe ejecutarse una tarea: 10msFrecuencia de ejecución de la Tarea 1: 1seg, tiempo para ejecutar: 10msFrecuencia de ejecución de la Tarea 2: 2seg, tiempo para ejecutar: 5msFrecuencia de ejecución de la Tarea 3: 3seg, tiempo para ejecutar: 250us

El código lo pongo a continuación y posteriormente les doy una explicación:

Código:

#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)#use RTOS(timer=0, minor_cycle=10ms) //temporizador Timer0, tiempo mínimo de ejecución de cada tarea 10msint8 test;

//Definición de las prototipos de función de las tareas#task (rate=1s, max=10ms) //Ejecutar cada 1 segundo y consumir como máximo 10msvoid Tarea1();

#task (rate=2s, max=5ms) //Ejecutar cada 2 segundos y consumir como máximo 5msvoid Tarea2();

#task (rate=3s, max=250us) //Ejecutar cada 3 segundo y consumir como máximo 250usvoid Tarea3();

void main(){ setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); rtos_run(); //A partir de aquí comenzará la ejecución de las tareas

}

//Implementación de las tareasvoid Tarea1(){printf("Ejecutada tarea 1\r");}

Page 7: Sistema Operativo Micro Control Adores Pic Rtos

7 de 22

void Tarea2(){printf("Ejecutada tarea 2\r");}

void Tarea3(){ printf("Ejecutada tarea 3\r");}

Este código funciona y si lo simulan con el Proteus comprobarán que las cadenas salen por el puerto serie.Como pueden ver es un ejemplo sencillo pero que muestra el funcionamiento del RTOS. Al ejecutarlo puedencomprobar que primero se ejecuta la Tarea 1, pero después comprobarán que las tareas no se ejecutan enorden secuencial porque la Tarea 2 se ejecutará cada 2 segundos y la Tarea 3 cada 3 segundos.

La no ejecución secuencial de cada tarea se debe al parámetro rate de la directiva #task, que le dice alplanificador con que frecuencia ejecutar cada tarea. Este programa puede ser fácilmente modificado paracualquier aplicación específica, un ejemplo que se me ocurre es la lectura de teclados y eliminación de rebotes.

[Volver al Índice]

> Controlando la ejecución de las tareasEn la pasada entrega sobre programación con el RTOS de CCS vimos como es que el planificador programabala ejecución de las tareas que estaban activas para ser ejecutadas. Pero como es lógico en todo momento lastareas no tienen por que encontrarse en condiciones de ser ejecutadas, a veces hace falta poner a “dormir”una tarea y “despertarla” cuando hace falta que se ejecute.Para lograr este objetivo el RTOS de CCS nos ofrece dos funciones: RTOS_DISABLE( ) y RTOS_ENABLE( )

Al crear una tarea el RTOS la marca como activa (enable), y cuando comienza a ejecutarse el planificador detareas la pondrá en la cola de ejecución para ejecutarla cuando le llega su turno. Sin embargo en muchasocasiones notaremos que no hace falta ejecutar la tarea hasta que se cumplan ciertas condiciones.

Este es un mecanismo simple, que sin el uso del RTOS controlaríamos mediante una bandera (flag), y laimplementación de una función a la cual llamaremos si se cumple la condición de su ejecución.

Hasta el momento el RTOS no nos ofrece ninguna ventaja respecto al método tradicional, sin embargocombinemos esta característica con lo aprendido en el ejemplo de la entrega anterior y comprobaremos que sihay ventajas, y por cierto nada despreciables.

La ventaja principal con respecto al método tradicional consiste en que usted hace la consulta para comprobarsi hay que ejecutar la función, sin embargo ahora solamente le dice al RTOS, habilita a la tarea tal y ponla aejecutarse cuando le corresponda y se olvida de todos los problemas asociados respecto al tema de cuando lecorresponde ejecutarse la tarea y demás. ¿Alguien se acuerda de los molestos temporizadores, banderas, registros y Dios sabe cuantos engendros decontrol de ejecución condicional para una función estándar?

De forma similar a como se le dice al planificador que la tarea tal debe ser ejecutada, podemos avisarle paraque no la ejecute.

Veamos esto con un ejemplo:Tenemos una aplicación en la que hemos colocado tres LEDs uno rojo en RB0, uno verde en RB1 y otroamarillo en RB2. Vamos a encender y apagar los LEDs con una frecuencia determinada y a intervalos regularessegún el siguiente esquema:

- Led Rojo parpadea con una frecuencia de 250ms por un período de 5s, el resto apagado.- Led Verde parpadea con una frecuencia de 350ms por un período de 10s, el resto apagado.- Led Amarillo parpadea con una frecuencia de 450ms por un período de 15s, el resto apagado.- Todos los LED parpadean, cada uno con su frecuencia correspondiente durante 5s.- Comenzamos por el LED rojo nuevamente y repetimos el ciclo.

La solución que les propongo es la siguiente:

- 3 tareas para controlar el parpadeo de cada LED y el tiempo que se ejecutan- 1 tarea para controlar el tiempo en que todos los LEDs parpadean.

Tenemos un total de 4 tareas en la aplicación y el control de la ejecución será el siguiente:

Page 8: Sistema Operativo Micro Control Adores Pic Rtos

8 de 22

Tenemos un total de 4 tareas en la aplicación y el control de la ejecución será el siguiente:

Al inicio solamente la tarea LED_R estará habilitada, una vez que LED_R ha concluido inicia la tarea LED_V yse autodeshabilita.Cuando LED_V concluye habilita LED_A y se autodeshabilita.Cuando LED_V concluye habilita LEDS y se autodeshabilita.Cuando LEDS se inicia por primera vez habilita LED_R, LED_V y LED_A cuando le toca de nuevo el turno seautodeshabilita y deshabilita a LED_V y LED_A

Veamos el código:

Código:

#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)//Como el reloj de este micro se ha puesto a correr con 20MHz el Timer0 no tiene//mayor resolución que 10ms, es por eso que el tiempo mínimo de ejecución es de 10ms#use RTOS(timer=0, minor_cycle=10ms) int1 iB0, iB1, iB2;int1 iLEDS = 0;int8 iCountR = 0;int8 iCountV = 0;int8 iCountA = 0;int8 iCount = 0; #task (rate=10ms, max=10ms)void Task_Disabler(); #task (rate=250ms, max=10ms)void LED_R(); #task (rate=350ms, max=10ms)void LED_V(); #task (rate=450ms, max=10ms)void LED_A(); #task (rate=5s, max=10ms)void LEDS(); void main(){setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);rtos_run(); } //esta es una función truculenta porque las tareas no pueden crearse deshabilitadas//y no se pueden deshabilitar hasta que el RTOS esté funcionando. Lo considero una//deficiencia sustancial de este RTOSvoid Task_Disabler(){rtos_disable(LED_V);rtos_disable(LED_A);rtos_disable(LEDS);rtos_disable(Task_Disabler);} //cada tarea tiene un contador para llevar la cantidad de veces que se pasa por la//función y cuando se cumple el tiempo establecido entonces habilita y deshabilita//las tareas correspondientesvoid LED_R(){ iB0 = !iB0; output_bit( PIN_B0, iB0); if (iCountR++==20){iCountR = 0;rtos_disable(LED_R);rtos_enable(LED_V);}}

Page 9: Sistema Operativo Micro Control Adores Pic Rtos

9 de 22

} void LED_V(){ iB1 = !iB1; output_bit( PIN_B1, iB1); if (iCountV++==27){iCountV = 0;rtos_disable(LED_V);rtos_enable(LED_A);}} void LED_A(){ iB2 = !iB2; output_bit( PIN_B2, iB2); if (iCountA++==33){iCountA = 0;rtos_disable(LED_A);rtos_enable(LEDS);}} void LEDS(){ if(!iLEDS){rtos_enable(LED_R);rtos_enable(LED_V);rtos_enable(LED_A);iLEDS = 1;}else {rtos_disable(LED_V); //Hay que habilitar y deshabilitar explícitamentertos_disable(LED_A); //cada tarea sobre todo LED_R que debe continuarrtos_disable(LEDS); //ejecutándose otros 5 segundos másrtos_enable(LED_R);iCountR = 0;iCountV = 0;iCountA = 0;iLEDS = 0; }}

Cuando corran y simulen el ejemplo verán que a veces los LEDs se quedan encendidos o apagadosindistintamente, este es un problema del programa, ya que lo deseable sería que los LEDs se quedaranapagados cuando termina la función. Sin embargo lo he dejado así porque en el futuro vamos a ver cómopodemos hacer esto con las propias funciones del RTOS.

Como la vez anterior, les dejo de tarea hacerlo sin RTOS para ver como les queda, a mi llevó menos de doshoras elaborar el texto y escribir el código. Me imagino que sin RTOS me tardaría más de un día completo,consumiría un montón de páginas de explicación y otro montón para el código.

Este es un método simple, pero hay otros mucho más elaborados que iremos viendo poco a poco. La próximaentrega será yield() vs delay(), vamos a ver el método de las esperas eficientes.

[Volver al Índice]

> Yield vs delay¿Cuantas veces en nuestras aplicaciones tenemos que situar demoras para esperar la ocurrencia de un eventodeterminado? Por ejemplo, para eliminar rebotes en un teclado, esperar a que el conversor AD termine y quiénsabe cuantas cosas más.Normalmente estas demoras se hacen poniendo al procesador a decrementar contadores y dar saltosrecursivos como si fuese un loco. Durante todo el tiempo de la demora, nuestro microcontrolador, estaráocupado en perder el tiempo, y es por eso que a este mecanismo se le llama espera ocupada.

Page 10: Sistema Operativo Micro Control Adores Pic Rtos

10 de 22

ocupado en perder el tiempo, y es por eso que a este mecanismo se le llama espera ocupada.

Sin embargo un RTOS nos ofrece un conjunto de herramientas para eliminar este molesto inconveniente, elmás sencillo de ellos es aquel que le permite a una tarea decirle al RTOS: ponme a dormir hasta que me toquede nuevo mi turno de ejecutarme. Para ese efecto el RTOS de CCS implementa la función rtos_yield().

Este mecanismo es muy bueno puesto que mientras la tarea “se duerme” nuestro microcontrolador puedededicarse a realizar otras tareas útiles y hacer de la espera ocupada una espera eficiente. Para la tarea queestá dormida esto no representa nada, a ella le da lo mismo ocupar al procesador en hacer nada que en haceralgo productivo, sin embargo no ocurre lo mismo para el resto de las tareas que están esperando que se lesentregue el procesador.

Otro caso en que yield() nos puede ser útil es para entregar el procesador cuando nos hemos pasado detiempo en la ejecución de alguna tarea. Ya sabemos que el RTOS de CCS es cooperativo, por lo que si unatarea consume más tiempo de la cuenta puede hacer que el sistema colapse, ya que hay que entregarexplícitamente el procesador al RTOS para que se lo de a otra tarea.

Sin embargo con la función de las estadísticas habilitadas, podemos comprobar si alguna tarea se ha pasadode tiempo, y con ello implementar mecanismos adecuados para que la tarea en cuestión reajuste su dinámicay ceda el procesador oportunamente, para ello podemos auxiliarnos de la función rtos_overrun(). Esta funciónno tiene valor si se usa dentro de una tarea para comprobar si ella misma se ha pasado porque la actualizaciónde las estadísticas se hace después de ceder el procesador, considero que esta es una de las debilidades deeste RTOS, en ese sentido.El uso de rtos_overrun(), debería poderse utilizar dentro de una misma tarea para comprobar si desde que mecedieron el procesador para ejecutar, me he pasado de tiempo o no y en consecuencia entregar el procesadoral RTOS.

En el ejemplo que les traigo hoy vamos a emplear rtos_yield() para ceder el procesador y rtos_overrun() paraconocer si una tarea se ha pasado de tiempo.

Sin embargo yield() no es una función realmente poderosa, al menos en este RTOS, porque pone a dormir a latarea durante un período completo del valor rate, que especificamos al declarar la función como una tarea delRTOS, y eso en ocasiones no es lo que deseamos. Aún así es mejor que el procesador de nuestro PIC estéhaciendo algo útil y no perdiendo el tiempo.

En las entregas futuras veremos otras funciones que nos ofrece este RTOS para hacer esperas más eficientesvinculadas al uso de recursos compartidos en nuestras aplicaciones. El uso eficiente del procesador, losrecursos del sistema y la no linealidad en la ejecución de las tareas en un sistema que emplea SO, ha obligadoa los diseñadores de SO a crear mecanismos para proteger los datos y hacer uso de esos recursos de formaordenada y segura. Estos mecanismos se clasifican en dos grupos: La sincronización y la coordinación quecomenzaremos a ver en la próxima entrega.

Ejemplo:Implemente en un PIC16F877 una aplicación en la que se ejecuten tres tareas, con las siguientescaracterísticas:

- La tarea No. 1 Tendrá un contador el cual se incrementa en un lazo hasta que alcanza el valor de 1000.Cuando llegue a ese valor imprime el siguiente mensaje: “Tarea contadora completada” y además pone unabandera a 1, para indicar que ha concluido. Debe colocar en esta tarea código para que la tarea ceda elprocesador en algún momento al RTOS. El tiempo máximo de ejecución de esta tarea es de 10ms y debeejecutarse cada 30ms.

- La tarea No. 2 debe esperar a que la tarea No. 1 termine para enviar por el puerto serie un mensaje similaral de la tarea No. 1, sin embargo, esta tarea también enviará, por el puerto serie, un mensaje cada vez que lecede el procesador al RTOS. Esta debe ejecutarse en un tiempo de 10ms y debe ejecutarse cada 40ms.

- Por último, existe una tarea que se encarga de hacer parpadear un LED conectado en RB0, cada 100ms yenviar un menaje por el puerto serie en caso de que la Tarea 1 o la Tarea 2 se hayan pasado en algúnmomento de su tiempo de ejecución. El tiempo de procesador para esta tarea debe ser de 10ms.

Código:

#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)#use RTOS(timer=0, minor_cycle=10ms, statistics) //se utilizan las estadísticas //hace falta para usar rtos_overrun() int32 iT1Counter = 0;int1 bT1Flag = 0;int1 bLed = 0; #task (rate=30ms, max=10ms)

Page 11: Sistema Operativo Micro Control Adores Pic Rtos

11 de 22

#task (rate=30ms, max=10ms)void Tarea1(); #task (rate=40ms, max=10ms)void tarea2(); #task (rate=100ms, max=10ms)void Tarea3(); void main(){setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);rtos_run(); } void Tarea1(){bT1Flag = 0;for(iT1Counter = 0; iT1Counter <= 1000; iT1Counter++) { if(!(iT1Counter%100)) //mecanismo para ceder el procesador cada cierto tiempo rtos_yield(); //cuando la tarea entra en contexto se comienza a ejecutar //la línea a continuación de esta } printf("Tarea contadora completada\r");bT1Flag = 1; } void tarea2(){ //Aunque esta tarea no tiene que preocuparse mucho por ceder el procesador //porque no tiene lazos infinitos o algo parecido puse de ejemplo tambien a //rtos yieldif(bT1Flag) printf("Espera por Tarea1 concluida\r");else { printf("dormir T2\r"); rtos_yield(); }} void Tarea3(){ bLed = !bLed; output_bit( PIN_B0, bLed); if(rtos_overrun(Tarea1)) //Si las tareas se pasaron de su tiempo de ejecución //se envían los mensajes por el pto serieprintf("Tarea 1 overrun\r"); if(rtos_overrun(Tarea2))printf("Tarea 2 overrun\r");} Como pueden observar, este ejemplo realmente no se corresponde con una aplicación que haga algo útil, sinembargo, me ha servido para ilustrar el uso de las funciones rtos_yield() y rtos_overrun() de la maneramás sencilla que encontré. Las posibilidades de estas funciones están ahora en sus manos y en lo que suscabezas puedan crear para ellas. Hay muchísimas aplicaciones en las que pueden ser útiles, sin embargo, ya eltema de los RTOS es bastante complicado como para meternos a hacer programas complejos que demuestrensu uso.El tiempo invertido para hacer el código y el texto, fue de 2:30 hrs, la decisión de que ejemplo utilizar me tomómás de un día.

[Volver al Índice]

> Coordinar para no dañarHasta ahora hemos visto al RTOS como un elemento que nos ayuda a “simplificar” el código de nuestraaplicación. Por una parte, dejándole parte de la temporización de las tareas que debe realizar nuestraaplicación y por otra utilizando el tiempo de las demoras ocupadas para hacer que otras tareas ejecuten sucódigo en ese tiempo. Sin embargo esas ventajas no son nada comparado con dos herramientas

Page 12: Sistema Operativo Micro Control Adores Pic Rtos

12 de 22

código en ese tiempo. Sin embargo esas ventajas no son nada comparado con dos herramientasfundamentales que nos ofrecen los SO: la coordinación y la sincronización, de ellas hoy vamos a ver solamenteuna 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 recursoscompartidos, es un concepto orientado a evitar que diferentes tareas puedan acceder a los datos o recursos yponer 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 elcurso lo más sencillo posible y adecuarlo un poco más a las aplicaciones que normalmente se nos presentan youtilizaré 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 concurrentea recursos, a mi me gusta llamarlo “coordinación” para establecer una mejor diferencia con respecto al otromecanismo; 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 debeimplementar un SO para asegurar el acceso seguro a recursos compartidos del sistema, y que no tiene encuenta restricciones temporales". Con esto queda claro que proteger a los recursos de un acceso no seguro eslo más importante en la coordinación, no importa durante que tiempo alguien (una tarea) esté utilizando elrecurso, 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 encuenta el factor tiempo, pero el RTOS de CCS no los implementa. Esto puede considerarse una limitante o unaventaja, 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, queveremos dentro de algún tiempo en este foro, debidamente documentado gracias a un proyecto que Darukur yun servidor, llevaremos a ustedes. Por el momento este simple cursillo es un buen método (no el único) paraacercarse 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 tiendasolo había una así que decidió comprarla de todas formas. Cuando llegó a casa llama a sus hijos (ambos usanla 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 debencompartirla, entonces la decisión de ambos es colocar la camisa en una percha, y cada vez que uno de los dosdecida utilizarla se la ponga (dejando el perchero vacío). Pero hay una regla adicional, si cuando uno de los dosva 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), demanera compartida (porque es la única), de forma coordinada (para eso se pusieron de acuerdo e hicieronunas reglas simples).

Para implementar las reglas mostradas en el ejemplo anterior, el RTOS de CCS tiene dos funcionesrtos_wait() y rtos_signal().

Para utilizar estas funciones primero hay que crear una variable entera que hará las funciones de percha y, quehablando con propiedad, se llama semáforo. El semáforo es el elemento que le permite a la tarea reclamar elrecurso compartido o esperar por él si ya está en uso. Las funciones rtos_wait() y rtos_signal() se utilizanpara marcar el momento de inicio y fin del código que utiliza el recurso compartido. A la sección de código queutiliza 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 unrecurso de memoria. O puede ser un periférico del sistema, como es el caso del puerto serie o la memoriaEEPROM, o cualquier otro.rtos_wait() y rtos_signal() son los marcadores de inicio y fin del código que hace uso de nuestro recursocompartido.

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

Page 13: Sistema Operativo Micro Control Adores Pic Rtos

13 de 22

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 ypermitirá que la tarea continúe su ejecución, sin embargo si el semáforo está en cero, el RTOS le quitará elprocesador a la tarea y se lo cederá a otra que le toque ejecutarse. Cuando le corresponda nuevamente a latarea que pidió el acceso al recurso compartido, el RTOS comprobará el estado del semáforo, si éste es mayorque cero, lo decrementará y le dará el procesador a la tarea para que se siga ejecutando, si no, volverá adormir 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 elsemá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 enun tramo de cinta transportadora en una embotelladora. La cinta es alimentada desde un almacén de botellasque tiene un robot que incrementa la variable Cantidad cada vez que coloca una botella en la cinta, mientrasque dos robots llenadores de cajas, decrementan en 12 la variable cantidad cada vez que toman 12 botellas dela cinta transportadora. Como es de suponer el robot despachador debe llenar la cinta más rápido de lo que los robots llenadores lavacían.

En la próxima entrega utilizaremos la sincronización para resolver el problema de que la cinta se quede vacía ose llene demasiado rápido. Como datos adicionales suponga que el robot despachador despacha una botellacada 250ms y que los robots llenadores llenan una caja cada 6 segundos. El robot despachador está conectadoa RB0 y cada vez que pone una botella en la cinta transportadora le da un pulso al microcontrolador paraindicárselo. Los robots llenadores están conectados uno a RB1 y el otro a RB2 e igualmente dan un pulso almicrocontrolador 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 losRTOS, pero eso se los dejo de tarea. Además el mecanismo de notificación de cada robot es un pocodeficiente, pero ese no es el tema de este curso, aunque en su momento pondremos un ejemplo mejor alrespecto, cuando rescatemos a las interrupciones del olvido.

Analicemos un poco en detalle el problema: Supongamos que la tarea asociada al robot despachador comienzaa ejecutarse, lee el valor de la variable Cantidad, 100 botellas, y se va adormir esperando que el robot lenotifique que ha puesto una botella en la cinta, en ese momento el RTOS le da permiso a la tarea del robotllenador 1 para que ejecute su código, ésta se da cuenta que el robot llenó una caja por lo que lee la variableCantidad y le resta 12 botellas, quedando Cantidad = 88 botellas. Ahora le toca de nuevo a la tarea del robotdespachador ejecutarse y como ya se despachó una botella le suma uno al valor previamente leído y actualizala 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 quenuestro RTOS es cooperativo y en este caso, mientras la tarea esté ejecutándose tiene todos los recursos paraella 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 queaccede a un recurso compartido, de esta forma la tarea se asegura el uso exclusivo del recurso compartido… ano ser que aparezcan las interrupciones en la palestra y las cosa se complique. Sin embargo en un sistema detiempo compartido (los hay para PIC, ejemplo de ellos es el FreeRTOS), donde no sabemos cuando el RTOSnos quitará el procesador el uso de secciones críticas es OBLIGATORIO, para evitar problemas como losmostrados, 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 puedeocurrir que para ser eficientes estemos obligados a poner un rtos_yield() dentro del código de la seccióncrítica. Moraleja: aprenda a programar con secciones críticas o no programe con RTOS.

El código:

#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)#use RTOS(timer=0, minor_cycle=10ms)int8 semaphore; //Este es nuestro semáforoint16 iCantidad; //Esta es la cantidad de botellas en la estera//constituye nuestro recurso compartido #task (rate=50ms, max=10ms)void R_Despachador(); #task (rate=50ms, max=10ms)void R_Llenador1();

Page 14: Sistema Operativo Micro Control Adores Pic Rtos

14 de 22

#task (rate=50ms, max=10ms)void R_Llenador2(); void main(){ semaphore = 1; //Solo una tarea puede utilizar el recurso cada veziCantidad = 100; //Inicializamos esta variable para tener algunas botellas en //la estera.setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);rtos_run(); } void R_Despachador(){int Botellas;rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc críticaBotellas = iCantidad; //Leemos la cantidad de botellas a una variable temporal if(input(PIN_B0)==1) { Botellas++; //Ya sabemos que este código no es eficiente pero iCantidad = Botellas; //sí es didáctico y por eso lo he utilizado así. } rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica rtos_yield(); // A dormir por otros 100ms para evitar poner dos veces la misma botella} void R_Llenador1(){rtos_wait(semaphore);if(input(PIN_B1)==1) iCantidad -= 12; //Este sí es un código lógico, pero entonces el despachador//no nos daría problemas aunque nos vayamos a dormir dentro de//la sección crítica.

rtos_signal(semaphore);rtos_yield();} void R_Llenador2(){rtos_wait(semaphore);if(input(PIN_B2)==1)iCantidad -= 12;

rtos_signal(semaphore);rtos_yield();}

Este programa lo simulé en Proteus poniendo en RB0 una fuente digital de tipo pattern con los siguientesparámetros:

First Edge at (Secs)=1Desmarcar el check mark: Equal Mark/Space Timing?‘Mark’ Time (Secs) = 100m‘Sapce’ Time(Secs) = 150mMarcar el check mark: Continuos Secuence of PulsesMarcar el check mark: Standard Hig-Low Pulse TrainPara RB1 y RB2 se utiliza una fuente del mismo tipo con los siguientes parárametros cambiadosPara RB1:First Edge at (Secs)=5‘Mark’ Time (Secs) = 100m‘Sapce’ Time(Secs) = 5.9Para RB2:First Edge at (Secs)=7‘Mark’ Time (Secs) = 100m

Page 15: Sistema Operativo Micro Control Adores Pic Rtos

15 de 22

‘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 decrementay 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.

[Volver al Índice]

> 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 lasincronizació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 oeventos, para en consecuencia hacer algo. La duración de estas demoras puede ser conocida, como en el casode esperar a que una LCD coloque los datos en determinados registros antes de enviarle otro dato, o esperar aque la USART saque un dato que está transmitiendo antes de poder escribir nuevamente en el registro detransmisión; sin embargo también son frecuentes aquellas esperas en las que no sabemos cuanto podemosdemorarnos.

En los casos en que no conocemos cuanto debemos esperar se pueden utilizar las interrupciones, pero en losuC no tenemos interrupciones ilimitadas ni tampoco existe una biblioteca de mecanismos de interrupcióndisponibles para todos los casos que se nos presentan. Es por estas razones que muchas veces esperamos a laocurrencia 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 nonos ofrece este tipo de mecanismos que podemos llamar un poco primitivos. Para la implementación dedemoras 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 temade los SO, han llamado a estos mecanismos y al que veremos hoy, “mecanismos de sincronización deprocesos”, pero a mi me gusta distinguir entre aquellos que se dedican especialmente a implementar esperaseficientes para la protección de recursos, de aquellos que se dedican a implementar esperas eficientes paraeventos por los cuales un proceso debe esperar antes de continuar su ejecución. Notemos que en ambos casosla tarea o proceso debe esperar, pero no en todos los casos la espera tiene la misma naturaleza, en unoesperamos por un recurso físico al que queremos acceder y que no está disponible, en el otro esperamos a quese 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 leindica al robot que no coloque o extraiga botellas de la cinta transportadora. Con este mecanismo simplevamos a tratar, por un lado, de evitar que el robot despachador de botellas llene demasiado la cinta y por elotro que los robots llenadores de cajas traten de llenar las cajas cuando no hay suficientes botellas en la cintatransportadora. Es decir, vamos sincronizar el proceso de llenado/vaciado de la cinta transportadora. Lasventajas de esto son evidentes, por ejemplo: si el robot llenador no tiene botellas que poner en la cinta losrobots llenadores trabajarán hasta que la cantidad de botellas se lo permita; si los robots llenadores dejan detrabajar, 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 de100 y que la cantidad mínima de botellas es 24, por lo que cada una de las tareas que atiende a los robotsdeberá, además de llevar la actualización del total de botellas en la cinta, indicarle a los robots que sedetengan cuando la cantidad de botellas en la cinta esté fuera del rango especificado. Además vamos a utilizarel 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 robotdespachador, 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 estafunción es bien poderosa, vamos a verla con más detenimiento. La función se llama rtos_await(expr) lo quetienes que pasarle es una expresión lógica que la función evaluará, si esta resulta verdadera entoncescontinúas la ejecución normal de tu programa, si te devuelve falso, entonces rtos_await() le cederá elprocesador al RTOS y la tarea quedará bloqueada hasta que exp se cumpla para entonces continuar en la líneasiguiente 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 dondeponerla, 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

Page 16: Sistema Operativo Micro Control Adores Pic Rtos

16 de 22

estaremos sometiéndonos a riesgos durante la ejecución de nuestro código. Por ejemplo puede ocurrir quealguna tarea se quede bloqueada esperando por siempre a que la expresión lógica se evalúe de verdadera yesto nunca ocurra o que la expresión esté mal diseñada y la tarea no se bloquee cuando haga falta. Bien todosesos problemas los veremos más adelante cuando la señorita Némesis (diosa griega de la venganza y lafortuna) haga acto de presencia para echarnos a perder toda la dicha que los RTOS traen al mundo de laprogramación con uC.

Desde aqui puedes descargar el código fuente y la simulación con Proteus (57Kb, formato ZIP)

Cuando corran el ejemplo noten como la cantidad de botellas en la cinta va descendiendo hasta que al llegar alas 24 botellas, después la cantidad de botellas en la cinta se mantendrá más o menos sobre las 20 y nuncapor debajo de 12. Las compuertas AND de conjunto con las formas de onda hacen la función de los robots.

El código:#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)#use RTOS(timer=0, minor_cycle=10ms)int8 semaphore; //Este es nuestro semáforoint16 iCantidad; //Esta es la cantidad de botellas en la estera//constituye nuestro recurso compartido #task (rate=50ms, max=10ms)void R_Despachador(); #task (rate=50ms, max=10ms)void R_Llenador1(); #task (rate=50ms, max=10ms)void R_Llenador2(); void main(){semaphore = 1; //Solo una tarea puede utilizar el recurso cada veziCantidad = 120; //Inicializamos esta variable para tener algunas botellas en //la estera, normalmente deberiamos tener un sensor que nos reporte //en algun momento el total de botellas en la cinta, ya que un //robot revisor de llenado o una persona puede retirar botellas //de la cinta //Al comenzar todos los robots estan deshabilitadosoutput_bit( PIN_B3, 0);output_bit( PIN_B4, 0);output_bit( PIN_B5, 0); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);rtos_run(); } void R_Despachador(){//Note como hacemos la sincronizacion fuera de la seccion critica, mas adelante veremos//que esto no siempre es posible hacerlo o que las cosas se complican un poco mas//de lo que hemos visto hasta ahora.rtos_await(iCantidad<100); //Esperemos a que se vacie un poco la cinta output_bit( PIN_B3, 1); //A partir de aqui, si no se podia antes, poner botellas rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc crítica if(input(PIN_B0)==1) iCantidad++; //sí es didáctico y por eso lo he utilizado así. if(iCantidad >= 100)output_bit( PIN_B3, 0); //Le decimos al robot despachador que no ponga mas botellas rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica printf("%3.0w \r",iCantidad);rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella}

Page 17: Sistema Operativo Micro Control Adores Pic Rtos

17 de 22

void R_Llenador1(){ //El robot debe esperar a que la cinta tenga suficientes botellas para sacar antes //de comenzar a trabajar. rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta output_bit( PIN_B4, 1); //A partir de aqui, si no se podia antes, sacar botellas rtos_wait(semaphore); if(input(PIN_B1)==1) iCantidad -= 12; if(iCantidad <= 24) output_bit( PIN_B4, 0); //Le decimos al robot que no saque mas botellas rtos_signal(semaphore); printf("%3.0w \r",iCantidad);rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella } void R_Llenador2(){rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cintaoutput_bit( PIN_B5, 1); //A partir de aqui, si no se podia antes, sacar botellas rtos_wait(semaphore); if(input(PIN_B2)==1)iCantidad -= 12; if(iCantidad <= 24) output_bit( PIN_B5, 0); //Le decimos al robot que no saque mas botellas rtos_signal(semaphore); printf("%3.0w \r",iCantidad);rtos_yield();}

Hasta ahora solamente hemos visto ventajas del uso de los RTOS, sin embargo el uso de estas herramientaspresupone un montón de complicaciones que he tratado de no mostrar hasta el momento, en aras de mostrarlo útil que puede ser un RTOS, pero aún con esas complicaciones el uso de los RTOS sigue siendo unabendición para cualquier desarrollador de sistemas con uC. Simplemente tendremos que ser un poco máscuidadosos con la semántica de nuestros programas y pensar un poco más en la concepción y modelación delas 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 otrade las ventajas que los RTOS traen al mundo de la programación para uC y cuando terminemos de ver todasesas cosas buenas comenzaremos a estudiar las desgracias y cómo enfrentarlas.

[Volver al Índice]

> RTOS mailHasta el momento solamente hemos visto mecanismos que nos permiten simplificar el diseño de nuestrosprogramas, pero hoy vamos a ver una nueva potencialidad de los RTOS que es una cuestión realmentenovedosa en cuanto la visión de la programación para uC a la cual estamos acostumbrados.

Cuando hacemos una llamada a una función, es frecuente pasarle algún parámetro para que esta pueda hacersu tarea, mientras la función trabaja, nuestro programa espera pacientemente a que la función retorne y nosdevuelva el resultado, que puede ser un valor de retorno, un arreglo cambiado o simplemente el cambio en elestado de algún periférico o salidas del uC.

El párrafo anterior describe lo que hace nuestro programa cuando llamamos a una función, sin embargo nuncahemos visto que una función le envíe un dato a otra (no en la llamada a la función, sino fuera de ésta) paraque cuando le toque ejecutarse tome esos valores y los procese, y si hay que devolver algún resultadoentonces que nos envíe un acuse de recibo. Es lógico que un mecanismo como el que acabo de describir no seutilice en las técnicas de programación anterior porque la ejecución secuencial del código presupone que no se

Page 18: Sistema Operativo Micro Control Adores Pic Rtos

18 de 22

utilice en las técnicas de programación anterior porque la ejecución secuencial del código presupone que no serequiera de un mecanismo como este.

Lo más cercano al método descrito en el poner datos en algún lugar para que una función lo procese es el usode las interrupciones, éstas deben procesar rápidamente el evento de interrupción y pude que pongamos eldato en algún lugar y levantemos una bandera para que cuando a la función encargada de procesar los datosle toque ejecutarse lea la bandera, procese los datos y coloque la bandera en el estado que notifica que ya seprocesó, no para notificar a otra función sino para notificárselo a ella misma, no vaya a ser que cuando letoque ejecutarse nuevamente procese los mismos resultados nuevamente o haga algo indebido.

Un ejemplo de lo anterior puede se el uso del conversor AD, en algún lugar del programa lo mandamos aconvertir; una vez hecha la conversión se produce una interrupción que es atendida en la correspondientesubrutina de atención a esa interrupción; leemos el dato lo ponemos en una variable e incrementamos uncontador. Posteriormente le toca ejecutarse a la función que promedia los resultados, ésta comprueba si hay,digamos 200 muestras, si las hay hace el cálculo que pone en otra variable y deja el contador en cero. Estemecanismo es eficaz porque se ha utilizado durante mucho tiempo, pero los RTOS brindan una soluciónelegante para hacer esto en el contexto de la ejecución de tareas.

Estos mecanismos pueden funcionar también entre funciones pero tendremos el problema de tratar con un montón de

estructuras de datos, banderas y contadores, complejas expresiones lógicas a procesar… ¿se acuerdan de eso?

Ahora imagínense hacer todo lo anterior cuando, en vez de llamadas a funciones metidas dentro de un códigoque se ejecuta más o menos estructuradamente, lo que tenemos es unas cuantas tareas de las que notenemos un control de cuando ni como se ejecutarán. Realmente puede ser una verdadera pesadilla hacer unprograma productivo, y es por ello que los RTOS nos ofrecen un poderoso mecanismo para hacer eso, y comosiempre, este mecanismo también es relativamente simple.

Para hacer lo anterior los RTOS implementan un mecanismo de mensajes. Sí, amigos míos, un RTOSimplementa una función similar a la de los correos.

El funcionamiento de ese mecanismo es simple, cuando una tarea o subrutina de atención a interrupcionesnecesita notificarle algo a otra tarea llama a una función que pone el dato en la cola de la tarea en cuestión,cuando a la tarea que recibió el mensaje le toca ejecutarse debe, en algún lugar consultar su cola demensajes, si hay mensajes debe leerlos y procesarlos, como pueden ver este mecanismo es bastante parecidoa lo que hacemos habitualmente.

Si yo quiero pasarles un mensaje, por ejemplo un post, hago lo siguiente:

- lo escribo, este es el equivalente a realizar una tarea- lo mando al foro, este es el equivalente a ponerlo en la cola de mensajes del hilo sobre RTOS- ustedes llegan y consultan si hay mensajes nuevos en el hilo, por supuesto llegan cuando su tarea de leer elforo está activa- si hay un mensaje nuevo, normalmente tratarán de leerlo y poner en práctica los nuevos conocimientos- si se sienten impresionados, me escribirán un mensaje a mi correo privado, dándome un acuse de recibo (nohagan esto si no es estrictamente necesario, no vaya a ser que me vuelvan loco)

Aquí se ha puesto de manifiesto un ejemplo del sistema de mensajes más simple utilizado por un SO: elaborary enviar de una parte y consultar si hay un mensaje, procesar y enviar acuse de recibo si es necesario de laotra parte.

(Todo esto está muy bien. Pero yo quiero código y ejemplos de verdad.)Vale, no nos ofusquemos, primero entender bien el concepto, luego ponerlo en práctica.

Lo primero que tenemos que hacer es decirle al compilador que le cree una cola de mensajes a aquella tarea ala cual queremos pasarle mensajes, para eso tenemos el parámetro queue, dentro de la directiva #task, coneste parámetro le indicamos al RTOS que reserve memoria y cree una cola de mensajes para la tarea, ladeclaración de una tarea con cola de mensajes sería como sigue:

El código:#task(rate = 1s, max=20ms, queue=5)void Tarea1(void);

En la declaración de la tarea el parámetro queue = 5, le dice al compilador que cree una cola de 5 bytes parala Tarea1.

Para el envío y recepción de mensajes tenemos las siguientes funciones:RTOS_MSG_SEND( )RTOS_MSG_POLL( )RTOS_MSG_READ( )

Page 19: Sistema Operativo Micro Control Adores Pic Rtos

19 de 22

RTOS_MSG_READ( )

RTOS_MSG_SEND(task, byte); permite enviar un byte de datos a la cola de mensajes de una tarea. Esta es laúnica función del RTOS de CCS que puede llamarse desde fuera de una tarea, lo que permite que desde unasubrutina de atención a interrupción se le envíen mensajes a una tarea. El parámetro task es para el nombrede la tarea y byte es un dato de 8 bits (un char o un int8), así que si queremos enviar un float o unaestructura tendremos que descomponer antes ese dato en bytes y luego componerlos cuando la cola demensajes sea leída.

int RTOS_MSG_POLL(); es la función que permite a una tarea conocer si tiene mensajes en su cola demensajes, no se puede llamar desde otra tarea para conocer cuantos mensajes tiene la tarea fulana. Devuelveen un entero la cantidad de bytes ocupados dentro de la cola de mensajes.

int8 RTOS_MSG_READ(); permite leer un byte de la cola de mensajes. Cuando se ejecuta esta función se lee elbyte y se saca de la cola, por lo que si el dato se pierde no se podrá recuperar, si se llama a la función y nohay mensajes en la cola se pueden obtener datos falsos.

En el ejemplo que hemos estado viendo sobre la embotelladora, vamos a incluir un servicio especial parabalancear la cantidad de botellas que hay dentro de la cinta transportadora, para ello pondremos una tareaadicional que recibirá de las otras tareas el estado de la cantidad de botellas dentro de la cinta. Si la cinta seestá vaciando demasiado rápido, esta tarea se encargará de inhabilitar los robots llenadores de cajas, si seestá llenando muy rápido pues entonces se deshabilita al robot que despacha botellas hacia la cinta.

Para lograr esto cada vez que un robot ejecuta la tarea de llenado de cajas o despacho de botellas le notifica ala tarea reguladora la cantidad de botellas que hay en la cinta, con este mecanismo evitamos que la tareasupervisora tenga que leer el recurso compartido iCantidad, y que tenga que sincronizarse con los robots. Lacola de mensajes tendrá dos bytes (aunque solo se necesita uno, después explico por que hacen falta dos)donde se reflejará la última escritura realizada por cualquiera de los tres robots. Además, delegaremos en estatarea la transmisión de la cantidad de botellas que hay en la cinta. La cantidad media de botellas a tener en lacinta es 50.

El código:#include "D:\Documentos\Projects\RTOS\RTOS.h"#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)#use RTOS(timer=0, minor_cycle=10ms)int8 semaphore; //Este es nuestro semáforoint8 iCantidad; //Esta es la cantidad de botellas en la estera//constituye nuestro recurso compartido #task (rate=50ms, max=10ms)void R_Despachador(); #task (rate=50ms, max=10ms)void R_Llenador1(); #task (rate=50ms, max=10ms)void R_Llenador2(); #task (rate=1s, max=10ms, queue=2) //la cola tiene 2 byte aunque solamente necesitamos 1void Supervisor(); void main(){semaphore = 1; //Solo una tarea puede utilizar el recurso cada veziCantidad = 120; //Inicializamos esta variable para tener algunas botellas en //la estera, normalmente deberiamos tener un sensor que nos reporte //en algun momento el total de botellas en la cinta, ya que un //robot revisor de llenado o una persona puede retirar botellas //de la cinta //Al comenzar todos los robots estan deshabilitadosoutput_bit( PIN_B3, 0);output_bit( PIN_B4, 0);output_bit( PIN_B5, 0); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);rtos_run(); } void R_Despachador()

Page 20: Sistema Operativo Micro Control Adores Pic Rtos

20 de 22

void R_Despachador(){//Note como hacemos la sincronizacion fuera de la seccion critica, mas adelante veremos//que esto no siempre es posible hacerlo o que las cosas se complican un poco mas//de lo que hemos visto hasta ahora.rtos_await(iCantidad<100); //Esperemos a que se vacie un poco la cinta output_bit( PIN_B3, 1); //A partir de aqui, si no se podia antes, poner botellas rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc crítica if(input(PIN_B0)==1) iCantidad++; //sí es didáctico y por eso lo he utilizado así. if(iCantidad >= 100)output_bit( PIN_B3, 0); //Le decimos al robot despachador que no ponga mas botellas rtos_msg_send(Supervisor, iCantidad); //Enviamos un mensaje con la cant de botellas rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella} void R_Llenador1(){ //El robot debe esperar a que la cinta tenga suficientes botellas para sacar antes //de comenzar a trabajar. rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta output_bit( PIN_B4, 1); //A partir de aqui, si no se podia antes, sacar botellas rtos_wait(semaphore); if(input(PIN_B1)==1) iCantidad -= 12; if(iCantidad <= 24) output_bit( PIN_B4, 0); //Le decimos al robot que no saque mas botellas rtos_msg_send(Supervisor, iCantidad); //Enviamos un mensaje con la cant de botellas rtos_signal(semaphore); rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella } void R_Llenador2(){rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cintaoutput_bit( PIN_B5, 1); //A partir de aqui, si no se podia antes, sacar botellas rtos_wait(semaphore); if(input(PIN_B2)==1)iCantidad -= 12; if(iCantidad <= 24) output_bit( PIN_B5, 0); //Le decimos al robot que no saque mas botellas rtos_msg_send(Supervisor, iCantidad); //Enviamos un mensaje con la cant de botellas rtos_signal(semaphore); rtos_yield();} void Supervisor(){int8 iBotellas; rtos_await(rtos_msg_poll()>0); //Esperamos a que haya algun mensaje en la cola iBotellas = rtos_msg_read(); //Leemos el mensaje

Page 21: Sistema Operativo Micro Control Adores Pic Rtos

21 de 22

iBotellas = rtos_msg_read(); //Leemos el mensaje //Lo que hacemos ahora es comprobar la cantidad de botellas que hay en la estera//y en funcion de eso habilitamos y deshabilitamos las tareas y los robots que hacen falta//para controlar la cantidad de botellas en la esteraif(iBotellas > 50){ output_bit( PIN_B3, 0); //No despachar mas botellasrtos_disable(R_Despachador); rtos_enable(R_Llenador1);rtos_enable(R_Llenador2); } else{ rtos_enable(R_Despachador); //No llenar mas cajas output_bit( PIN_B4, 0); rtos_disable(R_Llenador1); output_bit( PIN_B5, 0); rtos_disable(R_Llenador2);} printf("%3.0w \r",iBotellas); //Transmitir la cantidad de botellas }

Este programa se puede simular con el mismo fichero de Proteus que publiqué antes, noten como la cantidadde botellas en la cinta transportadora se mantiene sobre las 50 botellas. En el caso de la cola de mensajesdeben especificar n+1 bytes de los que necesiten, la razón no la conozco pero con 1 byte no funciona, debe seralgún problema de la implementación de CCS o alguna limitación de los PIC que obliga a ello.

Bueno espero que les sirva.

PD: Lo de esta embotelladora es un invento, en ningún momento esto se ha probado en una planta de esetipo.El tiempo que utilicé para este ejemplo fue de 3:30 horas, incluyendo la redacción y programación.

[Volver al Índice]

> Datos de Contacto:Los datos de contacto de Reinier son los siguientes:

e-mail: [email protected] de La Habana, CubaWEB provisional: http://reinier-torres-labrada.neurona.com

[Volver al Índice]

> Bibliografía:- Sistemas Operativos Diseño e Implementación. Andrew S. Tanenbaum.

[Volver al Índice]

En construcción...permanentemente. Pasa en unos días para ver las novedades.

Page 22: Sistema Operativo Micro Control Adores Pic Rtos

22 de 22

Pasa en unos días para ver las novedades.

www.ucontrol.com.ar | Desarrollo de sistemas de automatización y control | Pehuajó - Buenos Aires - Argentina e-mail: [email protected]