TODOPIC

Microcontroladores PIC => RTOS => Mensaje iniciado por: reiniertl en 02 de Febrero de 2007, 11:07:47

Título: Sistemas operativos en PIC
Publicado por: reiniertl en 02 de Febrero de 2007, 11:07:47
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 practicamente 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 nongú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. Dentro de poco les caigo algún texto introductorio para ir entrando en calor con la teoría y después a meter código, que es lo que nos hace falta.
Título: Re: Sistemas operativos en PIC
Publicado por: maunix en 02 de Febrero de 2007, 11:26:26
reiniertl, todo aporte es bienvenido.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 02 de Febrero de 2007, 12:35:48
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 por allá por los 60?, bueno más o menos.
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 y demás cacharros electrónicos que adornan a una computadora, y por otro lado algunos programadores ya habían escrito controladores para esos dispositivos y por tanto los que venían detrás simplemente querían utilizarlos 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 que debí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 coexistir sin que se produjera una guerra hubiteana (guerra en la que los hombres y los bits se pelean hasta que los hombres se mueren de alguna clase de infarto o pierden a la mujer). Surgieron así los primeros intentos de crear un SO y los hombres mantuvieron la Paz sobre la tierra y también la guerra “fria”, aunque las cosas se calentaran a intervalos.

Pasó el tiempo y llegó Bill Gates con DOS y luego Windows y Steve Jobs con su Mac, unos tipos más listo y cabrones que ingenieros o programadores…. y después también apareció Linus Torvalds con Linux, uno que estaba más loco que El Quijote y entonces las personas corrientes creyeron que en el mundo solo existen a lo sumo tres SO (Windows, Mac, y Linux), pero no es así hay un montón de SO, algunos muy poderosos y otros no 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 a ver algunas.

Bueno amigos, hasta aquí hemos visto algunas de las cosas en que puede ayudarnos un SO, y sería maravilloso poder contar con esas herramientas para programar nuestros PIC. Más adelante seguiremos aprendiendo un poco sobre la teoría de los SO, para después meterle el cuerpo a los programas.
Espero que los que no conocían nada al respecto hayan aprendido algo y sigan estudiando por su cuenta, porque todo no puedo ponerlo en el foro. Hay algunos libros interesantes sobre los SO, les recomiendo uno que puede ayudarles mucho en esta primera parte: Sistemas Operativos Diseño e Implementación. Andrew S. Tanenbaum
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 02 de Febrero de 2007, 13:58:17
Bueno, muy interesante el tema, esperare para seguir aprendiendo
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 02 de Febrero de 2007, 16:43:35
Interesante iniciativa que pretendo seguir de cerca, reiniertl.

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 del lenguaje que estés utilizando en cada momento.
No me cabe duda que un SO tendrá muchas más aportaciones que las librerías, ¿pero cuál es la principal ventaja que los diferencia?
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 02 de Febrero de 2007, 18:41:25
Citar
no veo diferencias entre usar un SO o usar las librerías del lenguaje que estés utilizando en cada momento.
No me cabe duda que un SO tendrá muchas más aportaciones que 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 u otras creadas por tí o por un buen amigo que te las haya cedido. De hecho si revisamos, por ejemplo, el RTOS de CCS y las funciones que brinda el lenguaje para desarrollar aplicaciones utilizando esta potencialidad del lenguaje, nos damos cuenta, que por ejemplo, la directiva #use RTOS lo que hace es indicarle al compilador que ponga en el programa final, creado por el compilador, el código del dispatecher (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 la implementación en el futuro). Bien hasta ahora nada nuevo, ninguna ventaja, y una desventaja: consumo de memoria 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 para gestionar varias cosas fundamentales en el sistema: el procesador, la memoria, y los periféricos, en nuestro caso eso sería todo nuestro flamante PIC. De todos ellos el más importante es el procesador, ya que es quién hace 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 inutil y ese tiempo que se la pasa saltando 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 de interrupción, no queda más remedio que encuestar a nuestro teclado para saber si han oprimido o soltado una tecla, 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 tecla->2-espera un tiempo a que termine el rebote->3-lee el teclado->4-procesa la tecla->5-hacer algo con el código del teclado->6regresa al punto 1

Pero una forma sencilla utilizando un SO tendría la siguiente forma: 1-Espera que se oprima o suelte una tecla->2-me dormiré hasta que termine el rebote->3-lee el teclado->4-procesa la tecla->5-manda un mensaje (el código del teclado) a la función adecuada->6regresa 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 a alguien (una función), no llamo directamente a la función, pongo el dato en algún lugar e indico que hay un dato, es asunto de ese alguien tomarlo, procesarlo y notificarlo. Esas dos acciones las hago sirviéndome del SO y le dejo a él el problema de despertarme, y poner el mensaje donde corresponde, sin embargo en este problema 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 podemos decirle al SO. Oye, este código debe ejecutarse todo en tal tiempo. Entonces cuando se cumpla el plazo establecido el SO, le quita el procesador a ese que se lo quiere coger todo para él solo y se lo da a otra función que hace algo parecido o para que se atienda una interrupción, etc. cuando todo el mundo haya recibido su poco de tiempo de procesador, le dice a la función que atiende el teclado: toma el procesdor por el tiempo que te corresponde y así todo el mundo puede tener el procesador para el solo durante un tiempo, es decir ponemos 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 no hemos terminado con la introducción teórica a los SO, pero para los más aventajados esto puede aclarar algunas de sus dudas. Yo se que cosas como esta se pueden hacer blandiendo interrupciones a derecha e izquierda, y con otras técnicas, pero como veremos más adelante los SO nos ayudan en otras cosas, mientras aprovechamos al máximo nuestros preciados recursos del PIC

Título: Re: Sistemas operativos en PIC
Publicado por: FJPPitta en 02 de Febrero de 2007, 21:13:30
Muy interesante esto del SO, siempre había tenido interes en desarrollar uno por minimo que fuese, ojala me de tiempo para implementar algo.

Saludos
FJPPitta
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 03 de Febrero de 2007, 01:08:54
muy interesante amigo reiniertl, estoy al tanto de tus post!!  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: akira_ve en 03 de Febrero de 2007, 02:04:18
vaya todo el foro esta de lujo..aqui en venezuela  ( segun se ) hicieron uno para el 877 es de uso libre........ esta es su direccion  http://www.araguaney.loquequierasya.com

dan documentacion y el sistema operativo como tal  :shock: hechenle un ojo a ver que tarrrrrrrr
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 03 de Febrero de 2007, 02:10:46
muchas gracias akira  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 03 de Febrero de 2007, 09:32:33
DOS , window$ y LINUX son OS relativamente nuevos, por ejemplo antes que esto esta UNIX.
Es mas antes que DOS se creo en Japon un RTOS que es un estandard, el TRON.

http://en.wikipedia.org/wiki/TRON_Project

Este OS corria ya ventanas cuando microsoft presionaba en japon para que se use DOS, patetico.

Otros RTOS:
uCos         El Papa de todos los RTOS
CMX
QNX
SALVO      Ideal para micros pequeños como los pics.
PICOS
FREERTOS Gratuito y potente.


Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 03 de Febrero de 2007, 10:08:03
Bueno veo que a ustedes, amigos, le ha picado el bichito.

El lunes les caigo con la próxima entrega. Voy a dedicar parte del fin de semana a preperar el esqueleto de una especie de curso sobre el tema, y el lunes lo publico. vamos a ver si hacemos un lindo proyecto sobre el tema.

De momento los que puedan que revisen el código de Darukur, porque yo estaré ocupado, y además estudiarse también el RTOS de venezuela, a ver si sacamos nosotros nuestro propio RTOS, por supuesto que sea GNU. En este sentido la propuesta de Darukur me parece muy buena como comienzo.

Les adelanto que la próxima entrega rondará alrededor del concepto de SO y las distintas clasificaciones de los mismos, de este modo sabremos en que campo de los SO, nos vamos a meter.

A aquellos que se sientan intersados pero temerosos les comento que yo jamás he tocado el interior de un SO, hasta ahora, pero como de los cobardes no se ha escrito nada bueno, le voy a poner todo el empeño para que esto salga bien y la comunidad se beneficie. Espero la colaboración de todo aquel que pueda aportar algo, por poco que sea.

Bueno hasta la próxima entonces
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 03 de Febrero de 2007, 11:14:36
pues cuenten conmigo!!! ya me consegui el libro q recomendastes lo encontre en la biblio de la u, ahora lo leo!!!  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: ESTECA55 en 03 de Febrero de 2007, 11:37:36
Muy interesante reiniertl, no tenia idea de estas aplicaciones, soy nuevo en el ámbito de los microcontroladores, este año curso Tecnicas Digitales 2, ahí espero aprender mucho mas sobre estos temas.

Saludos, 

a la espera de la segunda entrega!!!
Título: Re: Sistemas operativos en PIC
Publicado por: akira_ve en 03 de Febrero de 2007, 12:14:47
bueno amigos alguien sabe que fue el estandard MSX ?

les dare una lijero comentario de eso poco antes que IBM presentara el estandar PC los japones crearon el estandar MSX basado en el microcontrolador de la ZILOG Z80, y las compañias lideres como sony, yamaha, crearon sus version, la idea era contar en un sistema compatible entre todas las compañias pues en esos dias cada fabricante escojia el micro para sus diseños que los hacia incompatible.

es mas en ese entonces casi adquiero una commedor 64, en vista de esto los japoneces crearon este estandar........y luego creaeron es MSx2 para usar una version del Z80 que era de 16 bit pero IBM lanzo e estandar PC y lo demas es historia
y saben que?? Bill Gate, estaba metido en ese medio de ese estandar, por lo tanto si este estandar lo usaramos ahorita el estaria metiendos sus manos alli.......
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 03 de Febrero de 2007, 12:27:16
Dos cositas:

-Un libro excelente para empezar con OS sobre microcontroladores: An embedded software Primer (si lo consiguen avisen nadie lo comparte)

-MSX Significa MicroSoft eXtended, osea que nacio en Microsoft. Igual yo era de la commodore....  :mrgreen:
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 05 de Febrero de 2007, 13:41:13
Ya estuve "cacharreando" el RTOS de CCS y creo que para empezar está bien, sin embargo me fui al link de FreeRTOS y me parece que es mejor opción en muchos sentidos que el RTOS de CCS, entre otras cosas, porque tienes acceso al código fuente y podemos además de utilizar el RTOS, optimizar FreeRTOS para nosotros mismos.

Sin embargo quisiera que alguien me dijera donde consigo una versión del compilador GCC para PIC's, si es que existe. El código de FreeRTOS para PIC's está escrito con GCC, pero no dicen donde se puede obtener. Además mi intención futura con la idea de los SO para PIC's es que utilicemos, siempre que se pueda, software bajo licencias GNU. Las ventajas al respecto no hay que explicarlas pero puedo enumerar algunas: acceso al código fuente, menor o cero costos en licencias y una comunidad colaborando para mejorar constantemente los productos on conocimiento de que se hace y por qué.

Entonces, espero sus respuestas.

Gracias por el interés.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 05 de Febrero de 2007, 15:01:48
¿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 dar una definición definitiva de lo que es un SO. El problema consiste en que los SO tienen la característica de comportarse para el usuario (que puede ser una persona cualquiera, un programador, o un programa de computadora), como un tipo con "doble personalidad", veamos esto con más detenimiento.

El SO como máquina extendida
En esta faceta de la personalidad del SO, la característica destacable es simplificar al programador los detalles del 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ípico son las funciones output_x() e input_x() del compilador CCS. Un programador puede utilizar estas funciones sin conocer que para que los datos se pongan en los pines o se lean, hay que cambiar varios registros en el uC. Se dice que estas funciones son una abstracción del proceso de E/S en puerto. Esto es bueno porque ayuda a los programadores a desarrollar soluciones más rápidamente y con menor probabilidad de errores ya que 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 los recursos del sistema, sin tener que profundizar demasiado en los detalles del funcionamiento de sus diferentes componentes. Esta interfaz que el SO ofrece al programador o el usuario, se conoce comúnmente como Llamadas 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 que hoy se clasifican a las llamadas al sistema, ya que en nuestro mundo todo es pequeño en cuanto a capacidad y el crear una máquina extendida poderosa consume recursos que usualmente no tendremos. Entonces en este caso la máquina extendida queda limitada a algunas llamadas a funciones del SO y al uso de las librerías que hasta el momento hemos utilizado habitualmente.

El SO como administrador de recursos
En este caso el SO, se comporta como un administrador de nuestros recursos. La ventaja de tener alguien que administre eficientemente los recursos consiste en que el SO ofrezca al usuario un conjunto de reglas para compartir 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 tiene que estar muy pendiente de la implementación de su sistema, porque puede que determinados requisitos temporales 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 un SO puede hacerse cargo de todos esos temas de manera eficaz y eficiente, incluso ahorrando memoria y tiempo, y nosotros los programadores concentrarnos en la implementación de la solución, más que en la gestió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 de recursos del SO, por lo que es esta la faceta de personalidad que más a menudo encontraremos en los RTOS.

Clasificación de los SO.
A continuación veremos como se clasifican los SO en cuanto a dos características esenciales


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

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

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 los uC.

Aunque el concepto de "tiempo real" es muy controversial, la idea es ejecutar determinadas tareas de forma que parece que cada tarea se está ejecutando en un sistema independiente, donde el procesador y el resto 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 de ninguna índole.

Otro caso de SO, son los de propósito general como UNIX, LINUX, Windows, en este caso a diferencia de los RTOS, las tareas cambian de prioridades en función de satisfacer las exigencias de los humanos que actúan como usuarios, no importa si algunas cosas se ejecutan o no cumpliendo tiempos estrictos.

Hasta aquí el comentario de hoy, que ha sido bastante extenso. Todavía no he terminado el esqueleto del "curso". Pero en cuanto lo tenga, lo publico, además voy a mejorar un poco lo que he escrito hasta ahora para publicarlo como documento (PDF).

Y basta ya de muela, que eso cansa (a ustedes y a mis pobres dedos). En la próxima entrega ya tendremos código para ejecutar y ver como funciona un RTOS, comenzaremos con el de CCS y en el futuro veremos si no mudamos para el FreeRTOS o el que desarrolla Darukur, eso lo someteremos a votación en el foro.
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 05 de Febrero de 2007, 18:21:40
excelente amigo reiniertl, voy a veriguar sobre el compilador GCC para PIC's,  la priemra vez q lo leo  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: aitopes en 05 de Febrero de 2007, 19:38:24
Citar
Un SO nos puede ayudar a hacer sistemas más estables.

Ya me parecia que Windows no era un SO..... :D
Título: Re: Sistemas operativos en PIC
Publicado por: Mario en 06 de Febrero de 2007, 03:09:40
Muy interesante este hilo, habrá que seguirlo de cerca.
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 06 de Febrero de 2007, 08:40:56
Gracias reiniertl por ayudar a sembrar la semilla de la curiosidad por los RTOS y explicar que es y como trabaja un RTOS.

En el otro post de "RTOS para PIC GNU" habia puesto el enlace al manual del SALVO RTOS.

h**p://rapidshare.com/files/12902417/SalvoUserManual.pdf.html

Aca estan los conceptos de un RTOS.
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 06 de Febrero de 2007, 09:28:23
exceleente info, hoy me sumergo con todos los datos!!!  :mrgreen:
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 07 de Febrero de 2007, 13:16:07
Hola amigos, heme aquí de nuevo con ustedes. Disculpen que no haya posteado más pero es que he estado ocupado. Ahora el contenido del curso lo pueden encontrar también en Microfactory (http://microfactory.blogspot.com/) un blog que he creado para publicar información sobre el diseño de sistemas con microcontroladores. Espero que lo visiten y me dejen sus opiniones.

Hoy mismo espero poner el contenido del próximo tema: Hola mundo con RTOS

He estado revisando la redacción del contenido para publicarla en el Blog, de forma que esté disponible para más gente y que tenga mejor calidad, como la idea es que sea una especie de curso, creo que así está un poco mejor que los mensajes que posteo en el foro.

No se asusten que yo voy a seguir posteando aquí, y en dependencia de como van las cosas, mejoro un poco el contenido y entonces para el Blog.

Bueno, hasta dentro de un rato.
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 07 de Febrero de 2007, 13:29:18
okas amigo !!!  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: akira_ve en 07 de Febrero de 2007, 15:30:23
visite la direccion y vaya es muy interesante esta comensando .todos ayudemos un poco de teria no le hace mal a nadie...........pues todo esto comenso con teorias que a veces tildaban de fantasticas, de ciencia ficcion, de un loco universitario frustrado :shock: :shock:
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 07 de Febrero de 2007, 16:45:04
Hola mundo con RTOS
Después de teorizar un poco sobre los Sistemas Operativos, vamos a introducirnos en la programación de aplicaciones empleando un RTOS.

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

Introducción al RTOS de CCS
La versión del compilador que tengo instalada en estos momentos es la 3.249, así que si en versiones posteriores han aparecido nuevas características, les ruego que lo informen para tomar las debidas providencias 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 multiprocesamiento cooperativo (non preemptive), por lo que es responsabilidad del programador asegurarse de que el control del procesador retorna al planificador de tareas en algún momento. Así que cuando programemos nuestra aplicación, tenemos que asegurarnos de que no llamamos a una función que se queda esperando por algún evento largo como es el caso de gets(), o dentro de un lazo infinito o demasiado extenso.

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

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


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 de ejecución de cada tarea deben ser múltiplos de esta cantidad. Si por ejemplo decimos que el tiempo mínimo de ejecución para todas las tareas es de 1ms, debemos conocer que cada tarea se ejecutará, en menos tiempo que este. Lo realmente importante de este dato es que ayuda a establecer la frecuencia con que se ejecutan las tareas, luego veremos un ejemplo de esto. Este parámetro, si no se especifica, es calculado por el compliador 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 consume cada tarea en ejecutarse, sin embargo como veremos más adelante, la estadística realmente importante 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 tiempo y están activadas las estadísticas, entonces esta tarea es marcada con el valor overrun. Este parámetro es útil para informar al programador que una tarea se ha pasado de su tiempo de ejecución, y si el RTOS fuera de tiempo compartido seguramente especificaría el tiempo en que el planificador le retira el procesador para dárselo a otra tarea.
queue: especifica el tamaño de la cola de mensajes de la tarea. Si la tarea no recibe mensajes, entonces debe dejarse 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, la utilidad de esto es mejor verla con un ejemplo.

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

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


El código lo pongo a continuación y posteriormente les doy una explicación:
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) //temporizador Timer0, tiempo mínimo de ejecución de cada tarea 10ms
  4. int8 test;
  5.  
  6. //Definición de las prototipos de función de las tareas
  7. #task (rate=1s, max=10ms)  //Ejecutar cada 1 segundo y consumir como máximo 10ms
  8. void Tarea1();
  9.  
  10. #task (rate=2s, max=5ms)  //Ejecutar cada 2 segundos y consumir como máximo 5ms
  11. void Tarea2();
  12.  
  13. #task (rate=3s, max=250us)  //Ejecutar cada 3 segundo y consumir como máximo 250us
  14. void Tarea3();
  15.  
  16. void main()
  17. {
  18.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  19.    rtos_run();  //A partir de aquí comenzará la ejecución de las tareas
  20.  
  21. }
  22.  
  23. //Implementación de las tareas
  24. void Tarea1()
  25. {
  26.   printf("Ejecutada tarea 1\r");
  27. }
  28.  
  29.  
  30. void Tarea2()
  31. {
  32.   printf("Ejecutada tarea 2\r");
  33. }
  34.  
  35. void Tarea3()
  36. {
  37.  printf("Ejecutada tarea 3\r");
  38. }


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 pueden comprobar que primero se ejecuta la Tarea 1, pero después comprobarán que las tareas no se ejecutan en orden 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 al planificador con que frecuencia ejecutar cada tarea. Este programa puede ser fácilmente modificado para cualquier aplicación específica, un ejemplo que se me ocurre es la lectura de teclados y eliminación de rebotes.
Como tarea les dejo que elaboren un programa sin el uso del RTOS que haga lo mismo que este.
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 07 de Febrero de 2007, 17:18:53
¡Fantástico, clarificador, ejemplar, didáctico!

Gracias por el post, reiniertl.

Además, tu encargo final de realizar la misma aplicación sin RTOS es lo que realmente me ha abierto los ojos de la potencia de los mismos para este tipo de aplicaciones.

Espero con avidez tu próximo post de este cursillo acelerado porque no tienen desperdicio.

Gracias de nuevo.
Título: Re: Sistemas operativos en PIC
Publicado por: FJPPitta en 07 de Febrero de 2007, 21:26:25
Ya me va quedando mas claro el uso de RTOS. :)
Título: Re: Sistemas operativos en PIC
Publicado por: PalitroqueZ en 08 de Febrero de 2007, 12:03:49
la pregunta que hice en el otro post (http://www.todopic.com.ar/foros/index.php?topic=15561.60;topicseen) ha quedado respondida.  8)

Gracias reiniertl

Salu2
Pedro
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 08 de Febrero de 2007, 16:05:39
Me agrada que les haya gustado el ejemplo.

Pero si creen que el ejemplo anterior es fuerte, esperen aver lo que pienso preparar para la próxima entrega ya que solamente hemos arañado la superficie de las portencialidades de los SO.

Bueno amigos espero que le den buen uso a lo que aprendan de los RTOS y recuerden que todo lo que ya conozco al respeco y todo lo que aprenda espero compartirlo con Uds, y en respuesta solo quiero que estudien y se preparen bien para que compartan.

La próxima entrega tal vez demore uno o dos días más porque las cosas ya se están complicando y tengo que ver de que forma las enfoco para que todo mundo me entienda.

Pronto nos introduciremos en el tema de cómo eliminar el PIC-egoísmo, es decir, estudiaremos como ceder el procesador cuando no nos hace falta, y como recuperarlo en el momento apropiado. Esto lleva un poco de teoría, así que a lijar los platinos y a limpiar las bujías que hay que "quemar" bastante para sacar jugo al RTOS

Hasta muy pronto Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: MGLSOFT en 08 de Febrero de 2007, 16:36:40
Esperaremos ansiosos!!
Ya me apunte al hilo, porque entre Darukur y tu me han despertado la curiosidad!!! :D :D :D
Título: Re: Sistemas operativos en PIC
Publicado por: vicent en 08 de Febrero de 2007, 19:55:53
En la carrera, hemos estudiado un SO desde el diseño a la implementación, el KMOS, y la verdad es que es algo muy potente si se usa adecuadamente.
Me parece que para los PICs puede ser un adelanto grande según para que cosas.

Lo veo muy interesante, lástima no tener tiempo para investigar tantas cosas como me gustaría.

Un saludo. Au.
Título: Re: Sistemas operativos en PIC
Publicado por: Y@el en 08 de Febrero de 2007, 20:23:31
Hola amigos, acabo de encontrar este link interesante
h**p://www.avaxhome.ru/ebooks/vahvus-silberschatz-espanol.html

saludos,

Yoel
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 09 de Febrero de 2007, 18:20:56
Controlando la ejecución de las tareas
Hola, en la pasada entrega sobre programación con el RTOS de CCS vimos como es que el planificador programaba la ejecución de las tareas que estaban activas para ser ejecutadas. Pero como es lógico en todo momento las tareas 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 de tareas la pondrá en la cola de ejecución para ejecutarla cuando le llega su turno. Sin embargo en muchas ocasiones 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 la implementació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 embargo combinemos esta característica con lo aprendido en el ejemplo de la entrega anterior y comprobaremos que si hay ventajas, y por cierto nada despreciables.

La ventaja principal con respecto al método tradicional consiste en que usted hace la consulta para comprobar si hay que ejecutar la función, sin embargo ahora solamente le dice al RTOS, habilita a la tarea tal y ponla a ejecutarse cuando le corresponda y se olvida de todos los problemas asociados respecto al tema de cuando le corresponde ejecutarse la tarea y demás. ¿Alguien se acuerda de los molestos temporizadores, banderas, registros y Dios sabe cuantos engendros de control 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 para que 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 otro amarillo en RB2. Vamos a encender y apagar los LEDs con una frecuencia determinada y a intervalos regulares segú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
Comezamos por el LED rojo nuevamente y repetimos el ciclo

Programa

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:
Al inicio solamente la tarea LED_R estará habilitada, una vez que LED_R ha concluido inicia la tarea LED_V y se 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 se autodeshabilita y deshabilita a LED_V y LED_A
Veamos 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. //Como el reloj de este micro se ha puesto a correr con 20MHz el Timer0 no tiene
  4. //mayor resolución que 10ms, es por eso que el tiempo mínimo de ejecución es de 10ms
  5. #use RTOS(timer=0, minor_cycle=10ms)
  6.  
  7. int1 iB0, iB1, iB2;
  8. int1 iLEDS = 0;
  9. int8 iCountR = 0;
  10. int8 iCountV = 0;
  11. int8 iCountA = 0;
  12. int8 iCount  = 0;
  13.  
  14. #task (rate=10ms, max=10ms)
  15. void Task_Disabler();
  16.  
  17. #task (rate=250ms, max=10ms)
  18. void LED_R();
  19.  
  20. #task (rate=350ms, max=10ms)
  21. void LED_V();
  22.  
  23. #task (rate=450ms, max=10ms)
  24. void LED_A();
  25.  
  26. #task (rate=5s, max=10ms)
  27. void LEDS();
  28.  
  29. void main()
  30. {
  31.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  32.    rtos_run();
  33.  
  34. }
  35.  
  36. //esta es una función truculenta porque las tareas no pueden crearse deshabilitadas
  37. //y no se pueden deshabilitar hasta que el RTOS esté funcionando. Lo considero una
  38. //deficiencia sustancial de este RTOS
  39. void Task_Disabler()
  40. {
  41.  rtos_disable(LED_V);
  42.  rtos_disable(LED_A);
  43.  rtos_disable(LEDS);
  44.  rtos_disable(Task_Disabler);
  45. }
  46.  
  47.  
  48. //cada tarea tiene un contador para llevar la cantidad de veces que se pasa por la
  49. //función y cuando se cumple el tiempo establecido entonces habilita y deshabilita
  50. //las tareas correspondientes
  51. void LED_R()
  52. {
  53.  
  54.   iB0 = !iB0;
  55.   output_bit( PIN_B0,  iB0);
  56.   if (iCountR++==20)
  57.      {
  58.        iCountR = 0;
  59.        rtos_disable(LED_R);
  60.        rtos_enable(LED_V);
  61.      }
  62. }
  63.  
  64.  
  65. void LED_V()
  66. {
  67.   iB1 = !iB1;
  68.   output_bit( PIN_B1,  iB1);
  69.   if (iCountV++==27)
  70.      {
  71.        iCountV = 0;
  72.        rtos_disable(LED_V);
  73.        rtos_enable(LED_A);
  74.      }
  75. }
  76.  
  77. void LED_A()
  78. {
  79.   iB2 = !iB2;
  80.   output_bit( PIN_B2,  iB2);
  81.   if (iCountA++==33)
  82.      {
  83.        iCountA = 0;
  84.        rtos_disable(LED_A);
  85.        rtos_enable(LEDS);
  86.      }
  87. }
  88.  
  89.  
  90. void LEDS()
  91. {
  92.   if(!iLEDS)
  93.    {
  94.      rtos_enable(LED_R);
  95.      rtos_enable(LED_V);
  96.      rtos_enable(LED_A);
  97.      iLEDS = 1;
  98.    }
  99.      else
  100.       {
  101.        rtos_disable(LED_V);  //Hay que habilitar y deshabilitar explícitamente
  102.        rtos_disable(LED_A);  //cada tarea sobre todo LED_R que debe continuar
  103.        rtos_disable(LEDS);   //ejecutándose otros 5 segundos más
  104.        rtos_enable(LED_R);
  105.        iCountR = 0;
  106.        iCountV = 0;
  107.        iCountA = 0;
  108.        iLEDS = 0;
  109.       }
  110. }
  111.  
  112.  
  113.  


Cuando corran y simulen el ejemplo verán que a veces los LEDs se quedan encendidos o apagados indistintamente, este es un problema del programa, ya que lo deseable sería que los LEDs se quedaran apagados cuando termina la función. Sin embargo lo he dejado así porque en el futuro vamos a ver cómo podemos 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 dos horas 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'etodo simple, pero hay otros mucho más elaborados que iremos viendo poco a poco. La próxima entrega será yield() vs delay(), vamos a ver el método de las esperas eficientes.

Chao amigos y que lo disfruten.
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 09 de Febrero de 2007, 21:17:19
 :-/ :-/ QUE BUENA INICIATIVA   :-/ :-/ Muchas felicitaciones por compartir tus conocimentos con nosotros.

Gracias!!!!
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 10 de Febrero de 2007, 03:30:12
Reiniertl, he modificado tu post para aplicar "Geshi" al código, lo cual facilita su lectura. Ánimo con tu curso.
Título: Re: Sistemas operativos en PIC
Publicado por: aitopes en 10 de Febrero de 2007, 08:53:28
¡Epa! Esos son colores nuevos?
Yo estaba acostumbrado al codigo en gris.....Esto esta mejor.

Por cierto, muy interesante tu aporte, Reiniertl!
Título: Re: Sistemas operativos en PIC
Publicado por: Y@el en 12 de Febrero de 2007, 23:58:51
Reiniert,

Gracias por hacer esto de la manera mas entendible posible.

Has hecho que por fin le ponga ganas a la programacion en C....

Por cierto estuve buscando informacion y encontre esta web, que esta muy interesante: http://www.dea.icai.upco.es/daniel/asignaturas/TiempoReal/

Saludos,

Yoel
Título: Re: Sistemas operativos en PIC
Publicado por: togarha en 13 de Febrero de 2007, 05:01:33
Muy interesante el tema, me apunto a seguirlo...

Título: Re: Sistemas operativos en PIC
Publicado por: Milo en 13 de Febrero de 2007, 07:37:14

Y yo también. :-/
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 13 de Febrero de 2007, 15:15:41
Yield vs delay
¿Cuantas veces en nuestras aplicaciones tenemos que situar demoras para esperar la ocurrencia de un evento determinado? Por ejemplo, para eliminar rebotes en un teclado, esperar a que el conversor AD termine y quién sabe cuantas cosas más.
Normalmente estas demoras se hacen poniendo al procesador a decrementar contadores y dar saltos recursivos 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.
Sin embargo un RTOS nos ofrece un conjunto de herramientas para eliminar este molesto inconveniente, el más sencillo de ellos es aquel que le permite a una tarea decirle al RTOS: ponme a dormir hasta que me toque de 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 puede dedicarse a realizar otras tareas útiles y hacer de la espera ocupada una espera eficiente. Para la tarea que está dormida esto no representa nada, a ella le da lo mismo ocupar al procesador en hacer nada que en hacer algo productivo, sin embargo no ocurre lo mismo para el resto de las tareas que están esperando que se les entregue el procesador.
Otro caso en que yield() nos puede ser útil es para entregar el procesador cuando nos hemos pasado de tiempo en la ejecución de alguna tarea. Ya sabemos que el RTOS de CCS es cooperativo, por lo que si una tarea consume más tiempo de la cuenta puede hacer que el sistema colapse, ya que hay que entregar explí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 pasado de tiempo, y con ello implementar mecanismos adecuados para que la tarea en cuestión reajuste su dinámica y ceda el procesador oportunamente, para ello podemos auxiliarnos de la función rtos_overrun(). Esta función no tiene valor si se usa dentro de una tarea para comprobar si ella misma se ha pasado porque la actualización de las estadísticas se hace después de ceder el procesador, considero que esta es una de las debilidades de este RTOS, en ese sentido.
El uso de rtos_overrun(), debería poderse utilizar dentro de una misma tarea para comprobar si desde que me cedieron el procesador para ejecutar, me he pasado de tiempo o no y en consecuencia entregar el procesador al RTOS.
En el ejemplo que les traigo hoy vamos a emplear rtos_yield() para ceder el procesador y rtos_overrun() para conocer 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 la tarea durante un período completo del valor rate, que especificamos al declarar la función como una tarea del RTOS, 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 eficientes vinculadas al uso de recursos compartidos en nuestras aplicaciones. El uso eficiente del procesador, los recursos del sistema y la no linealidad en la ejecución de las tareas en un sistema que emplea SO, ha obligado a los diseñadores de SO a crear mecanismos para proteger los datos y hacer uso de esos recursos de forma ordenada y segura. Estos mecanismos se clasifican en dos grupos: La sincronización y la coordinación que comenzaremos a ver en la próxima entrega.
Ejemplo:
Implemente en un PIC16F877 una aplicación en la que se ejecuten tres tareas, con las siguientes caracterí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 una bandera a 1, para indicar que ha concluido. Debe colocar en esta tarea código para que la tarea ceda el procesador en algún momento al RTOS. El tiempo máximo de ejecución de esta tarea es de 10ms y debe ejecutarse cada 30ms
La tarea No. 2 debe esperar a que la tarea No. 1 termine para enviar por el puerto serie un mensaje similar al de la tarea No. 1, sin embargo, esta tarea también enviará, por el puerto serie, un mensaje cada vez que le cede 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 y enviar un menaje por el puerto serie en caso de que la Tarea 1 o la Tarea 2 se hayan pasado en algún momento de su tiempo de ejecución. El tiempo de procesador para esta tarea debe ser de 10ms
Código:
Código: C
  1. #include "D:\Documentos\Projects\RTOS\RTOS.h"
  2. #use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=9)
  3. #use RTOS(timer=0, minor_cycle=10ms, statistics) //se utilizan las estadísticas
  4.                                                   //hace falta para usar rtos_overrun()
  5. int32 iT1Counter = 0;
  6. int1  bT1Flag = 0;
  7. int1  bLed = 0;
  8.  
  9. #task (rate=30ms, max=10ms)
  10. void Tarea1();
  11.  
  12. #task (rate=40ms, max=10ms)
  13. void tarea2();
  14.  
  15. #task (rate=100ms, max=10ms)
  16. void Tarea3();
  17.  
  18.  
  19. void main()
  20. {
  21.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  22.    rtos_run();
  23.  
  24. }
  25.  
  26.  
  27. void Tarea1()
  28. {
  29.  bT1Flag = 0;
  30.  for(iT1Counter = 0; iT1Counter <= 1000; iT1Counter++)
  31.     { if(!(iT1Counter%100))  //mecanismo para ceder el procesador cada cierto tiempo
  32.           rtos_yield(); //cuando la tarea entra en contexto se comienza a ejecutar
  33.                         //la línea a continuación de esta
  34.     }
  35.  
  36.  printf("Tarea contadora completada\r");
  37.  bT1Flag = 1;
  38. }
  39.  
  40.  
  41. void tarea2()
  42. {
  43.   //Aunque esta tarea no tiene que preocuparse mucho por ceder el procesador
  44.   //porque no tiene lazos infinitos o algo parecido puse de ejemplo tambien a
  45.   //rtos yield
  46.  if(bT1Flag)
  47.     printf("Espera por Tarea1 concluida\r");
  48.      else
  49.       {
  50.         printf("dormir T2\r");
  51.         rtos_yield();
  52.       }
  53. }
  54.  
  55. void Tarea3()
  56. {
  57.   bLed = !bLed;
  58.   output_bit( PIN_B0, bLed);
  59.   if(rtos_overrun(Tarea1))  //Si las tareas se pasaron de su tiempo de ejecución
  60.                             //se envían los mensajes por el pto serie
  61.      printf("Tarea 1 overrun\r");
  62.   if(rtos_overrun(Tarea2))
  63.      printf("Tarea 2 overrun\r");
  64. }
  65.  
Como pueden observar, este ejemplo realmente no se corresponde con una aplicación que haga algo útil, sin embargo, me ha servido para ilustrar el uso de las funciones rtos_yield() y rtos_overrun() de la manera más sencilla que encontré. Las posibilidades de estas funciones están ahora en sus manos y en lo que sus cabezas puedan crear para ellas. Hay muchísimas aplicaciones en las que pueden ser útiles, sin embargo, ya el tema de los RTOS es bastante complicado como para meternos a hacer programas complejos que demuestren su 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.
Título: Re: Sistemas operativos en PIC
Publicado por: PalitroqueZ en 15 de Febrero de 2007, 16:43:21
Hola reiniertl. ahora que hablas de la frase "cooperativo" voy a hacer una analogía con lo que sucede en el sistema operativo Windows:

Esto es un extracto del documento El Registro de Windows y temas relacionados (http://www.gbcomputacion.com.ar/web/tutoriales/pdf/registro.pdf) 14.6 Multitarea real página 35
Código: [Seleccionar]
...
1 ) Intercambio de tareas.
2 ) Prioridad de las tareas.
El intercambio de tareas, es simplemente el guardar el estado de una tarea cuando
ha agotado su tiempo (sus quantums asignados), recuperar el estado de otra tarea
y cederle el control. Normalmente esto se puede realizar por el hardware de la CPU
(existe una instrucción especifica para ello, en "todas" las CPUs del mercado, incluidos
los mainframes). Pero Microsoft en vez de utilizar el mecanismo hardware,
lo hace por software, "a mano". Esto es muy costoso en ciclos de reloj, pero aparentemente,
Microsoft no se fiaba, al menos al principio, de la implementación de
este mecanismo en la CPU por parte de Intel.
Prioridad de las tareas, es simplemente un numero asignado a cada tarea, que indica
el numero de "quantums" que puede ejecutar antes de que el sistema operativo
tome control y le ceda el control a otra tarea.
Hay que hacer notar, que una tarea, puede "perder" el control, antes de agotar su
numero de quantums. Sí esa tarea hace una petición de entrada / salida a disco por
ejemplo, debido a que esa petición es muy costosa en tiempo (estamos hablando
de algunos milisegundos), mientras se ejecuta, evidentemente la CPU puede hacer
muchísimas mas cosas. Por tanto el sistema operativo toma el control y se lo cede
a otra tarea.

El sistema operativo, debe ser "listo". Debe jugar con las prioridades de tarea y variarlas
ligeramente. Es decir, a un programa que hace muchas entradas/salida, debido
a que está poco tiempo en memoria, el sistema operativo le debería subir la
prioridad. En cambio al revés, a un programa que chupa mucha CPU y no realiza
apenas entrada / salida, el sistema operativo debe bajarle la prioridad al objeto de
que no se apodere todo el tiempo de la CPU.
...

en este parrafo hablan que existen 2 tipos de multitareas: el cooperativo y el "Real", el cooperativo lo usaban los antiguos windows (3.1 y MSDOS) y el problema que tenian era precisamente que si su mensajeria fallaba, entonces comprometería al resto de las tareas por ejecutar.

después llegó el "Real" (que no es real en verdad :)) cuyo cambio se debió a que cada tarea actuaba independientemente de la otra, como una especie de maquina virtual, y que si alguna tarea fallaba, simplemente el SO la desechaba y no interfería con el resto de las tareas y SO en sí.

el gran problema que suscitó el Windows fué la llamada compatibilidad ascendente (justa pero dañina al mismo tiempo) era que ya para el windows 95 en adelante estos aceptaban los 2 tipos de tareas, y copiandome de una formula:  "está demostrado que si en hay un sistema seguro + sistema inseguro -> sistema inseguro".


el tema que estas hablando tiene cierta analogía con lo que expuse, pero logicamente que esto es mas reservado y esperemos no tener inconvenientes con las cooperaciones en un RTOS.

Salu2
Pedro

PD: disculpa la intromisión  8)

Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 15 de Febrero de 2007, 16:57:07
Bueno, pues yo los esta suguiendo de ladito, y pues pensaba demorarme mas en implementar este tipo de programacion, pero Gracias a un amigote YOEL, me ha convencido de trabajar con esto de los RTOS. Es por ello, que no se si sea conveniente preguntar en este mismo hilo, o creo uno nuevo solo para preguntas y pues dejar este solo para las clases que nos estas dando. jejeje  :-)

Nuevamente Gracias por tomar esta iniciativa de enseñarnos paso a paso esto de los RTOS.

Saludos!
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 15 de Febrero de 2007, 18:55:43
Referente al tema de aprender sobre los RTOS (las cosas relacionadas con este cursillo), espero las preguntas por aqu'i, porque así me realimento para mejorar el contenido. Si lo que quieren es hablar de diseño de RTOS, es mejor que vayan al hilo del amigo Darukur.

Sobre lo que Palitroquez planteo respecto a lo de Windows, puedo hacer algunas aclaraciones más adelante, porque ese es el tema de mi trabajo de la asignatura de la maestría que me tiene muy ocupado y por lo cuál no he podido dedicarme a elaborar la próxima entrega del curso. Espero tenerla para el lunes

Chao
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse 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!
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl 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 (http://www.todopic.com.ar/foros/index.php?topic=16080.0)

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
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur 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
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 19 de Febrero de 2007, 09:28:47
Esta bien, disculpas. Entiendo.

Saludos.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl 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. }
  67.  
  68.  

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
Título: Re: Sistemas operativos en PIC
Publicado por: lous 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.
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur 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
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl 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
Título: Re: Sistemas operativos en PIC
Publicado por: SimonMG 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
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl 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
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 22 de Febrero de 2007, 18:48:49
Será larga la espera, pero seguro que merece la pena. Por aquí te esperamos.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl 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
Título: En sus marcas, listos, ¡FUERA!
Publicado por: reiniertl 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 (http://www.4shared.com/file/11454967/20dbdac4/RTOS_Sincro.html) 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. }
  101.  

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.
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno 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.
Título: Re: Sistemas operativos en PIC
Publicado por: PalitroqueZ 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
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 28 de Febrero de 2007, 16:04:20
Lo que más me sorprende es lo rápido que han contestado a este post, pareciera que me estaban esperando, realmente no estoy muy contento con la entrega de hoy, porque estoy un poco cansado del esfuerzo de estos últimos días, pero me gusta cumplir mis promesas así que por eso publiqué hoy.

Las gracias son bienvenidas, el esfuerzo no será en vano y yo mismo estoy aprendiendo mucho para poder escribir estos "articulillos".

Gracias a ustedes por prestar un poco de atención.
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 28 de Febrero de 2007, 20:12:07
Gracias reiniert. Esto es como tener a un perrito esperando por la proxima galletita. !! es muy bueno lo que estas haciendo y te agradezco nuevamente.

Saludos!
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 02 de Marzo de 2007, 14:28:18
RTOS mail

Hasta el momento solamente hemos visto mecanismos que nos permiten simplificar el diseño de nuestros programas, pero hoy vamos a ver una nueva potencialidad de los RTOS que es una cuestión realmente novedosa 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 hacer su tarea, mientras la función trabaja, nuestro programa espera pacientemente a que la función retorne y nos devuelva el resultado, que puede ser un valor de retorno, un arreglo cambiado o simplemente el cambio en el estado 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 nunca hemos visto que una función le envíe un dato a otra (no en la llamada a la función, sino fuera de ésta) para que cuando le toque ejecutarse tome esos valores y los procese, y si hay que devolver algún resultado entonces que nos envíe un acuse de recibo. Es lógico que un mecanismo como el que acabo de describir no se utilice en las técnicas de programación anterior porque la ejecución secuencial del código presupone que no se requiera 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 uso de las interrupciones, éstas deben procesar rápidamente el evento de interrupción y pude que pongamos el dato en algún lugar y levantemos una bandera para que cuando a la función encargada de procesar los datos le toque ejecutarse lea la bandera, procese los datos y coloque la bandera en el estado que notifica que ya se procesó, no para notificar a otra función sino para notificárselo a ella misma, no vaya a ser que cuando le toque 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 a convertir; una vez hecha la conversión se produce una interrupción que es atendida en la correspondiente subrutina de atención a esa interrupción; leemos el dato lo ponemos en una variable e incrementamos un contador. 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. Este mecanismo es eficaz porque se ha utilizado durante mucho tiempo, pero los RTOS brindan una solución elegante 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ódigo que se ejecuta más o menos estructuradamente, lo que tenemos es unas cuantas tareas de las que no tenemos un control de cuando ni como se ejecutarán. Realmente puede ser una verdadera pesadilla hacer un programa productivo, y es por ello que los RTOS nos ofrecen un poderoso mecanismo para hacer eso, y como siempre, este mecanismo también es relativamente simple.

Para hacer lo anterior los RTOS implementan un mecanismo de mensajes. Sí, amigos míos, un RTOS implementa 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 interrupciones necesita 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 de mensajes, si hay mensajes debe leerlos y procesarlos, como pueden ver este mecanismo es bastante parecido a lo que hacemos habitualmente.

Si yo quiero pasarles un mensaje, este post por ejemplo:

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

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

Lo primero que tenemos que hacer es decirle al compilador que le cree una cola de mensajes a aquella tarea a la cual queremos pasarle mensajes, para eso tenemos el parámetro queue, dentro de la directiva #task, con este parámetro le indicamos al RTOS que reserve memoria y cree una cola de mensajes para la tarea, la declaración de una tarea con cola de mensajes sería como sigue:
Código: C++
  1. #task(rate = 1s, max=20ms, queue=5)
  2. 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 para la Tarea1.

Para el envío y recepción de mensajes tenemos las siguientes funciones:
RTOS_MSG_SEND( )
RTOS_MSG_POLL( )
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 una subrutina de atención a interrupción se le envíen mensajes a una tarea. El parámetro task es para el nombre de la tarea y byte es un dato de 8 bits (un char o un int8), así que si queremos enviar un float o una estructura tendremos que descomponer antes ese dato en bytes y luego componerlos cuando la cola de mensajes sea leída.

int RTOS_MSG_POLL(); es la función que permite a una tarea conocer si tiene mensajes en su cola de mensajes, no se puede llamar desde otra tarea para conocer cuantos mensajes tiene la tarea fulana. Devuelve en 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 el byte 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 no hay 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 para balancear la cantidad de botellas que hay dentro de la cinta transportadora, para ello pondremos una tarea adicional que recibirá de las otras tareas el estado de la cantidad de botellas dentro de la cinta. Si la cinta se está vaciando demasiado rápido, esta tarea se encargará de inhabilitar los robots llenadores de cajas, si se está 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 a la tarea reguladora la cantidad de botellas que hay en la cinta, con este mecanismo evitamos que la tarea supervisora tenga que leer el recurso compartido iCantidad, y que tenga que sincronizarse con los robots. La cola 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 esta tarea la transmisión de la cantidad de botellas que hay en la cinta. La cantidad media de botellas a tener en la cinta es 50.

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. int8 iCantidad; //Esta es la cantidad de botellas en la estera
  6.                  //constituye nuestro recurso compartido
  7.  
  8.  
  9. #task (rate=50ms, max=10ms)
  10. void R_Despachador();
  11.  
  12. #task (rate=50ms, max=10ms)
  13. void R_Llenador1();
  14.  
  15. #task (rate=50ms, max=10ms)
  16. void R_Llenador2();
  17.  
  18. #task (rate=1s, max=10ms, queue=2) //la cola tiene 2 byte aunque solamente necesitamos 1
  19. void Supervisor();
  20.  
  21. void main()
  22. {
  23.    semaphore = 1; //Solo una tarea puede utilizar el recurso cada vez
  24.    iCantidad = 120; //Inicializamos esta variable para tener algunas botellas en
  25.                     //la estera, normalmente deberiamos tener un sensor que nos reporte
  26.                     //en algun momento el total de botellas en la cinta, ya que un
  27.                     //robot revisor de llenado o una persona puede retirar botellas
  28.                     //de la cinta
  29.  
  30.    //Al comenzar todos los robots estan deshabilitados
  31.    output_bit( PIN_B3, 0);
  32.    output_bit( PIN_B4, 0);
  33.    output_bit( PIN_B5, 0);
  34.  
  35.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  36.    rtos_run();
  37.  
  38. }
  39.  
  40.  
  41. void R_Despachador()
  42. {
  43.  //Note como hacemos la sincronizacion fuera de la seccion critica, mas adelante veremos
  44.  //que esto no siempre es posible hacerlo o que las cosas se complican un poco mas
  45.  //de lo que hemos visto hasta ahora.
  46.  rtos_await(iCantidad<100); //Esperemos a que se vacie un poco la cinta
  47.  
  48.  output_bit( PIN_B3, 1); //A partir de aqui, si no se podia antes,  poner botellas
  49.  
  50.  rtos_wait(semaphore); //Reclamamos el recurso y aquí comienza la secc crítica
  51.  
  52.    if(input(PIN_B0)==1)
  53.         iCantidad++;  //sí es didáctico y por eso lo he utilizado así.
  54.  
  55.    if(iCantidad >= 100)
  56.        output_bit( PIN_B3, 0); //Le decimos al robot despachador que no ponga mas botellas
  57.  
  58.  rtos_msg_send(Supervisor, iCantidad); //Enviamos un mensaje con la cant de botellas
  59.  
  60.  rtos_signal(semaphore); //Liberamos el semáforo y aquí se acaba la sec crítica
  61.  
  62.  rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella
  63. }
  64.  
  65.  
  66. void R_Llenador1()
  67. {
  68.   //El robot debe esperar a que la cinta tenga suficientes botellas para sacar antes
  69.   //de comenzar a trabajar.
  70.   rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta
  71.   output_bit( PIN_B4, 1); //A partir de aqui, si no se podia antes, sacar botellas
  72.  
  73.  rtos_wait(semaphore);
  74.  
  75.  if(input(PIN_B1)==1)
  76.     iCantidad -= 12;
  77.  
  78.  if(iCantidad <= 24)
  79.     output_bit( PIN_B4, 0); //Le decimos al robot que no saque mas botellas
  80.  
  81.  rtos_msg_send(Supervisor, iCantidad);  //Enviamos un mensaje con la cant de botellas
  82.  
  83.  rtos_signal(semaphore);
  84.  
  85.  rtos_yield(); // A dormir por otros 50ms para evitar poner dos veces la misma botella
  86.  
  87. }
  88.  
  89. void R_Llenador2()
  90. {
  91.  rtos_await(iCantidad>24); //Esperemos a que se llene un poco la cinta
  92.  output_bit( PIN_B5, 1); //A partir de aqui, si no se podia antes, sacar botellas
  93.  
  94.  rtos_wait(semaphore);
  95.  
  96.  if(input(PIN_B2)==1)
  97.      iCantidad -= 12;
  98.  
  99.  if(iCantidad <= 24)
  100.     output_bit( PIN_B5, 0); //Le decimos al robot que no saque mas botellas
  101.  
  102.  rtos_msg_send(Supervisor, iCantidad); //Enviamos un mensaje con la cant de botellas
  103.  
  104.  rtos_signal(semaphore);
  105.  
  106.  rtos_yield();
  107. }
  108.  
  109. void Supervisor()
  110. {
  111.  int8 iBotellas;
  112.   rtos_await(rtos_msg_poll()>0);  //Esperamos a que haya algun mensaje en la cola
  113.  
  114.  
  115.  iBotellas = rtos_msg_read(); //Leemos el mensaje
  116.  
  117.  //Lo que hacemos ahora es comprobar la cantidad de botellas que hay en la estera
  118.  //y en funcion de eso habilitamos y deshabilitamos las tareas y los robots que hacen falta
  119.  //para controlar la cantidad de botellas en la estera
  120.  if(iBotellas > 50)
  121.    {
  122.  
  123.      output_bit( PIN_B3, 0); //No despachar mas botellas
  124.      rtos_disable(R_Despachador);
  125.  
  126.      rtos_enable(R_Llenador1);
  127.      rtos_enable(R_Llenador2);
  128.  
  129.    }
  130.   else
  131.    {
  132.     rtos_enable(R_Despachador);  //No llenar mas cajas
  133.  
  134.     output_bit( PIN_B4, 0);
  135.     rtos_disable(R_Llenador1);
  136.  
  137.     output_bit( PIN_B5, 0);
  138.     rtos_disable(R_Llenador2);
  139.    }
  140.  
  141.  
  142.  printf("%3.0w \r",iBotellas);  //Transmitir la cantidad de botellas
  143.  
  144. }
  145.  
  146.  
  147.  

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

Bueno espero que les sirva.

Un saludo Reinier

PD: Lo de esta embotelladora es un invento, en ningún momento esto se ha probado en una planta de ese tipo.
El tiempo que utilicé para este ejemplo fue de 3:30 horas, incluyendo la redacción y programación.
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 02 de Marzo de 2007, 15:14:55
:-/ :-/ :-/ Impresionante reinirtl, que nivel,.. Que nivel. Esto realmente te abre puertas a la hora de programar. Te parecerá lo mismo de siempre lo que yo digo pero Muchísimas gracias y siempre diré lo mismo MUCHISIMAS GRACIAS por compartirlo. :mrgreen:
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 02 de Marzo de 2007, 15:32:55
En la próxima entrega, que espero tenerla para el lunes, veremos como mezclar las interrupciones con el servicio de mensajes para hacer funciones mucho más poderosas que las que implementa CCS para atender a unos cuanto de esos periféricos que tienen servicio de interrupción.

Se llamará: ¡Interrupciones...! ¡A MÍ!

Estoy apurandome un poco porque pronto salgo de vacaciones y estaré ausente unos 15 días.

Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: micro_cadaver en 04 de Marzo de 2007, 05:40:34
sigo leyendo tus post y estan muy bien redactados reiniertl  :-), esperamos ansiosos tus siguientes temas  :-/
Título: Re: Sistemas operativos en PIC
Publicado por: Y@el en 04 de Marzo de 2007, 13:34:36
WOW... cada vez, me sorprendo mas, aprendo mas,  y me dan ganas de conocer mas. Es que este mundo del RTOS, nuevo para mi hasta hace poco.  Abre la imaginacion a la gran cantidad de cosas que se pueden hacer, y ni que decir de la metodologia q usas. Es como decian por ahi... enseñar a sumar con manzanitas.... Muy buena por cierto....

Saludos, y gracias por tu bien preciado tiempo.

Yoel
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 05 de Marzo de 2007, 10:45:10
Gente, empece a ver el RTOS uCOS-II de micrium.
Seguramente reiniertl lo debes conocer, es un sistema operativo en tiempo real muy bien documentado y con ports para todos los microcontroladores y compiladores conocidos.
Lo mas importante, se ofrece libremente para su uso académico y estudiantil. Su pagina www.micrium.com
Es un sistema operativo preemptivo excelente, entre otras cosas tien certificaciones tan importantes como el aval para uso en aviones, tal vez deberiamos enfocarnos en el para los ejemplos e informacion de este post.

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: Zaphyrus en 06 de Marzo de 2007, 17:34:06
Darukur, yo me prendo a la idea. Ya estoy por empezar a leer por segunda vez el libro de uCOS-II para poder usarlo en ARM. Sería bueno empezar un hilo para compartir ideas sobre el tema.

Saludos.
Título: Re: Sistemas operativos en PIC
Publicado por: aitopes en 07 de Marzo de 2007, 11:14:31
Hola amigos!
Es un PLACER contarles que Reinier me ha autorizado a darle forma de guia a todo lo posteado en el hilo (e iremos agregando las futuras entregas), y lo he publicado aquí (http://www.ucontrol.com.ar/Articulos/sistemas_operativos_microcontroladores/sistema_operativo_microcontroladores_pic_rtos.htm#2).

Ademas, el documento esta disponible en formato PDF, son 220Kb y unas 22 paginas de informacion sin desperdicio. Lo pueden bajar desde un link en el mismo lugar que mencione (http://www.ucontrol.com.ar/Articulos/sistemas_operativos_microcontroladores/sistema_operativo_microcontroladores_pic_rtos.htm#2).

Saludos!
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 07 de Marzo de 2007, 16:56:11
Hola. Lamento no haber posteado el mensaje sobre las interrupciones y los mensajes

Le problema es que me he complicado un poco con el trabajo y además este viernes me voy de vacaciones y tengo que dejar unas cuantas cosas arregaldas.

Ya casi tengo listo el post, pero es probable que no lo pueda poner hasta mañana. Voy a hacer el mayor esfuerzo posible para poner ese post antes de irme durante una semana completa lejos de la PC, los programas, etc.


Un saludo Reinier
Título: Lo prometido es deuda: ¡Interrupciones! ¡A MÍ!
Publicado por: reiniertl en 08 de Marzo de 2007, 14:17:31
¡Interrupciones! ¡A MÍ!

La oración anterior me hace parecer súper héroe. Aunque yo no lo sea, pero con un RTOS y la técnica que veremos hoy, puedo considerarme uno de ellos, al menos en la programación de microcontroladores, y después de hoy, todos podemos aspirar a ser un RTOS PIC SÚPER-HÉROE.

En la entrega anterior estudiamos el paso de mensajes, pero solamente vimos el paso de mensajes entre tareas, esta posibilidad de los RTOS es poderosa y además es el mejor método para pasar información de una tarea a otra, por su sencillez. El paso de mensajes es una necesidad de los SO, porque como expliqué, las tareas no son como las funciones, a las cuales un segmento de código llama y se queda esperando hasta que la función retorna. Entonces como no sabemos en que momento una tarea entrará en su contexto, hay que crear un mecanismo eficiente para que trabaje con los datos que debe servir otra parte del código.

Además de lo anterior, durante todo el cursillo, no hemos visto ni utilizado ninguna interrupción y eso, desde mi punto de vista, no es nada bueno. Los procesos de interrupción nos permiten atender con eficiencia procesos asincrónicos como la conversión analógica, la escritura en memorias EEPROM, las interrupciones externas, la recepción de datos por la USAR, el PSP o el MSSP y también procesos sincrónicos como los que producen los temporizadores.

Pero el uso de un RTOS, nos plantea un dilema con el uso de las interrupciones, ya que en principio cuando utilizamos un RTOS estamos imponiendo que las tareas se van a ejecutar más o menos cada cierto tiempo o que estarán bloqueadas en espera de algo. Por lo tanto, si deseamos que una tarea atienda un proceso asincrónico, ésta debe hacerlo por encuesta, es decir cuando le toque ejecutarse debe comprobar si hay información que procesar. Por otro lado, las interrupciones cuando ocurren, deben ser atendidas en el instante y no cuando al RTOS considere que deben ser atendidas.

Ahora tenemos por un lado una herramienta que nos obliga a utilizar los mecanismos de encuesta, el RTOS, pero que nos ayuda a crear código robusto, eficiente y con velocidad, ventajas nada despreciables. Por otro tenemos un mecanismo para atender procesos que no pueden esperar mucho tiempo en ser atendidos o se corre el riesgo de perder la información, y perder datos es inaceptable para un sistema embebido. Entonces: ¿cómo hacer para aprovechar de las ventajas de ambos?

Para solucionar este problema los RTOS deben permitir que desde una ISR (subrutina de atención a interrupción) podamos pasarle mensajes a cualquier tarea que lo requiera. Vamos a ver esta ventaja con un ejemplito simple.

Supongamos que tenemos una aplicación que tiene varias tareas, entre ellas hay una dedicada a atender la recepción de datos por el puerto serie, ésta tarea se ejecuta con una frecuencia que permite procesar los datos que llegan desde el puerto serie. Un método para hacerlo sería, que cada vez que a la tarea le toque ejecutarse, ésta compruebe si ha llegado un dato al puerto serie para tomarlo y procesarlo. Eso está bien, pero que pasa si mientras la tarea está esperando su turno de ejecutarse llega más de un dato al puerto serie, por supuesto que se perderán datos y esto si que no podemos permitirlo.

La solución al problema anterior es separar la atención de la llegada de datos al puerto serie del procesamiento de los datos recibidos, para ello dejamos en manos de una ISR la lectura del registro de datos y el control de los registros de estado del puerto serie y que la tarea se encargue, cada cierto tiempo, de procesar la información recibida.

El método anterior se puede implementar si el RTOS permite el paso de mensajes desde una ISR hacia una tarea del RTOS, invocando una función adecuada. De esta forma cuando se produzca la interrupción y nos vayamos hasta la ISR, lo que tenemos que hacer es leer el dato y mandarle un mensaje a la tarea, si llega otro dato lo leemos y lo mandamos y así sucesivamente, si la tarea tiene una cola de mensajes suficientemente larga, no debemos perder datos en la recepción por el puerto serie, aún cuando la tarea se ejecute con una frecuencia menor que la de recepción de datos en el puerto serie.

En el ejemplo de hoy vamos a hacer con RTOS algo parecido a lo que hace la función gets(), con la diferencia de que en vez de quedarnos como tontos esperando a que llegue el carácter de fin de línea o retorno de línea vamos a ceder el procesador cada vez que comprobemos que no ha llegado el carácter de terminación adecuado.

Para la implementación utilizaremos dos PIC16F877, en uno de ellos pondremos un programa que envía una cadena por el puerto serie hasta el otro PIC con una frecuencia de 3 segundos. El PIC que recibe los datos, implementa esta funcionalidad mediante la interrupción de la USART, los cuales pone en la cola de una tarea, la cual va reconstruyendo la cadena, hasta que esta está completa y entonces también la envía por su USART.

Este es el código del PIC que envía la cadena
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.  
  5. int8 iBuffer; //Indice en el buffer para ir llenandolo
  6.  
  7. #task (rate=3s, max=10ms) //Creamos una cola con 10 bytes utiles
  8. void Serial();
  9.  
  10.  
  11. void main()
  12. {
  13.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  14.  
  15.    rtos_run();
  16. }
  17.  
  18.  
  19. void Serial()
  20. {
  21. printf("Prueba\n");
  22. }
  23.  
  24.  


y este el del PIC que recibe y retransmite la cadena
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=10us)
  4.  
  5.  
  6.  
  7. char cBuffer[17] ; //Aqui guardamos el texto a enviar por el puerto serie
  8. int8 iBuffer; //Indice en el buffer para ir llenandolo
  9.  
  10.  
  11. #task (rate=100us, max=10us, queue = 3) //Creamos una cola con 2 bytes utiles
  12. void Serial();
  13.  
  14. void main()
  15. {
  16.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  17.    enable_interrupts(GLOBAL);
  18.    enable_interrupts(INT_RDA);
  19.  
  20.    rtos_run();
  21. }
  22.  
  23.  
  24. void Serial()
  25. {
  26.   char cDato;
  27.   rtos_await(rtos_msg_poll());  //Esperamos hasta que haya algun dato en cola
  28.  
  29.  
  30.   while(rtos_msg_poll())  //Procesamos la cola completa
  31.    {
  32.      cDato = rtos_msg_read();
  33.      cBuffer[iBuffer] = cDato;
  34.      iBuffer++;
  35.    }
  36.  
  37.  
  38.      if(iBuffer == 16 || cDato == '\n') //Si esta toda la cadena la enviamos
  39.         {
  40.          printf("%s\r", cBuffer);
  41.          iBuffer = 0;
  42.         }
  43. }
  44.  
  45.  
  46. #INT_RDA
  47. void fINT_RDA(void)
  48. {
  49.  rtos_msg_send(Serial, getc());  //Tomamos el dato del buffer y lo ponemos en la cola
  50. }
  51.  
  52.  


Aquí está el fichero con los programas y la simulación en proteus: RTOS_ISR (http://www.4shared.com/file/11925904/598a8453/RTOS_ISR.html)

Como verán en la implementación de estos programas he puesto al PIC que retransmite los datos a ejecutar su tarea que procesa los datos recibidos por el puerto serie con una frecuencia mucho mayor que la del PIC que le envía los datos, incluso es mucho más rápida que la velocidad de transmisión recepción de los mensajes, esto me permite tener una cola muy pequeña y que los mensajes no se pierdan.

Yo les aconsejo que jueguen con la frecuencia de ejecución de la tarea, (parámetro rate en la declaración #task) en el PIC que retransmite, y el tamaño de la cola, verán como la cadena a veces se corta, en ocasiones el PIC no retransmite nada. Pero esto les dará una idea de cómo funciona el mecanismo.

Si por ejemplo aumentan la frecuencia de ejecución pueden poner una cola más pequeña, es el código del ejemplo. Si tienen una frecuencia menor, entonces tendrán que poner una cola más grande para que el mensaje quepa completo.

Otra solución a este problema es que la ISR escriba directamente en el Buffer y solamente le mande un mensaje a la tarea cuando se haya recibido el mensaje completo para que esta lo retransmita. Con esto ahorramos memoria RAM, ya que podemos poner una cola muy pequeña, además podemos transferirle a la tarea que atienda los mensajes de error, el procesamiento de comandos y cosas por el estilo. Todo depende de la aplicación y de la imaginación del programador.

Me tomó 1:30 horas escribir el programa y ponerlo a punto, otra hora para escribir el texto y varios días para pensar como enfocarles el problema. Ahora es tarea de ustedes poner todo esto en práctica.

Les propongo que hagan un programa para enviar datos por la USART, similar a printf(), pero más eficiente. Pueden por ejemplo utilizar sprintf(), para poner la cadena en RAM y después que la tarea configure el servicio de interrupciones, mande el primer byte y la ISR envíe el resto, cuando la ISR termine debe notificar a la tarea que ya está en condiciones de enviar más datos, de modo que la tarea le puede crear otra cadena y volver a mandar a transmitir. Notarán que hay que tener unas cuantas cosillas en cuenta, pero es un buen problema para practicar.

Un saludo Reinier.


Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 08 de Marzo de 2007, 17:21:26
Esa misma técnica que utilizas en tu programa la he usado cienes y cienes de veces en programas secuenciales. Lo ideal es que la interrupción esté muy poco tiempo ejecutándose, así que yo preparo los datos en la interrupción para que sean procesados en el bucle principal del programa, tal y como tú has hecho con RTOS.

¿Qué capítulos nos esperan a la vuelta de tus vacaciones?
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 08 de Marzo de 2007, 18:11:10
Los capítulos a las vuelta no son los más alagüeños, voy a tratar la visita de la diosa del infortunio, Némesis.

Los Griegos creian que a los hombres (hablo en sentido genérico) afortunados había que ponerles un límite, por eso crearon a Némesis, la diosa de la fortuna, que podía hacer que los más afortunados conocieran el desasociego y la deseperación, y eso aparece un poco en la programación con SO, vamos a conocer a nuestro enemigo No. 1 el abrazo fatal, y algunas técnicas para salvarnos  de él.

Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 09 de Marzo de 2007, 11:31:49
Que buena forma de enseñar. Aplausos por ello  :D.
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 10 de Marzo de 2007, 10:51:45
Evidentemente reiniertl tienes capacidades de orador / profesor, los tienes todos bien atentos a tus enseñanzas :P :P :P
Te felicito por tu trabajo!

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: Zaphyrus en 10 de Marzo de 2007, 15:17:52
Gracias por el esfuerzo y las horas que has dedicado en compartir tus conocimientos.

Este es el espíritu que hay en las personas que gustan compartir, similar a lo que es el software libre (Open Source), Free Software Fundation y GNU.

El foro de TodoPic está creciendo en cantidad y calidad, esto me pone contento.

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: kamehouse en 13 de Marzo de 2007, 03:43:17
 :-/Felicidades reiniertl por esta gran enseñanza y por compartirlo tan desinteresadamente.Gracias. :-)
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 16 de Marzo de 2007, 12:12:32
Se terminaron mis vacaciones.

Muchas gracias por los agradecimientos, espero que para la semana próxima pueda ponerles nuevos posts sobre este maravilloso mundo de los RTOS.

Así que amigos a prepararnos, (porque yo también tengo mucho que estudiar para escibierles estos posts) para sacarle el jugo a los RTOS.


Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: aitopes en 16 de Marzo de 2007, 12:42:23
Bienvenido! Espero la hayas pasado bien.

Y esperamos esos posts! :)
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 21 de Marzo de 2007, 10:04:43
Estoy un poco ocupado con un trabajo y no he podido tirarle ni un chícharo a esto de los RTOS, pero para el viernes seguro tengo algo listo. Ya lo he estado pensando y recreando en mi procesador central, así que en cuanto tenga un time, lo escribo y lo posteo.

Sinceramente disculpen mis atrasos, se que muchos esperan estos mensajes y a mi mismo me gusta mucho trabajar en ellos porque aprendo un montón de cosas cada vez que les escribo.

Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: maunix en 21 de Marzo de 2007, 16:53:18
Sin embargo quisiera que alguien me dijera donde consigo una versión del compilador GCC para PIC's, si es que existe.

Hasta donde los conocimientos de este mortal llegan, no hay tal cosa y según los que saben es muy difícil que exista un puerto del GCC para los pics. 

Esto lo he visto en piclist, en gnupic y en el foro de Microchip.

Lo más parecido es el puerto para pics del SDCC , codificado por Scott Dattalo.

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: microman en 23 de Marzo de 2007, 15:46:00
Saludos Reinertl,
Te felicito una vez mas por la exelente introducción que estas brindando a cerca de los RTOS.
Quiesiera que me aclares una duda referente al ejemplo q has mostrado en la sección de Insertar Cita
¡Interrupciones! ¡A MÍ!
Tengo entendido q utilizas 2 Pic 16F877 los cuales estan interconectados a traves de su respectiva interfaz serial (USART). Hasta ahi me queda todo claro...lo q no logro entender es si el 2do. Pic q hace de receptor de la cadena del otro y luego lo retransmite...hacia donde...? Es hacia el primero...? Puesto q el Pic solo posee una interfaz fisica ( el primer pic no posee una rutina para la recepcion, aunque entiendo q no habra colision simplemente la cadena retransmitida no tendrá un receptor.. )....la cual esta configuarada al principio....(directiva #use rs232(...)). Si quisieramos debugear en Hardware seria mas interesante retransmitirlo hacia la PC...obviamente a traves de otro puerto USART simulado por soft.

Desde ya gracias..y que siogas adelante, ya que el curso se esta volviendo cada vez mas interesante

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 23 de Marzo de 2007, 17:22:57
La respuesta está en este link: Discusión sobre RTOS (http://www.todopic.com.ar/foros/index.php?topic=16080.0) por motivos que ya he explicado anteriomente.

Un saludo Reinier
Título: Volviendo sobre nuestros pasos
Publicado por: reiniertl en 30 de Marzo de 2007, 19:32:31
Volviendo sobre nuestros pasos


Hasta el momento hemos visto que los RTOS pueden ser muy útiles al enfrentar la implementación de aplicaciones complejas, ellos nos ofrecen herramientas poderosas y simples que facilitan el desarrollo rápido de aplicaciones, las desventajas fundamentales que hemos estado viendo son aceptables cuando las comparamos con los beneficios que obtenemos por utilizar un RTOS.

Hasta hace algún tiempo, el diseño de sistemas con microcontroladores se enfrentaba con horas y horas delante de una PC o con una hoja de papel, escribiendo código en ensamblador y pasando mucho trabajo para que cualquier cosa que diseñásemos funcionara, eso solamente en teoría, ni que decir de llevar esos diseños a la práctica, y tener que lidiar entonces con las PCB, circuitos haciendo cosas “extrañas” y demás.

Con la llegada de los compiladores para lenguajes como C, PASCAL, BASIC y simuladores avanzados como el PROTEUS, los desarrolladores de aplicaciones han tenido un importante respiro para llevar adelante sus diseños. Pero el mercado, y los consumidores se han vuelto más exigentes y la parada ha tenido que subir un poco, la solución: utilizar sistemas operativos en los dispositivos embebidos.

Como toda maravilla tecnológica, el uso de un SO requiere muchas veces perder ciertas ventajas respecto a los métodos anteriores. Cuando programábamos en ensamblador obteníamos el máximo en desempeño y aprovechamiento del microcontrolador pero el desarrollo y puesta a punto era muy lento y las aplicaciones podían tener errores muy difíciles de detectar.

Los compiladores mejoraron el problema de los errores y redujeron considerablemente el tiempo de desarrollo, pero los programas gastan más memoria de programa, memoria de datos y son más lentos en ejecución.

Los SO aumentan las desventajas de los compiladores pero mejoran el desarrollo de aplicaciones en muchos otros aspectos.

La solución al dilema de eficiencia vs eficacia nos la ofrecen los mismos fabricantes de microcontroladores, al diseñar dispositivos cada vez más rápidos y con más memoria. Ahora podemos simplemente movernos entre las diferentes gamas y familias de dispositivos buscando el que se adapta mejor a nuestras necesidades y utilizar métodos de diseño tan avanzados como los RTOS. Los precios no son el mayor problema como antaño, incluso algunos uC ya obsoletos salen más caros que sus sustitutos.

Toda la explicación anterior está destinada a refrescar el por qué utilizar un RTOS respecto de utilizar los medios que hemos venido utilizando hasta el momento y porque a partir de ahora comenzaremos a ver los peligros de implementar aplicaciones con el uso de este tipo de herramientas.

La mayor pesadilla para cualquier programador es que su aplicación se bloquee o “cuelgue” y el sistema deje de trabajar como debe, este tipo de problemas es muy frecuente en sistemas operativos orientados a usuarios como Windows y en menor medida GNU/LINUX, la razón para ello está en la diversidad de aplicaciones que puede utilizar un usuario, los errores de estos programas, los propios del SO, la capacidad del usuario para hacer que el SO colapse (conozco varios usuarios expertos en esta materia), etc.

Al utilizar un RTOS para programar aplicaciones nos estamos enfrentando al problema de crear aplicaciones que tienen alta probabilidad de bloquear al sistema, ello está dado porque las cosas que debe hacer el sistema están divididas en procesos o tareas que se ejecutan de forma más o menos independiente del resto, compartiendo recursos del sistema y compitiendo por ellos. A todo lo anterior hay que sumarle que en el momento de la ejecución, el SO no tiene idea de que orden lleva la ejecución de los procesos o cuanto tiempo le tomará a un proceso terminar su ejecución, es por eso que no se pueden programar aplicaciones para SO en base a suposiciones en el orden de ejecución de las tareas o los tiempos requeridos para su completamiento.

Todo lo anterior puede asustarnos mucho porque implica que programar utilizando RTOS es potencialmente peligroso, y sí, ¡ES PELIGROSO! Pero más que peligroso es complicado y puede ser muy tedioso, ya que se complica la semántica y la depuración de las aplicaciones, pero eso no debe ser motivo de desaliento, ya que existen técnicas para reducir esas complicaciones y los problemas están debidamente identificados. Y eso es lo que vamos a comenzar a tratar en las próximas entregas.

Existen muchos problemas con los que los diseñadores deben lidiar al programar utilizando un SO, pero en nuestro caso, por las características de nuestros dispositivos, estamos salvados de un buen número de ellas. Sin embargo Némesis ha querido de todas formas poner un límite a nuestra dicha, y nos ha obsequiado dos clases de problemas que pueden hacernos perder la razón si decidimos utilizar un RTOS:


En las próximas entregas iremos viendo poco a poco cada una de estas clases de problemas, como detectar los problemas, ejemplos tipos de aplicaciones en que se presentan y como enfrentar estas dificultades.

El arma fundamental con que contamos está en utilizar correctamente los mecanismos de coordinación y sincronización, ya que el mal uso de ellos es una da las causas que pueden provocar una condición de competencia o un bloque mutuo, otras veces el hecho está en un diseño chapucero, mal pensado, errores semánticos en el código o simplemente que no haya solución al problema (aunque esto último es muy poco frecuente o muy difícil de detectar).

Ahora, como veremos próximamente, aprender a programar con un RTOS es mucho más complicado de lo que hemos visto hasta el momento, pero yo no quise meterles miedo y poner los problemas por delante de las ventajas de los RTOS, sino mostrarles un poco de lo mucho que se puede hacer para luego meternos con los problemas a los que debemos enfrentarnos.

Como han podido apreciar, hoy no tengo ninguna aplicación que mostrarles, pero no se desalienten porque próximamente vamos a toparnos con cada programita que ya ustedes tendrán de sobra para dolores de cabeza, pero al final cada uno de ustedes estará en condiciones de enfrentarse a la solución de aplicaciones difíciles de implementar en muy poco tiempo, podrán también estudiar y profundizar en la teoría de los Sistemas Operativos sin muchas dificultades y si explotan bien lo aprendido podrán llegar a ser profesionales muy competitivos y capaces.

Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 31 de Marzo de 2007, 01:23:11
No acabo de entender cuál es el problema. Si el RTOS pone una bandera cuando utiliza un recurso del micro y antes de utilizarlo mira si la bandera la ha puesto otro proceso no debería haber problemas.
Supongo que cuando la cosa se va complicando el problema también lo hace, pero esperaré a que nos ilustres en el próximo capítulo para quedarme con "la copla".
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 31 de Marzo de 2007, 23:14:31
Ya que el amigo Nocturno lo pide, voya a darles un adelanto:

Los SO cooperativo tienen la ventaja de mejorar un poco los problemas de los que les he estado hablando, pero aún así estos se pueden presentar.

Imaginen que tenemos dos tareas, A y B, que deben esperar por dos semáforos pra poder hacer su trabajo, es decir, por alguna razón estas tareas necesitan acceder a recursos compartidos a las que tienen derecho otras tareas, digamos que C tiene acceso al semáforo 1 y D al semáforo 2. Por razones de diseño, estos recursos compartidos no pueden accederse con un solo semáforo pero A y B necesitan acceso exclusivo a los dos recursos para poder trabajar. mientras que C y D solamente necesitan de uno de los recursos.

Ahora A toma el control del semáforo 1 y como el otro está siendo utilizado por D, se queda a esperar pacientemente entregando el procesador. Luego D termina de ejecutarse y libera el semáforo pero en ese momento B comienza a ejecutarse y toma el control del semáforo 2 por lo que debe quedarse a esperar por el semáforo 1, que está en poder de la tarea A y como este espera por el semáforo 2, no podrá continuar ejecutándose, pero tampoco B que espera por el semáforo 1. Ahora C y D tampoco pueden ejecutarse porque sus semáforos están en poder de otras tareas (A y B que están en una espera circular que nunca termina), así que se ha producido una condición de competencia y el sistema se ha colgado.

Como pueden ver es bastante enredado explicar una situación de condición de competencia y es por eso que es difícil darse cuenta cuando existe una de ellas. En el ejemplo anterior tenemos un caso de un diseño con una semántica mal diseñada, que se puede resolver fácilmente como veremos, pero si el SO fuese de tiempo compartido los problemas serían más difíciles de evitar.

Más adelante iremos viendo estos problemas con más detalle.

Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 01 de Abril de 2007, 02:11:14
Pues ya me ha quedado claro. Ciertamente no se me había ocurrido que las cosas se podrían complicar tanto, pero me alegro que sea un problema detectado y analizado. Ahora nos queda esperar que nos expliques cómo se arreglan esas competencias  :D

Gracias Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 03 de Abril de 2007, 16:29:48
Sip, para que no aparezcan deadlocks es conveniente manejar un orden estricto de captura de los recursos compartidos.
Se puede elegir tratar de capturar todo al comienzo o ir capturando y liberando en el mismo orden en las diferentes tareas que solicitan dichos recursos.
Lo que me gusta de los sistemas operativos cooperativos es que nos libera de problemas "no pensados en el momento" acerca de recursos que compartimos y no pueden ser compartidos en cioertos casos.
Por EJ: Usamos una funcion que no es reentrante y que utiliza para sus tareas una unica memoria, en un RTOS cooperativo no existe problema ya que no es interrumpida hasta que la tarea que la solicito no relegue el micro (con lo que se le da la oportunidad de ejecutarse hasta su conclusion).
En un RTOS preemptivo depende del "quantum" de tiempo predeterminado, con lo que es posible que se pause la ejecucion de dicha tarea y que en otra tarea que gane el micro se la vuelva a ejecutar.
En un RTOS cooperativo es posible evitar la "reentrancia" de una funcion.

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: gauchosuizo en 10 de Abril de 2007, 10:13:19
hola amigos

muy interesante el tema, sigan asi que yo estoy prendido como garrapata al perro :).
Título: Re: Sistemas operativos en PIC
Publicado por: aitopes en 10 de Abril de 2007, 15:02:43
Hola amigos!

Reinier, hoy he actualizado el documento con el curso "pasado en limpio". Lo pueden descargar o consultar desde aqui:

http://www.ucontrol.com.ar/Articulos/sistemas_operativos_microcontroladores/sistema_operativo_microcontroladores_pic_rtos.htm

Saludos!
Título: Las condiciones de competencia
Publicado por: reiniertl en 12 de Abril de 2007, 12:33:41
Las condiciones de competencia

Como introduje en los posts anteriores, las condiciones de competencia son uno de los problemas potenciales que se presentan en la programación con Sistemas Operativos, pero: ¿Qué es una condición de competencia?

Básicamente es una bronca entre procesos que termina con el cuelgue de nuestro sistema, pero esa no es una definición apropiada para este problema, una mas acertada sería esta: una condición de competencia es un fenómeno que se produce cuando uno o varios procesos compiten por uno o varios recursos produciendo el bloqueo en la ejecución de esos procesos, lo que a la postre termina con el cuelgue del sistema.

Entonces una condición de competencia es una de las pesadillas que un programador de aplicaciones que utiliza algún Sistema Operativo debe evitar si desea dormir tranquilamente. En mi post anterior puse un ejemplo en el cual se produce una condición de competencia, si se analiza con más detenimiento podemos darnos cuenta que es muy difícil definir bajo que condiciones se producirá una condición de competencia; sin embargo, como este es un tema investigado desde los años 60, un grupo de gente ya se ha ocupado de identificar bajo que condiciones un programa será robusto ante condiciones de competencia.

Para evitar una condición de competencia debemos establecer un conjunto de reglas que nos aseguren que no se producirá, adicionalmente, el Sistema Operativo debe ofrecer al programador un conjunto de herramientas de programación que le permitan poner en práctica estas reglas.

De hecho, a lo largo del curso en los ejemplos que he puesto, hemos estado evitando las condiciones de competencia, sólo que no se los dije para no complicar las cosas más de lo que ya eran en aquel entonces, pero es el momento de tocar este tema y aquí vamos.

La regla de oro para evitar las condiciones de competencia es garantizar el acceso seguro a recursos compartidos, es decir, debemos hacer coordinación y sincronización de procesos.

Para lograr implementar esta regla es que se inventaron las secciones críticas, pero el utilizar las herramientas de implementación de secciones críticas no asegura evitar una condición de competencia, ese es el caso del ejemplo de mi mensaje anterior.

Bien, si aún utilizando secciones críticas no se asegura evitar que se produzca una condición de competencia, ¿que podemos hacer para resolver el problema? Lo que podemos hacer es poner restricciones en la semántica de nuestro código que aseguren que el código es seguro, valga la redundancia.

El párrafo anterior nos pone otra vez en aprietos porque debemos preguntarnos ¿entonces cuales son esas restricciones semánticas? La respuesta a esa pregunta está dada en las siguientes cuatro reglas que debemos cumplir:


Como veremos en el futuro, hacer que nuestros programas cumplan con estas restricciones puede ser realmente doloroso, (al menos para nuestra cabeza), pero también veremos que ya algunos se rompieron la cabeza por nosotros y nos ofrecen soluciones tipo para la mayoría de los problemas a los que debemos enfrentarnos, estas soluciones se presentan con ejemplos bastante didácticos que perecen tonterías pero que podemos trasladar a problemas reales que son muy semejantes en su dinámica.

Ahora analicemos detalladamente cada una de las reglas semánticas que debe cumplir un programa libre de condiciones de competencia:


Dos o más procesos no pueden estar simultáneamente dentro
de sus regiones críticas


Cuando introduje las secciones críticas expliqué que su misión fundamental era evitar que más de un proceso accediera a un recurso compartido, esto implica que para ello debemos contar con algún mecanismo de protección y este mecanismo resultó ser el uso de semáforos, pero los semáforos por si solos no garantizan la ejecución segura, debemos pensar donde ponerlos y cuantos necesitamos para evitar que más de un proceso se meta en el código que manipula al recurso compartido.

En ocasiones se permite que más de un proceso acceda al recurso compartido para realizar lecturas pero cuando se hagan escrituras debemos impedir que más de un proceso esté dentro de la sección crítica, esta es una variación a la regla tal como la hemos definido, pero esta situación se da en muy contadas ocasiones así que no debemos preocuparnos mucho por esta variación.


No debe suponerse nada acerca de la velocidad o el orden de ejecución de los procesos

Este es un tema que podemos subestimar porque tradicionalmente programamos pensando que tenemos para nosotros todo el equipo de cómputo, pero cuando utilizamos Sistemas Operativos las condiciones cambian mucho porque cada proceso actúa como si todo el equipo de cómputo fuese suyo en el momento en que está ejecutándose, por lo que debemos proteger los recursos compartidos adecuadamente ante los cambios de contexto de los procesos.

Para ello existen, por supuesto, las secciones críticas; pero esta nueva regla le indica al programador que no puede soportar la semántica de su programa en suposiciones de carácter temporal o de orden de ejecución de los procesos y eso quedó claro en uno de los primeros ejemplos que puse en este cursillo.


Ningún proceso que se ejecute fuera de su región crítica
puede bloquear a otros procesos


Esta regla lo que define es que el bloqueo a otros procesos debe realizarse justo antes de entrar a la sección crítica, para evitar que otro proceso sea detenido cuando en realidad puede ejecutar código de forma segura, igualmente los procesos que hayan sido bloqueados cuando se entró en la sección crítica deben ser desbloquedaos al salir de esta.

Además al poner en práctica esta regla reducimos al máximo el tamaño del código dentro de la sección crítica y con ello maximizamos el uso de la CPU y minimizamos los tiempos de bloqueo, así que aunque parece simple de poner en práctica, veremos que no es tan simple lograr estos objetivos.

Ningún proceso deberá tener que esperar indefinidamente
para entrar a su región crítica


Ahora se trata de evitar que un proceso muera de inanición, es decir, que estando listo para ejecutarse y requiriendo que se ejecute, otro proceso mucho más rápido o prioritario bloquee a uno más lento, menos prioritario o ambas cosas a la vez, matándolo de hambre. Este problema puede ser muy solapado y por ello muy peligroso.

Normalmente los sistemas de planificación de procesos de los Sistemas Operativos implementan mecanismos que tratan de evitar el fenómeno de inanición, pero estos mecanismos no son infalibles y los programadores debemos estar pendientes de lo que hacemos para evitarlo.

Hasta aquí el post de hoy porque ya tengo dolor de cabeza y creo que es suficiente materia para provocarle el mismo problema a alguno de ustedes. En la próxima entrega comenzamos a ver problemas y programas para evitar las condiciones de competencia así que preparen los compiladores y el coco, tengan agua o hielo cerca para refrescarlo y no se asusten que esto es difícil pero no imposible.

Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: PICNGRADO en 15 de Abril de 2007, 08:41:10
hOLA reiniertl:

   Acabo de encontrar toda esta información tuya sobre RTOS y me parece un trabajo increible. Aún tengo que leer todo lo que has escrito pero he encontrado cosas que se pueden matizar, por ejemplo cuando hablas de RTOS mail para pasar mensajes de una tarea a otra creo que se ha de tener en cuenta que si las variables que pasan son globales no hace falta el uso de las funciones de correo, solo en el caso de que las variables sean particulares es necesario el uso de las funciones correo (pruebalo con el ejemplo que has puesto y lo comprobarás). Una dificultad que encuentro con estas funciones es el uso de float, cuando se pasan int8 o int16 no hay problemas pero con float suele dar problemas ?¿¿¿.
  En fin, espero que siguas por este camino, intentaré apoyarte cuanto pueda.

saludos

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 16 de Abril de 2007, 09:57:58
Es cierto que al utilizar variables globales no necesitas el servicio de mensajes, pero la ventaja fundamental de utilizar mensajes es que puedes implementar esperas eficientes, evitando las esperas ocupadas.

Una variable global no te permitirá saber cuando esta ha cambiado de valor a no ser que utilices una bandera, claro este método de tener una variable global y otra variable global de bandera es una solución eficaz, pero no eficiente si utilizas un RTOS.

Por ejemplo el paso de mensajes te permite hacer un RTOS_Wait(RTOS_Message_Poll()); que es una espera eficiente, y eso sólo con una línea. Es decir, si no hay mensajes le dices al RTOS, me voy a dormir, despiértame cuando llegue un mensaje, ahora piensa en implementar esto con variables globales, estoy seguro de que se puede, pero me parece que no va a quedar muy elegante. Este es sólo un criterio, es derecho de todo programador y diseñador hacer lo crea más idoneo.

Por otro lado, este RTOS no permite pasar variables de cualquier clase como mensajes, solamente bytes, es decir un int8 o un char, si tienes un float tendrás que pasarlo por partes descomponiéndolo en sus respectivos bytes y donde lo recibas puedes recomponerlo, también puedes poner el dato en una variable global y entonces pasar como mensaje algún tipo de comando para indicar que el dato cambió, si el resultado es válido, etc. Eso siempre queda como tarea del programador, yo solo doy algunas pistas el resto tienen que pensarlo ustedes.

Por supuesto estoy abierto a todo tipo de discusión y aclaración de dudas o preguntas, si me he equivocado en algo también estoy en la mejor disposición de corregir mis errores, espero haberte sido de ayuda y muchas gracias por los elogios.

Un saludo Reinier

PD: de hecho para la cantidad de lecturas que tiene este hilo me parece que genera muy poca controversia, no sé a lo mejor es que mis amigos no se atreven a preguntar o simplemente leen este hilo para adquirir cultura general. En realidad me gustaría que fuese un poco más movido, al menos de parte de los lectores.

Título: Re: Sistemas operativos en PIC
Publicado por: Nocturno en 16 de Abril de 2007, 11:10:19
Supongo que siempre se podra enviar un mensaje con un puntero al float...
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 16 de Abril de 2007, 11:18:40
Siempre que el puntero sea de 8 bits, es posible, si el puntero es de 16 bits (cosa frecuente) entonces tienes que madar dos bytes independientes y reconstruir el dato, recuerda que un puntero no es más que una variable que guarda una dirección y rara vez son de 8 bits, ya con la dirección puedes direccionar la variable.

Pero es una buena idea, todo depende de la aplicación y lo que desees hacer.

Un saludo Nocturno, siempre andas por este hilo, gracias por el interés.

Un saludo a todos Uds. Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: PICNGRADO en 16 de Abril de 2007, 16:48:55
¡Ojo! SI se pueden pasan int16 sin problemas, por ejemplo el valor de una adquisición AD. Lo que no permite (por lo que he utilizado) es el uso directo de float (el manual de CCS no aporta mucha más información sobre esta función de mail).

  Efectivamente es más elegante el uso de la función de mail pero es conveniente utilizarla sólo en el caso de que se necesite esperar la variable o un cambio en ella; pero en caso de tener que leer la varible "por narices" es más "económico" leerla directamente ¡se ahorra código y en las tareas la reducción de código es fundamental!.

saludos




Título: Re: Sistemas operativos en PIC
Publicado por: jorgevert en 18 de Abril de 2007, 20:31:01
estuve revisando este hilo sobre el tema de sistemas operativos en los pic con el ccs y tengo un problema con la simulacion de las tareas. La teoria dice, que a cada tarea se le da un tiempo maximo de ejecucion y que si esta tarea no termina de ser ejecutada. El cpu sale del la tarea que esta ejecutando y sigue con las siguiente tarea que tenga asignada.
tengo un ejemplo donde eso no ocurre. 

#include <18F452.h>
#include <MATH.H>
#fuses XT,NOWDT,PROTECT,NOLVP,PUT,NOBROWNOUT
#use delay(clock=4000000)
#use fixed_io(C_outputs=PIN_C0, PIN_C1,PIN_C2, PIN_C3,PIN_C4, PIN_C5,PIN_C6)
#use rs232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
#use RTOS(timer=0, minor_cycle=10ms) //temporizador Timer0, tiempo mínimo de ejecución de cada tarea 10ms

#task(rate=100ms,max=10ms)   //Ejecutar cada 1 segundo y consumir como máximo 10ms
void Tarea1();

#task(rate=200ms,max=10ms)    //Ejecutar cada 2 segundos y consumir como máximo 10ms
void Tarea2();

#task(rate=300ms,max=10ms) //Ejecutar cada 3 segundo y consumir como máximo 10ms
void Tarea3();


//Implementación de las tareas
void Tarea1()
{
   output_b(0x01);
   delay_ms(200);
   printf("t1\r");
}


void Tarea2()
{
   printf("t2\r");
}

void Tarea3()
{
   printf("t3\r");
}

void main()
{

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

aqui tengo 3 tareas cada una con un tiempo maximo de ejecucion de 10ms sin embargo en la tarea1 inserte un delay de 200ms y cuando el cpu atiene esta tarea ejecuta los 200ms y el printf sin respetar el tiempo maximo de 10ms. Alguien me puede explicar a que se debe eso.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 19 de Abril de 2007, 08:18:59
Se debe sencillamente a que este RTOS es cooperativo o non preentive, eso significa que si la tarea no cede el procesador antes de que se cumpla el tiempo de slice, en tu caso 10ms, esta continuará ejecutándose y el RTOS no podrá quitarle el procesador a la tarea.

Las razones por las cuales este RTOS es así pueden ser muchas, pero la más importante a mi juicio, es que en la mayoría de los PICs la pila no puede ser leía, así que para hacer una cabio de contexto, no se puede saber por donde se está ejecutando tu programa, tampoco se puede meter ni sacar un contador de programas en la pila (no hay PUSH ni POP) y por lo tanto el RTOS no puede simplemente hacer un cambio de contexto seguro, otras razones pueden ser el tamaño  del RTOS, su simplicidad, etc.

Ahora, con el RTOS de CCS, no puedes esperar a que él tome el control del procesador como puede ocurrir con otros RTOS, como el FreeRTOS (este tiene puertos para los PICs más avanzados donde la pila puede ser leída para obtener los contadores de programa y oder hacer cambio de contexto), el cual es configurable y puede actuar como cooperativo o de tiempo compartido, aquí debes simplemente devolver el procesador cuando no lo necesites, o creas que ya has consumido demasiado tiempo, es tu responsabilidad como programador pensar en esos asuntos.

Sistemas operativos como este hay un montón, así que no se preocupen por el tema de los SO cooperativos, por ejemplo Windows fue cooperativo hasta una de las primeras versiones de win95 y nunca ningún usuario se preocupó de eso.

Un saludo Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: jorgevert en 19 de Abril de 2007, 20:04:17
no me percate que el ccs aplica un sistema del tipo cooperativo gracias por la ayuda.

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 11 de Mayo de 2007, 14:00:34

Luego de una condición de competencia producida entre la tarea Trabajo y la tarea Foro, en la cual la tarea trabajo casi mata de inanición a la tarea Foro, he venido con esta nueva entrega sobre el hilo sobre RTOS.

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 11 de Mayo de 2007, 14:05:53
Introducción a los procesos

Hasta el momento hemos visto ejemplos de programas utilizando RTOS y les he hablado de los problemas asociados a la programación con RTOS, pero hay un concepto que debemos aclarar antes de continuar, o de otro modo ustedes pueden llegar a confundirse y escribir programas que no funcionan correctamente.

Todo el tiempo han visto que he utilizado el término tarea o proceso para denotar un fragmento de código que hace “algo”, pero no han visto una definición formal sobre esos términos, así como tampoco una explicación de que es una tarea o proceso.

Las razones de la omisión, son más o menos las mismas que para el caso de los problemas asociados a la programación con RTOS. Normalmente estos temas son bastante tediosos de estudiar, programar utilizando SO no es una tarea fácil al principio, aunque una vez que se domina constituye una poderosa herramienta de trabajo que mejora la productividad y el desempeño de cualquier sistema.

Entonces con el objetivo de motivar en ustedes el interés por la programación con RTOS, decidí no proponerles una línea formal de aprendizaje como suele ocurrir en una escuela o libro sobre el tema, sino ir poniendo ejemplos de cómo utilizar un RTOS y luego introducir la parte pesada del asunto.

Hoy vamos a ver, con bastante detalle qué es un proceso o tarea, porque cuando comencemos a ver los ejemplos de coordinación y sincronización de procesos, necesitaremos tener bien claro que es un proceso, para poder comprender esos problemas-ejemplo de los que tanto les he hablado.

¿Cómo se consigue la multiprogramación?
La multitarea o multiprogramación es un proceso que intenta crear la ilusión de que la computadora está haciendo varias cosas al mismo tiempo. Pensemos en una PC, normalmente usted puede escribir un documento mientras escucha música, el programa de descargas baja algún archivo de INTERNET y el antivirus se encuentra activo.

Para lograr hacer cada una de las cosas anteriores, tenemos un conjunto de programas, uno por cada tarea, y cada programa “parece” que se ejecuta como si tuviese la computadora para él solo. En realidad cada programa se ejecuta durante un período corto de tiempo y luego el procesador es cedido a otro programa para que se ejecute durante un poco de tiempo, este mecanismo se conoce como multiprogramación (definición estilo UNIX) o multitarea (definición estilo Microsoft).

Si para una computadora tuviésemos una lista de los programas que está ejecutando y muestreáramos que está haciendo el procesador en un instante de tiempo cualquiera; comprobaríamos que en ese momento está ejecutando una instrucción de alguno de sus programas, pero nunca dos programas a la vez. Más aún, si ese procesador tuviese un pipeline suficientemente grande como para contener varias instrucciones en la cola de ejecución, notaríamos que todas las instrucciones son de un solo programa.

Ahora tomemos un período de tiempo, digamos un segundo, en ese tiempo el procesador debe cambiar de un programa a otro para que se ejecute un pedacito de cada uno y crear la ilusión de que el conjunto se ejecuta de forma concurrente, como si cada programa tuviese un procesador para él solo. Es posible que en ese tiempo el procesador haya cambiado muchas veces de programa, pero si el usuario o sistema conectado a él no nota que sus intereses se han afectado, el objetivo fundamental de la multiprogramación se ha cumplido: crear la ilusión de que el sistema de cómputo tiene varios procesadores, uno por cada programa en ejecución.

Hay sistemas con más de un procesador trabajando de conjunto para ejecutar instrucciones de varios programas, a ese método de ejecución de código en un sistema computacional se le conoce como paralelismo, mientras que a los sistemas con un solo procesador se les conoce como de ejecución seudo paralela.

Como los seres humanos somos muy malos siguiendo la pista a un sistema que cambia constantemente de un lugar a otro, y a veces eso nos trae problemas de cabeza, es que se ha inventado un modelo que permite programar código que pueda ser ejecutado de forma paralela o seudo paralela: el modelo de proceso.

El modelo de procesos:
Normalmente se considera que un proceso es un programa en ejecución. Sin embargo eso sería limitar el concepto de proceso al programa que se está ejecutando en el instante en que se mira a la CPU.

Más bien un proceso es un programa al que le ha sido asociado un conjunto de datos que crea una CPU virtual. Eventualmente el proceso irá a parar a la CPU, se ejecutará un poco de código y volverá a ser suspendido hasta que le toque nuevamente la CPU, pero cuando el proceso no se está ejecutando en el procesador, su conjunto de datos asociado mantiene el estado del proceso como si estuviese ejecutándose.

Con este modelo podemos seguir la pista a nuestros programas sin preocuparnos mucho por la forma en que la CPU conmuta o cambia de contexto de un proceso a otro, es como si tuviésemos a cada programa ejecutándose en su propia computadora.

Comprender este concepto es muy importante, porque a partir de ahora si un programa se convierte en proceso, además del código del programa (escrito por el programador), el SO le asignará un registro de control y estado, de modo que el proceso tenga su CPU virtual. Y usted como programador que utiliza las funcionalidades del SO para escribir su código, deberá conocer este detalle si quiere que sus código sea productivo y seguro.

Estados de proceso
Ya vimos que a cada programa que se promueve a proceso le es asignado un registro de control y estado. Este registro puede tener varios campos y cada campo puede tomar varios valores, muchas veces al programador no le interesan cuales son los campos de este registro y cuales sus valores porque son de uso interno del SO, pero hay un conjunto reducido de ellos que sí es necesario conocer.

Dentro de los campos del registro de proceso uno de los más importantes para el programador es el de estado del proceso. Este campo sirve para conocer en que situación está el proceso y permite determinar hacia que nuevo estado puede dirigirse éste.

Los estados que puede tomar un proceso son básicamente los siguientes:

En ejecución: corresponde al proceso que en el momento presente está ejecutando el procesador real el sistema.

Listo: el proceso está listo para ser ejecutado. Este estado permite que el SO pueda planificar al proceso para ser ejecutado en algún momento posterior.

Suspendido o bloqueado: los procesos van a parar a este estado porque deben esperar a que alguna condición lógica se cumpla para poder continuar ejecutándose, las condiciones pueden ser muchas: esperar por una E/S, a que transcurra algún tiempo, entre otras.

Además de los estados existen un conjunto de transiciones entre los diferentes estados:

Ejecución -> Suspendido o bloqueado: ocurre cuando un proceso debe esperar por una condición lógica, en este caso como el proceso no puede continuar ejecutándose, lo más lógico es que el procesador se dedique a ejecutar otros procesos que estén listos para ejecutarse.

Ejecución -> Listo: ocurre en los sistemas de tiempo compartido (preentive), en el cual un proceso que estaba ejecutándose es interrumpido porque se terminó su tiempo (slice) de ejecución y debe esperar a que lo vuelvan a planificar para ejecutarse. En este caso el proceso no pasa al estado de bloqueado porque no existe nada que le impida continuar, excepto que el procesador real del sistema debe ejecutar otro proceso para que se cumpla el objetivo de la multiprogramación.

Listo -> Ejecución: a un proceso que estaba listo para ejecutarse le es cedido el procesador

Bloqueado -> Listo: la condición lógica que mantenía al proceso en este estado se ha cumplido y el proceso ya puede ser planificado para ejecutarse.

Ahora he introducido un nuevo elemento en el asunto: la planificación de procesos. Este es un tema importante, aunque a nosotros no nos interesa mucho, porque no diseñamos ningún SO sino que simplemente lo utilizamos.

El planificador de procesos es un componente del SO que básicamente se encarga de revisar la lista de procesos que están listos para ejecutarse y los pone en una cola de la que otro componente del SO, llamado despachador o dispatcher, los va tomando y poniéndolos en ejecución.

En un SO puede haber otros componentes encargados de la E/S, la comunicación entre procesos, etc. pero con lo que hemos visto es suficiente para seguir avanzando en nuestro curso.

Los procesos con el RTOS de CCS
Para el RTOS de CCS, los procesos se nombran tareas y es por eso que durante el curso he utilizado indistintamente el término tarea o proceso. Tal y como hemos visto hasta hoy, cuando el RTOS crea una tarea le asigna un registro mediante el cual el RTOS puede controlar la ejecución de la tarea y conocer su estado. Para el programador esta información no está disponible porque realmente no debe acceder directamente a ella, pero como veremos un poco más adelante si se trabaja con esto registros, por supuesto, a través de las funciones que ofrece el propio RTOS.

Para comprender esto mejor veamos cada una de las funciones y directivas del RTOS y el impacto que cada una tiene sobre las tareas:

#TASK:
Con esta directiva simplemente le decimos al compilador que la función que viene a continuación será una tarea. En el momento de la compilación le será creado el registro de control y estado y se marcará como lista, si la tarea tiene cola se reserva memoria para la cola.

Una tarea no será tenida en cuenta como si fuese una función, por lo tanto no podrá llamar a una “función tipo tarea” como lo hace con cualquier otra función, las tareas son como programas completamente independientes que tienen asociado un registro de control y estado como si tuviese su propio procesador.

Tampoco debe implementarse una tarea como si fuese una función tipo main(), ya que la tarea ejecutará el código desde que comienza hasta que termina, se marca con el estado listo y luego el procesador es cedido al RTOS para que el despachador ponga otra tarea en ejecución. Si la tarea se mantiene en el estado listo, entonces cuando le toque nuevamente su turno en la cola de despachos volverá a ser ejecutada desde el principio, como si hubiese un lazo infinito. Hágase la idea que en vez de un main() con un lazo infinito, tenemos tantos main() como tareas hayamos definido, que se ejecutan de acuerdo a un plan de ejecución.

RTOS_AWAIT( ) y RTOS_WAIT( ):
Estas dos funciones permiten pasar a una tarea del estado en ejecución al estado bloqueado si las condiciones lógicas que permiten continuar ejecutando código no se cumplen y permanecerán en el estado bloqueado hasta que el RTOS detecte que puede continuar ejecutándose las pase al estado listo. Nunca el programador puede pasar una tarea del estado bloqueado a listo, esto es asunto del RTOS.

RTOS_DISABLE( )
Permite al programador, que desde otra tarea, se cambie el estado de una tarea de listo para deshabilitada (un estado nuevo de este RTOS), es necesario utilizar la función RTOS_ENABLE( ) para volver a conmutar del estado deshabilitada al estado anterior en que se encontraba la tarea. Una tarea no puede auto deshabilitarse, este cambio debe hacerse desde una tarea diferente.

RTOS_YIELD( ):
Cede el procesador explícitamente y pasa del estado en ejecución al estado listo. La otra forma en que con este RTOS se hace esa transición es cuando se termina el código de la tarea. Cuando le vuelva a corresponder el turno de ejecución a esta tarea, el despachador la volverá poner en ejecución en la línea posterior al yield().

Uff, bueno, hasta aquí por hoy, creo que es más que suficiente. Espero que las condiciones de competencia no vuelvan a afectar a la tarea Foro y pueda escribirles pronto.
El próximo tema será: El problema del productor-consumidor, uno de los más famosos problemas tipo de la programación con SO.

Un saludo: Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: PICpegaso en 16 de Mayo de 2007, 03:52:48
Vaya... y yo que ingresaba a la pagina para manejar el ADC,
has logrado captar mi atención,
Gracias Reinier  :-)

  :-/ esta de lujo :lol:
Título: Re: Sistemas operativos en PIC
Publicado por: barral en 18 de Mayo de 2007, 08:27:14
La verdad es que este hilo es genial... yo lo sigo desde el principio. Además la parte teórica me refresca la memoria de mis clases de sistemas informáticos de tiempo real...
Título: Re: Sistemas operativos en PIC
Publicado por: carlosmaid en 28 de Octubre de 2007, 21:56:00
Mas que excelente toda la informacion!!

Ahora, veo que ya hace algunos meses no se postea mas data nueva :-( una lastima porque es de primera mano.
Título: Re: Sistemas operativos en PIC
Publicado por: papinolmedo en 05 de Marzo de 2008, 00:32:29

Muy bueno el hilo. No se que habrá pasado que el amigo reiniertl no publicó nada más. Una lastima. Me quede con ganas de aprender más y de leer el supuesto nuevo tema "El problema del productor-consumidor"

De todos modos se agradece el material que publicó, realmente muy buena información y muy buen modo de enseñar. Voy a aplicar algo de lo aprendido a algún proyecto.

Saludos cordiales.

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 05 de Marzo de 2008, 16:49:43
Lo que pasó es que me he enfrascado en un proyecto mayor con Ariel, que ya va rindiendo frutos y este proyecto, desgraciadamente ha quedado un poco atrasado en mi modesto planificador, casi que ha muerto de inanición.

Espero rescatarlo y llevarlo a uControl con más calidad y mejor presentación, luego de un buen tiempo dedicado a elaborar otros documentos, he descubierto que este a pesar que binda buena información tiene unos cuantos detalles que pueden ser mejorados.

Saludos
Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: papinolmedo en 05 de Marzo de 2008, 21:19:33

Saludos reiniertl. Pues bien, quedo a la espera de la resucitación del curso de RTOS, con lo que ya has publicado me es suficiente para poner en marcha varias aplicaciones, espero montar algo para mi próxima mesa de evaluación de proyecto de titulo, que es dentro de dos meses.

Saludos cordiales
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 06 de Marzo de 2008, 16:01:41
Yo desde que aprendí a utilizar el RTOS no dejo de hacer aplicaciones con él, a no ser que no quepa en el PIC que haya seleccionado.

De hecho no me hayo eliminando rebotes, haciendo temporizciones poco precisas, demoras y coordinando tareas sin el RTOS, porque hay trabajos que de la forma tradicional me tomarían días, mientras que con el RTOS lo resuelvo en minutos


Saludos
Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: papinolmedo en 07 de Marzo de 2008, 23:51:18
Estoy terminando de leer el curso (que lo imprime para "ahorrar ojos", jejeje), luego de eso voy a tratar de implementar algunas aplicaciones para el trabajo con servomotores. A ver como va eso, ojala resulte.

Espero lograr alcanzar un nivel mas alto en el desarrollo de aplicaciones (tal como lo ha logrado el maestro reiniertl) al hacer uso del RTOS.

Saludos cordiales.
Título: Re: Sistemas operativos en PIC
Publicado por: ALEXVEDOR en 11 de Mayo de 2008, 22:24:37
Un saludo amigos del foro...
Interesante tema.. ya he hecho algunas cosas con el RTOS de CCS; transmision serial, manejo de LCD, RTC, leds etc, usando las librerias de CCS para esto y no he tenido problemas: Sin embargo estoy requiriendo realizar una rutina de barrido de varios display de siete segmentos y estoy asignandole un rate=1ms por lo que segun entiendo en minor_cycle debe de ser tambien de 1ms y el max=1ms. tambien estoy haciendo otras cosas con rate mayores a 50ms, 200ms y 500ms entre estas mostrar datos en LCD, esta tarea tiene un rate de 250ms pero el compilador no me deja asignarle un max mayor de 1ms creo que p´q este es el minimo tiempo de rate dado por la primera tarea. Mi problema esta en ke la instruccion lcd_putc() tarda mas de 1ms y cuando corro el programa intenta arrancar y se bloquea... si subo el rate de la primera tarea pejm a 10ms el programa corre bien, pero necesito que ese rate sea de 1ms.. como podria solucionar este problema??? gracias por su ayuda.. aki coloco parte del codigo:

#use RTOS(timer=0) // no le asigno minor_cycle y dejo ke el compilador lo calcule

//********Tareas Rapidas********//

#task(rate=1ms)
void desplaza_display ();

#task(rate=50ms)
void procesa_trama_radar();

#task(rate=100ms)
void presentacion();

//==============================//


//********Tareas Medias********//
#task(rate=150ms)
void fija_velocidad_up();


#task(rate=150ms)
void fija_velocidad_down();

#task(rate=250ms)
void alarma_intermitente ();

#task(rate=500ms)
void imprime ();
//============================//



 void imprime()
 {

 
    lcd_gotoxy(0,1);
    printf(lcd_putc,"VEL MAX: %2u Km/h",VEL_MAX);
    lcd_gotoxy(0,2);
    printf(lcd_putc,"Detec:  %3u Km/h",vel_capturada);

}

void desplaza_display()
{

for(barrido_display=0;barrido_display<6;barrido_display++)
  {
   PORTC=(dinamica[barrido_display]);

   switch(barrido_display){

         case 0:
            PORTB=(tab7segK[vel_und]);
            break;

         case 1:
            PORTB=(tab7segK[vel_und]);
            break;

         case 2:
            PORTB=(tab7segK[vel_dec]);
            break;

         case 3:
           PORTB=(tab7segK[vel_dec]);
            break;

        case 4:
            PORTB=(tab7segK[vel_cen]);
            break;

         default:
            PORTB=(tab7segK[vel_cen]);



rtos_yield();
}
Título: Re: Sistemas operativos en PIC
Publicado por: pachopic en 13 de Mayo de 2008, 12:16:23
Buenos dias

Alguien de casualidad todavia posee los ejemplos de proteus, del tema?

Gracias
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 14 de Mayo de 2008, 08:48:13
ALEXVEDOR tu problema está aquí:

#use RTOS(timer=0) // no le asigno minor_cycle y dejo que el compilador lo calcule

dejas que el sistema te calcule el minor cicle el solito, debes asignarlo porque es este el ciclo menor para cualquier tarea, por lo que todos los rates de las tareas deben ser múltiplo de este mínimo ciclo.

pachopic debo tener esos ejemplos en algún lugar de mi HDD, pero ahora mismo estoy en proceso de reordenamiento de todos mis archivos, así que en cuanto los encuentre veré como subirlos de nuevo, esta vez a uControl.

Saludos
Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: Cryn en 05 de Septiembre de 2008, 13:34:40
Que buenisimo curso Reiner, aquel tiempo leía partes y me parecía muy interesante el tema, sin duda que quería probarlo y aprender pero todavía no comprendía algunas cosas, ahora me siento con más ganas de poder aprender sobre este RTOS, felicidades (atrasado :oops:) por el trabajo, te ha quedado simplemente mágnifico, muchas gracias.

Y vas a continuar con el curso proximamente?? todavía porque me quede con las ganas :mrgreen:

Citar
El próximo tema será: El problema del productor-consumidor, uno de los más famosos problemas tipo de la programación con SO.

un saludo Reiner.

Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 05 de Septiembre de 2008, 13:43:02
De momento no he hecho nada nuevo pero es algo que tengo entre mis pendientes
Título: Re: Sistemas operativos en PIC
Publicado por: Cryn en 05 de Septiembre de 2008, 14:42:55
vale pues esperaré con ansias una nueva entrega, tan bien explicada como hasta ahora lo has hecho Reiner, gracias nuevamente
Título: Re: Sistemas operativos en PIC
Publicado por: firepic en 05 de Septiembre de 2008, 15:41:12
Qué tal!
Gracias Cryn, por revivir este hilo... de no ser así no me hubiese enterado... qué buen hilo!
Y por supuestos gracias a tí, Reinier... eres todo un experto con esto de los micros! Guao, estoy sorprendido con todo esto!
Bien vale la pena ponerse a estudiar entonces el RTOS... cuando tenga chance seguiré viendo lo que ha publicado ariel en su web, la recopilación de lo que tú has publicado acá.
Nuevamente felicitaciones, y gracias por compartir tus conocimientos!  :P
Saludos!  :mrgreen:
Título: Re: Sistemas operativos en PIC
Publicado por: superprp en 06 de Septiembre de 2008, 13:13:40
Yo he trabajado con el CMX-SCHEDULER para el C30 de microchip, es para dsPIC y va genial, es gratuito pero solo puedes priorizar 4 tareas, por las casi 200 que se pueden usar en los de pago.

Estoy intentando crear un RTOS para dsPIC en C30, si os apuntais alguno mas a ayudarme a realizarlo podemos abrir un post e ir posteando ideas y código para realizarlo entre todos, es una buena forma de aprender a fondo las bases de un RTOS.
Título: Re: Sistemas operativos en PIC
Publicado por: Darukur en 08 de Septiembre de 2008, 21:49:18
Yo he trabajado con el CMX-SCHEDULER para el C30 de microchip, es para dsPIC y va genial, es gratuito pero solo puedes priorizar 4 tareas, por las casi 200 que se pueden usar en los de pago.

Estoy intentando crear un RTOS para dsPIC en C30, si os apuntais alguno mas a ayudarme a realizarlo podemos abrir un post e ir posteando ideas y código para realizarlo entre todos, es una buena forma de aprender a fondo las bases de un RTOS.

Si te interesa nosotros estamos trabajando con FreeRtos, es gratuito y porteado para casi todas las arquitecturas de micros.

Tutorial paso a paso para FreeRTOS (http://www.sistemasembebidos.com.ar/forum/index.php?topic=225.0)

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: superprp en 16 de Septiembre de 2008, 11:21:55
Habeis incluido ya para los dsPIC30F?????

Este RTOS lo he visto en algunos foros, pero nunca me he puesto a verlo a fondo, puedo ayudar a realizar la versión para el 30F o incluso otro de gama inferior.

Aunque mi idea era la de realizar un RTOS los del foro todopic, algo sencillo que nos sirviera de base sobre todo para aprender lo que es un RTOS y que estrategias software utiliza
Título: Re: Sistemas operativos en PIC
Publicado por: Cryn en 16 de Septiembre de 2008, 12:15:46
la verdad que estoy muy interesado en aprender mucho más acerca del RTOS, ya vi la ayuda que presenta en el manual de CCS, y pues quede algo desepcionado, porque simplemente dan unos pequeños datos de lo que hace cada funcion del RTOS, supongo que esas son todas las funciones pues no fijuran más en el manual. Pero la verdad que estoy muy interesando en seguir aprendiendo más acerca de este RTOS para CCS, no existe algún otro manual de ello, aunque sea en ingles?? para poder continuar con el mundo del RTOS.

muchas gracias un saludo.
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 16 de Septiembre de 2008, 15:13:39
Hasta donde yo se no hay mucho más, lo que es una lástima, sobre las funciones es cierto que son pocas pero sirven bien
Título: Re: Sistemas operativos en PIC
Publicado por: gera en 17 de Septiembre de 2008, 11:39:25
Muy bueno todo este tema, ya voy a hacer algun proyectito que lo implemente. Pero tengo una duda... no hay algun RTOS o alguna funcionalidad que pueda traer procesos desde una memoria externa, en lugar de tener q declarar funciones que seran los procesos? (como lo hacen nuestras computadoras)
Saludos!
Título: Re: Sistemas operativos en PIC
Publicado por: superprp en 17 de Septiembre de 2008, 11:59:40
encontré algunos libros bastante buenos sobre RTOS en microcontroladores PIC, aquí están los enlaces:


http://www.amazon.co.uk/Embedded-C-Programming-Microchip-Pic/dp/1401837484

http://www.amazon.co.uk/Programming-16-Bit-PIC-Microcontrollers-Technology/dp/0750682922/ref=pd_sim_b_1

http://www.amazon.co.uk/Designing-Embedded-Systems-PIC-Microcontrollers/dp/0750667559/ref=pd_sim_b_3

a quien no le importe que sea en ingles son perfectos, es lo mejor que he encontrado.
Título: Re: Sistemas operativos en PIC
Publicado por: Cryn en 17 de Septiembre de 2008, 15:21:56
mmmm

nose si será lo que busco, pues no dice exactamente CCS, en caso de que sean con CC pues un pequeño detalle, que personalmente no puedo comprarlos, pues no poseo TC

creo que no hay ningún material 'libre' como este que ha dejado reiner :(

ni modo, cosas de la vida, jaja, pero de todos modos seguiré buscando. un saludo
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 17 de Septiembre de 2008, 22:51:05
Muy bueno todo este tema, ya voy a hacer algun proyectito que lo implemente. Pero tengo una duda... no hay algun RTOS o alguna funcionalidad que pueda traer procesos desde una memoria externa, en lugar de tener q declarar funciones que seran los procesos? (como lo hacen nuestras computadoras)
Saludos!

Indio no entender, que quieres traer de memoria externa?
Título: Re: Sistemas operativos en PIC
Publicado por: LABmouse en 21 de Septiembre de 2008, 11:17:08
Muy bueno todo este tema, ya voy a hacer algun proyectito que lo implemente. Pero tengo una duda... no hay algun RTOS o alguna funcionalidad que pueda traer procesos desde una memoria externa, en lugar de tener q declarar funciones que seran los procesos? (como lo hacen nuestras computadoras)
Saludos!

Pues gera, simplemente colocas la memoria externa, y haces una función en el PIC que traiga datos y envié datos a la memoria externa..  Los PICs son buenos para aplicaciones pequeñas, es imposible que lo compares con un PC. Si quieres algo mas poderoso, entonces hay que mirar los ARM u otros de 32 Bits, con capacidad de correr LINUX o Windows C.
Título: Re: Sistemas operativos en PIC
Publicado por: scientist en 01 de Diciembre de 2008, 04:29:42
muy buen hilo, no lo habia visto, y la verdad a sido una grata sorpresa para mi haberlo encontrado, un pedazo de hilo, felicidades reniertl muy didactico
Título: Re: Sistemas operativos en PIC
Publicado por: josnelihurt en 26 de Diciembre de 2008, 05:09:23
Felicitaciones por el grandioso trabajo reniertl, auque no soy nuevo en el foro, no habia tenido una participacion activa y he decidido empezar por esta, me tomado como 3 dias de a trozos leer todo el contenido, por esto de las festividades navideñas pero la verdad tenia una mala idea infundada de los OS y ahora veo el alcance que pueden llegar a tener, espero que este hilo se reactive, quedo muy agradecido y altamente interzado en el tema
Título: Re: Sistemas operativos en PIC
Publicado por: edwin657 en 26 de Octubre de 2009, 12:27:49
Bueno, parece que este hilo hace rato no se alimenta, asi que decidi publicar una parte del libro  "The Art of Designing Embedded Systems" 2ed de "Jack Ganssle", donde habla hacerca de los RTOS, Jack Ganssle es uno de los gurus de los sitemas embebidos, la traduccion esta un poco burda pero se entiende....

Estos son mis reglas de oro para la decisión si obner o no un RTOS

Cualquier sistema grande, donde "grandes" se define como la pornografía (es decir, "Sé esto cuando lo veo"), se pone bien un RTOS o, en su caso, un sistema operativo convencional como Linux. Grandes sistemas siempre se hacen más grandes, grandes sistemas son inherentemente complejos, y los grandes sistemas manejan muchas diferentes actividades, por lo que se benefician de tener un entorno multitarea.

La mayoría de los sistemas pequeños, donde "pequeños" significa que estamos contando centavos, no le pongas un sistema operativo de ningún tipo.

Cuando hay vidas en juego si el sistema no es cargado ligeramente hacemos un análisis muy cuidadoso para ver si el multitarea podría crear problemas en el determinismo (ver más abajo). Si el determinismo no se puede garantizar, y si no hay ningún mecanismo de seguridad redundante, evitar un RTOS. Tenga en cuenta, sin embargo, que el traslado de tareas a los llamados de interrupción no resuelve el problema de determinismo. Un mecanismo diferente, como secuencias de disparo por tiempo, es probablemente más adecuado.

Si un organismo regulador debe certificar el producto, entonces, utilizar un RTOS sólo si una versión certificable está disponible. Por ejemplo, varios proveedores venden sistemas operativos comerciales certificable a DO-178B Nivel A, pero estos productos no están disponibles para todos los procesadores.

Si hay múltiples actividades independientes en marcha, tales como la necesidad de actualizar la pantalla al mismo tiempo que la obtención de datos y escaneo de un teclado, prefiero usar un RTOS.

Si un simple loop puede manejar todas las necesidades de la aplicación, y que se prevé la no necesidad futura de agregar mas funcionalidad más allá de lo que el bucle se puede manejar, no tome la RTOS

Título: Re: Sistemas operativos en PIC
Publicado por: IIIC en 04 de Enero de 2010, 18:02:20
Si bien al fin de cuentas se dio un curso de RTOS, el desarrollo de un sistema operativo sobre pic no se abordo, ahora mismo estoy interesado por un firmware que permita la ejecucion de una maquina virtual de java que a su vez permita la ejecucion de bytecode que controla las acciones y procesos del pic.

Ustedes han oido hablar acerca de estos proyectos, del unico que tengo referencia es de LEJOS NXT... que trabaja precisamente de esa forma, y esta orientada para los carisimos juguetes de LEGO MINDSTORMS.

Cabe mencionar que este proyecto esta enfocada a los siguientes micros

32-bit AT91SAM7S256 (ARM7TDMI) main microprocessor @ 48 MHz (256 KB flash memory, 64 KB RAM)
8-bit ATmega48 microcontroller @ 4 MHz (4 KB flash memory, 512 Bytes RAM)

Aunque tambien entiendo que la programacion de un microprocesador y un microcontrolador difieren.
 
Alguien podria dar un poco de luz a mi ignorancia?

Saludos.


Título: Re: Sistemas operativos en PIC
Publicado por: jeremylf en 03 de Noviembre de 2011, 01:11:16
Muy buen curso reiniertl, gracias.

Creo que en otro lado has mencionado que te estas pasando al FreeRTOS cierto? Habra un curso como este para este RTOS?  :mrgreen:  La pega, como bien se sabe, es que es en c18 (en el caso de los PIC18). Aunque ya estoy metiendome a este lenguaje.

Gracias otra vez!!
Título: Re: Sistemas operativos en PIC
Publicado por: reiniertl en 04 de Noviembre de 2011, 23:12:28
Estuve dando un curso en micropic, el cual por motivos de tiempo no he podido completar. Sin embargo, espero que en el primer trimestre del próximo año pueda retomarlo muy en serio y con muchas mejoras. Pretendo para esa fecha tener lo siguiente:

Todas las clases escritas y listas (se asegura el curso) gracias a que utilizaré los materiales que he escrito para dar este curso en la universidad donde doy clases como profesor. En enero comienzo a dar nuevamente el curso de sistemas operativos, así que tendremos una versión revisada y corregida de esos materiales.

Los resultados de mi tesis de maestría, para el desarrollo de sistemas de tiempo real on FreeRTOS. Esta será una parte avanzada del curso y es probable que no todos estén motivados a seguirla, pero aquellos que lo hagan tendrán una herramienta muy poderosa en sus manos para diseñar sistemas de tiempo real, verificables. Esto quiere decir que si aplicas mi técnica y el compilador no hace cosas raras, tu aplicación no debe fallar por problemas de implementaciones de tu software o por incumplimiento de plazos en sistemas de tiempo real.

El curso se mantendrá totalmente gratuito y abierto a toda la comunidad dentro y fuera de TODOPIC

Saludos
Reinier
Título: Re: Sistemas operativos en PIC
Publicado por: rivale en 05 de Noviembre de 2011, 00:30:11
Hola reiniert, no habia visto este post, gracias a tu ultimo mensaje vi que existia.

Muchas gracias por compartir informacion, y seguire de cerca lo que pongas relacionado a tu curso.

Saludos
Título: Re: Sistemas operativos en PIC
Publicado por: jeremylf en 28 de Marzo de 2013, 18:14:50
Hola mundo con RTOS
Después de teorizar un poco sobre los Sistemas Operativos, vamos a introducirnos en la programación de aplicaciones empleando un RTOS.

En nuestro caso, para comenzar, utilizaremos el RTOS que viene con el compilador de CCS. Las razones de mi elecció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

Introducción al RTOS de CCS
La versión del compilador que tengo instalada en estos momentos es la 3.249, así que si en versiones posteriores han aparecido nuevas características, les ruego que lo informen para tomar las debidas providencias 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 multiprocesamiento cooperativo (non preemptive), por lo que es responsabilidad del programador asegurarse de que el control del procesador retorna al planificador de tareas en algún momento. Así que cuando programemos nuestra aplicación, tenemos que asegurarnos de que no llamamos a una función que se queda esperando por algún evento largo como es el caso de gets(), o dentro de un lazo infinito o demasiado extenso.

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

Directivas del preprocesador
Existen 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 por el 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 de ejecución de cada tarea deben ser múltiplos de esta cantidad. Si por ejemplo decimos que el tiempo mínimo de ejecución para todas las tareas es de 1ms, debemos conocer que cada tarea se ejecutará, en menos tiempo que este. Lo realmente importante de este dato es que ayuda a establecer la frecuencia con que se ejecutan las tareas, luego veremos un ejemplo de esto. Este parámetro, si no se especifica, es calculado por el compliador 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 consume cada tarea en ejecutarse, sin embargo como veremos más adelante, la estadística realmente importante 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 tiempo y están activadas las estadísticas, entonces esta tarea es marcada con el valor overrun. Este parámetro es útil para informar al programador que una tarea se ha pasado de su tiempo de ejecución, y si el RTOS fuera de tiempo compartido seguramente especificaría el tiempo en que el planificador le retira el procesador para dárselo a otra tarea.
queue: especifica el tamaño de la cola de mensajes de la tarea. Si la tarea no recibe mensajes, entonces debe dejarse 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, la utilidad de esto es mejor verla con un ejemplo.

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

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

  • Temporizador para el RTOS: Timer0
  • Tiempo mínimo en que debe ejecutarse una tarea: 10ms
  • Frecuencia de ejecución de la Tarea 1: 1seg, tiempo para ejecutar: 10ms
  • Frecuencia de ejecución de la Tarea 2: 2seg, tiempo para ejecutar: 5ms
  • Frecuencia 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: 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) //temporizador Timer0, tiempo mínimo de ejecución de cada tarea 10ms
  4. int8 test;
  5.  
  6. //Definición de las prototipos de función de las tareas
  7. #task (rate=1s, max=10ms)  //Ejecutar cada 1 segundo y consumir como máximo 10ms
  8. void Tarea1();
  9.  
  10. #task (rate=2s, max=5ms)  //Ejecutar cada 2 segundos y consumir como máximo 5ms
  11. void Tarea2();
  12.  
  13. #task (rate=3s, max=250us)  //Ejecutar cada 3 segundo y consumir como máximo 250us
  14. void Tarea3();
  15.  
  16. void main()
  17. {
  18.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  19.    rtos_run();  //A partir de aquí comenzará la ejecución de las tareas
  20.  
  21. }
  22.  
  23. //Implementación de las tareas
  24. void Tarea1()
  25. {
  26.   printf("Ejecutada tarea 1\r");
  27. }
  28.  
  29.  
  30. void Tarea2()
  31. {
  32.   printf("Ejecutada tarea 2\r");
  33. }
  34.  
  35. void Tarea3()
  36. {
  37.  printf("Ejecutada tarea 3\r");
  38. }


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 pueden comprobar que primero se ejecuta la Tarea 1, pero después comprobarán que las tareas no se ejecutan en orden 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 al planificador con que frecuencia ejecutar cada tarea. Este programa puede ser fácilmente modificado para cualquier aplicación específica, un ejemplo que se me ocurre es la lectura de teclados y eliminación de rebotes.
Como tarea les dejo que elaboren un programa sin el uso del RTOS que haga lo mismo que este.


He echo el mismo ejemplo pero con el RTOS OSA (v110306), un PIC18F258 a 20Mhz y usando el timer2 como temporizador para el RTOS. Estoy con el CCS v.4.134 y simulado con el proteus 7.10.

Código: [Seleccionar]
#include <18F258.h>

#fuses HS, NOWDT, NOPROTECT, NOLVP, NODEBUG, NOBROWNOUT

#use delay (clock = 20 000 000)

#use rs232(baud = 9600, uart1)

#include <osa.h>

void Init (void);
void Tarea1 (void);
void Tarea2 (void);
void Tarea3 (void);


void main (void)
{
   Init();  // Init periphery

   OS_Init(); // Init OS

   OS_Task_Define(Tarea1); // Define tasks.
   OS_Task_Define(Tarea2);      
   OS_Task_Define(Tarea3);      

   OS_Task_Create(0, Tarea1); // Create tasks.
   OS_Task_Create(0, Tarea2);  
   OS_Task_Create(0, Tarea3);    
  
   OS_EI();                            // Enable interrupts

   OS_Run();       // Running scheduler
}

void Init (void)
{  
   // TImer2 used for system ticks
   // post = 4, period = 250*4*5* 0.2 us = 1 ms
   setup_timer_2(T2_DIV_BY_4, (250-1) ,  5);
  
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_TIMER2);
}

// System timer (for system ticks)
#INT_TIMER2
void timer2_isr (void)
{
    OS_Timer();
}

void Tarea1(void)
{
   for (;;)
   {
      printf("Ejecutada tarea 1\r");    
      OS_Delay(1000);
   }
}

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

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

Y el OSAcfg.h:
Código: [Seleccionar]
#ifndef _OSACFG_H
#define _OSACFG_H

#define OS_TASKS               3
#define OS_DISABLE_PRIORITY
#define OS_ENABLE_TTIMERS

#endif

Gracias reiniertl.
Título: Re: Sistemas operativos en PIC
Publicado por: matlixco en 04 de Abril de 2014, 19:21:19
Muchas gracias reinier. hace un par de años busque información sobre RTOS de CCS pero no encontré mucha, de haber encontrado tu post en ese entonces hubiera sido de gran ayuda. muchas gracias por todo la información y los ejemplos. :) ya pude usar rtos gracias a ti, que pusiste esto para todos.

Espero aún se pueda agregar un poco más de rtos en lo futuro.
Título: Re: Sistemas operativos en PIC
Publicado por: eduardo_avelar en 19 de Junio de 2014, 15:15:40
Este hilo ha sido un poco olvidado, pero no perdemos nada en seguir aportandole. Les comparto un fragmento del libro "Advanced pic microcontroller projects in c", es el capitulo 10 de este que se titula "Multi-Tasking and Real-Time Operating Systems (https://f8e54762be7a1903c9954a0f290c502a808548f9.googledrive.com/host/0B66f7b-FUu65RGdZLWdZOEIyQzQ/Multi-Tasking%20and%20Real-Time%20Operating%20Systems.pdf)", donde habla sobre los rtos, como ejemplos en CCS Compiler, espero y les sirva de ayuda, y gracias reinier por el gran aporte que iso, nos bendria bien mas informacion al respecto, saludos
Título: Re: Sistemas operativos en PIC
Publicado por: MGLSOFT en 19 de Junio de 2014, 16:33:01
Muy buen capitulo.
Título: Re: Sistemas operativos en PIC
Publicado por: cvargcal en 22 de Mayo de 2016, 18:55:44
Hola a todos, este tema esta genial. Pero disculpen mi ignorancia aun no logro entender el planificador:
hice un programa de esta forma:

Código: C
  1. #use rtos(timer=0,minor_cycle=100ms)      // Configuración del RTOS
  2.  
  3.  
  4. //***** Tarea#: Get GPS *************
  5. #task(rate=900ms,max=100ms)
  6. //***** Tarea#: Lectura de Comando ****
  7. #task(rate=800ms,max=10ms)
  8. //***** Tarea#: Alertas en entradas *****
  9. #task(rate=700ms,max=10ms)  
  10. //***** Tarea#: Configuración GPRS ****
  11. #task(rate=600ms,max=100ms)  
  12. //***** Tarea#: Reporte **************
  13. #task(rate=200ms,max=10ms)
  14. //***** Tarea#: PWM ****************
  15. #task(rate=100ms,max=100ms)

Lo entiendo de esta forma:
1- Hay un tiempo mínimo de ejecución que es 100ms
2- La tarea se ejecuta cada "X" tiempo y toma "Y" tiempo de ejecución.

La duda es, ¿Cuando la tarea necesita mucho tiempo, más del tiempo especificado ahí que sucede?
¿Salta la siguiente tarea y la actual se queda a medias?

Mi confusión:
1- La tarea  "configuración del modem GPRS" Estoy seguro que no se toma los 100ms...
en teoría debería tomar al redor de 5 segundos (por los retardos y demás procesos).

2 - La tarea "PWM" es básicamente tiempo off, on de un led para indicar el estado del programa.
lo tengo de esta forma, "blink_led(50,500); // time up , time down"   50ms en alto, 500ms en bajo,
pero se supone que esa tarea toma máximo 100ms.

¿Entonces como es la cosa?

Pero  lo curioso es que así como esta, mi programa corre muy bien. ¿Cómo es eso?
¿A dónde voy? Quiero entender  cómo debo configurar optimamente el planificador.