# Realizar acciones paralelas en un pic



## sammaael (Abr 29, 2010)

Hola a todos. La verdad se me hace un poco dificil explicar cual es mi duda pero alla voy. Quisiera saber si es posible ( y de ser asi como hacerlo) realizar dos instrucciones o acciones en forma paralela en un pic cualquiera sea este. Por ejemplo mientras se escanea un teclado, paralelamente a esto, el pic realice otras tareas como puede ser controlar leds o displays.
bueno se que mi explicacion no ha sido buena. espero haya un adivino que entienda lo que quiero hacer.

PD: Si lo llevamos al plano humano seria como estar caminando y comiendo a la vez. No paramos de caminar mientras caminamos sino que lo hacemos simultaneamente. (bueno una mujer pensara lo contrario)

Gracias Saludos amigos


----------



## DOA (Abr 29, 2010)

Algo parecido seria controlar los leds o displays en el programa principal y escanear el teclado por interrupcion


----------



## Dr. Zoidberg (Abr 29, 2010)

sammaael dijo:


> Hola a todos. La verdad se me hace un poco dificil explicar cual es mi duda pero alla voy. Quisiera saber si es posible ( y de ser asi como hacerlo) realizar *dos instrucciones o acciones en forma paralela en un pic* cualquiera sea este. Por ejemplo mientras se escanea un teclado, paralelamente a esto, el pic realice otras tareas como puede ser controlar leds o displays.
> bueno se que mi explicacion no ha sido buena. espero haya un adivino que entienda lo que quiero hacer.



Dado que los PICs tiene un único nucleo de procesamiento, ejecutar dos instrucciones "en paralelo" es imposible. Lo que sí puedes hacer un lograr ejecución concurrente, donde cada tarea tiene asignada un tiempo de ejecución y un pequeño proceso se encarga de conmutar entre ellas lo suficientemente rápido como para lograr la "apariencia" de ejecución simultánea.
Hacerlo en C es muy fácil si usás el CCS, ya que tenés que agregar algunas directivas de preprocesador para el uso de RTOS y estructurar en programa en funciones perfectamente definidas en base a las tareas a realizar concurrentemente.
Si solo manejás assembler....no tengo idea de como puede hacerse, pero seguro que es posible.


----------



## sammaael (Abr 29, 2010)

justo ese es mi caso soy analfabeto en C. supongo que la idea de conmutar una accion en un corto tiempo daria la impresion de ser ejecutada simultaneamente. Pero si quisiera por ejemplo ejecutar un contador donde se necesita precision a nivel de milisegundos y paralelamente a esto escanear si una tecla se apreto o no para saltar a otra rutina seria esto posible de alguna forma?

claro debe serlo pero no se me ocurre en estos momnetos como..¿habra que tener en cuenta los ciclos que demora en realizar una instruccion y calcular todo eso?


----------



## AleMarquE (Abr 29, 2010)

Claro, en realidad en los pic no podes hacer nada en simultaneo, sí podes hacer cosas muy rápido como si fuera en simultaneo para nosotros. El pic realiza de a una instrucción por vez.

Sin embargo existe una forma de hacer cosas en "paralelo" cuando sea necesario hacerlo usando interrupciones. Las interrupciones son llamadas al procesador para atender alguna situación en particular que vos podes seleccionar, ej algun periférico listo para recibir o transmitir, fin de conteo de un TIMER, etc. Cuando aparece una interrupcion el MCU primero termina de realizar la instrucción que estaba haciendo y despues se dedica a atender la interrupción. Cuando termina de atender la interrupción vuelve al programa principal y continúa con la instrucción siguiente. En los pic las interrupciones y la forma en que la MCU las atiende son programadas por el usuario. Las interrupciones se programan con la ayuda del registro INTCON del pic.

En tu caso podrías programar un TIMER para que cada cierto tiempo genere una interrupción y verifique el estado de algun puerto o lo que sea que necesites.
Esto permitirá que tu programa corra independientemente de la interrupción.


Sino, en lugar de complicarte con interrupciones, podes simplemente utilizar un bucle donde estes permanentemente haciendo las dos cosas en "paralelo" que vos querias hacer. Aunque no se van a realizar en simultaneo, practicamente lo es porque sucede muy rapido.

Espero que te sirva la info!


----------



## sammaael (Abr 29, 2010)

entonces si llamo a una interrupcion el contador seguiria trabajando igual y no le afectaria ??
se podria conseguir esto (llamar a una interrupcion) con el watchdog?? o estoy muy perdido?


----------



## Eclip-se (Abr 29, 2010)

Utiliza unta interrupción para que ingrese cada cierto tiempo por ejemplo 100ms. 
  Variables globales int contTarea1, contTarea2;
  Variables globales bool banderaTarea1, banderaTarea2;
*Dentro de la interrupción:*

```
//Como la interrupción entra cada 100ms banderaTarea1 se activa a 1 S.
  If(contaTarea1++>=10)
  {
    banderaTarea1 = true;
    contaTarea1 =0;
  }
  //Como la interrupción entra cada 100ms banderaTarea2 se activa a 4 S.
  If(contaTarea2++>=40)
  {
    banderaTarea1 = true;
    contaTarea2 =0;
  }
```
 *Dentro de Main:*

```
While(true)
  {
     If(banderaTarea1 = true)
     {
       banderaTarea1 = false;
       //Escaneo teclado
     )
     If(banderaTarea2 = true)
     {
      banderaTarea2 = false;
      //Muestro datos en el display
     )
  }
```


----------



## AleMarquE (Abr 29, 2010)

podes usar uno de los TIMERS como contador y poner un bucle para que esté permanentemente leyendo el pin que te interesa mientras el TIMER cuenta. Creo que no te haria falta usar interrupciones.


----------



## Chico3001 (Abr 29, 2010)

sammaael dijo:


> entonces si llamo a una interrupcion el contador seguiria trabajando igual y no le afectaria ??
> se podria conseguir esto (llamar a una interrupcion) con el watchdog?? o estoy muy perdido?



Efectivamente... cuando el PIC atiende una interrupcion no detiene la ejecucion de los otros modulos... a menos que se lo ordenes....


----------



## AleMarquE (Abr 29, 2010)

el watchdog no te serviría porque lo que genera es el reset del pic, en lugar de una interrupción si no me equivoco. Igualmente un TIMER es practicamente lo mismo que el watchdog, solo que te sirve para generar una interrupción.


----------



## sammaael (Abr 29, 2010)

gracias amigos ahora estoy un poco mas tranquilo.. eclipse al ver el codigo que pusiste me doy cuenta que debo si o si aprender c en algun momento...

Sera muy complicado que la cuenta que realice se visualice en unos displays por ejemplo? creo que no, solo habra que tener cuidado con el tiempo que toman las instrucciones para visualizar en los displays cierto??


----------



## Dr. Zoidberg (Abr 29, 2010)

Sammaael:
Mejor explicanos específicamente que es lo que necesitas hacer concurrentemente, por que si nó, todos estamos ofreciendo soluciones a las adivinanzas.
Si necesitas atender un periférico externo, la forma mas simple es mediante interrupciones, asumiendo que el periférico es capaz de interrumpirte y que no debes hacer eso para muchos periféricos diferentes, por que vas a terminar con un lío de software que no vas a entenderlo mas allá de media hora luego de escribirlo.

Si son tareas sin vinculación externa y temporizadas, con restricciones en los tiempos de duración y accionamiento preemptivo, te recomiendo usar el RTOS por que en un par de minutos vas a tener todo el problema resuelto....lo que significa que tenés que estudiar C.

Por otra parte, que sepas C es casi una obligación, por que desperdiciar el tiempo programando en assembler cosas que las resolvés en un par de minutos con un compilador C...no es una cosa muy coherente...


----------



## antiworldx (Abr 29, 2010)

Es muy facil realmente hacer dos o varias tareas concurrentemente (pseudoparalelismo) utilizando el algoritmo round robbin.

Y la mejor forma de hacerlo, o al menos donde tienes mayor control, es con assembler. Hice algo igual pero para AVR. Este puede ejecutar 4 hilos y cada uno de ellos tiene su propia pila y sus propios registros.

Para hacerlo, necesitas entender muy bien el uso de la pila, ya que la pila o stack es la pidra angular para ello. Tambien una cantidad generosa de ram. 

Te doy la pista.
El timer, cada 1 ms. Cada que arranque el timer, metes los registros a stack, y por ultimo el apuntador del stack a una localidad fija. Despues en otra localidad fija donde tienes el otro apuntador del stack lo cargas, recuperas los registros del stak y al dar regreso de interrupcion, regresara a la instruccion de la siguiente tarea puesto que de ahi fue llamada la ultima vez que estuvo la aplicacion ejecutandose. Es muy facil de hacer pero un poco de comprender si no estas acostumbrado a usar como calzon a un microcontrolador.


----------



## sammaael (Abr 29, 2010)

gracias ezevalla y tienes razon tendre que aprender C....

Lo que queria hacer era basicamente medir un tiempo de reaccion. La idea sencillamente es asi: se tiene una luz que al encender (aca se inicia el cronometro) se debe presionar apresuradamente un pulsador (aca termina el cronometro) y visualizar el tiempo transcurrido en forma real, es decir que al encender la luz, se inicie la cuenta de un cronometro y esta se visualize "en vivo" (que vea los numeritos corriendo como locos en el display) hasta que aprete el pulsador donde ahi se detenga la cuenta. i duda radica en que miestras se realiza el conteo del cronometro de que forma puedo verificar si se presiona o no el pulsador. La idea es hacer una cronometro del orden de los milisegundos lo as preciso posible o almenos aceptablemente precisos para la aplicacion de medir tiempos de aplicacion.
Se que seguramente ustedes sabran como hacerlo y probabemente tengan el codigo de algo similar, pero mi idea es diseñarlo a modo de ejercicio y asi aprender un poquito mas
Gracias


----------



## Meta (Abr 29, 2010)

En cosas paralelas están los PIC32.


----------



## DOA (Abr 29, 2010)

Los pics traen interrupcion por cambio de estado en el puerto B en RB0 o  entre RB4 y RB7, hay programas en los que todo se realiza solo por  interrupciones
Depende de que pic utilices


----------



## asherar (Abr 29, 2010)

sammaael dijo:


> ... (la) duda radica en que miestras se realiza el conteo del cronometro de que forma puedo verificar si se presiona o no el pulsador. ...


Para eso (en un pic 16F84) ponés el botón de set/reset en el pin RB0 y activás su 
interrupción (bit R0IE en el registro INTCON). 
Te quedan 7 bits del registro PORTB para manejar 7 segmentos. 
Con el registro PORTA manejás los cátodos (hasta 4, vas cómodo). 
El contador de tus tiempos y los retardos necesarios los debés implementar 
mediante registros de usuario. 
En realidad el pic sólo estará contando (y mostrando el nro en el display) 
hasta que se produzca la interrupción y se detenga el conteo. 
La implementación de eso en assembler puede no ser elemental, pero 
tampoco es cosa del otro mundo. 
Es más fácil en C pero perdes un poco de control de la resolución temporal. 

La resolución del timer va a depender de cuántas instrucciones tenga que 
ejecutar desde que salta a la rutina de interrupciones y hasta detener el conteo. 
En C ese número lo fija el compilador, en assembler lo fijas vos.
Con un cristal de 20 MHz y el prescaler en 1, cada instucción simple tarda 200 ns.


----------



## sammaael (Abr 29, 2010)

Muchas gracias amigos es de mucha ayuda toda su informacion!! Creo que hare este proyecto en assembler para practicar un poco mas el lenguaje (solo llevo como 1 mes programando pic) y luego veo que hago aprendiendo C..

de nuevo muchas gracias cualquier otra idea es bien recibida de seguro sera util a todos los que nos iniciamos en pic


----------



## antiworldx (Abr 29, 2010)

Repito, en assembler es mejor cuando debes tener total control sobre los registros, especialmente de la pila.


----------



## sammaael (Abr 29, 2010)

y eso que significa ??? se complica mucho el programa en assembler en este caso???


----------



## antiworldx (Abr 29, 2010)

No precisamente... pero de que programa hablamos? del control de hilos o del programa que te interesa hacer compartido.

de cual programa hablas? del que quieres hacer o del que va a controlar los tiempos entre programas o hilos.

El assembler no es complicado. Simplemente, que C te evita escribir mas codigo.
Cada uno tiene sus bondades y sus limitantes. Todo depende.


----------



## Eclip-se (Abr 29, 2010)

sammaael dijo:


> gracias amigos ahora estoy un poco mas tranquilo.. eclipse al ver el codigo que pusiste me doy cuenta que debo si o si aprender c en algun momento...
> 
> Sera muy complicado que la cuenta que realice se visualice en unos displays por ejemplo? creo que no, solo habra que tener cuidado con el tiempo que toman las instrucciones para visualizar en los displays cierto??


Lo mejor es usar C18, para que hagas proyectos de verdad, y puedas usar los programas con otros compiladores.

Tambien.......

No entiendo por que mencionan algoritmos, otros micros. Si sammaael lo único que quiere es leer un teclado y mostrar los datos. Cosas básicas.

  Además hilos o thread por lo general se habla en lenguajes de programación que se ejecutan en sistemas operativos, y aquí en este tema de este blog se pregunta algo elemental.

  No confundir con cosas que no vienen al tema.


----------



## antiworldx (Abr 29, 2010)

Precisamente lo que samael pregunto en un inicio, es ejecutar dos tareas simultaneas... a eso se le llaman hilos. Si solo tienes un nucleo, entonces requieres hilos. Nadie ha metido cosas fuera de tema.


----------



## sammaael (Abr 29, 2010)

dos preguntas 
1-eclipse que es C18??? y a que te refieres con 





> para que hagas proyectos de verdad


 no entendi lo que querias decir con eso

2-antiworldx entiendo la idea de un solo nucleo pero a que te refieres con hilos como se hacen tienes algun tutorial?


----------



## Eclip-se (Abr 29, 2010)

sammaael dijo:


> Quisiera saber si es posible ( y de ser asi como hacerlo) realizar dos instrucciones o acciones en forma paralela en un pic cualquiera sea este. Por ejemplo mientras se escanea un teclado, paralelamente a esto, el pic realice otras tareas como puede ser controlar leds o displays.
> Gracias Saludos amigos


En la pregunta hay algunas cosas importantes, teclado, display y lo mas importante PIC.

Con respecto a lo del C18, es un compilador que te permite escribir los programas en C a demas que permite insertar lineas de codigo en assembler. Y permite generar un codigo optimizado es decir que tu archivo .hex va ha tener un menor tamaño al generado por otros compiladores. Aparte que usando este compilador podras migrar facilmente tu programa a otros compiladores como el C30 o GCC, que son compiladores para escribir codigo para dsPIC y AVRs.


----------



## antiworldx (Abr 29, 2010)

No tengo un tutorial... simplemente un dia se me ocurrio la idea e hice el administradorsillo de hilos.
Es muy simple, pero hay que tener practica con el stack.


----------



## sammaael (Abr 29, 2010)

si te pegaas una de "esas" explicaciones y ayudas a todos los neofitos en esto de los pic seria bueno sino cuando tengas tiempo de suguro lo haces de todas formmas gracias


----------



## eidtech (Abr 29, 2010)

Hace un tiempo hice un kernel multi-tasking para ejecutarse sobre MS-DOS, en realidad no es tan dificil, solo que como comenta antiworldx se necesita práctica con el stack para realizar la rutina de cambio de contexto.

El kernel esta escrito un 90% en lenguaje C, por lo tanto puede ser portado a diferentes arquitecturas con relativa facilidad. La unica parte dificil de portar es la ya mencionada rutina de cambio de contexto... ya que depende mucho del lenguaje ASM y de la arquitectura destino...


----------



## sammaael (Abr 29, 2010)

donde puedo averiguar sobre eso del stack en el contexto que tratamos en este tema


----------



## eidtech (Abr 29, 2010)

aqui viene para AVR..

http://www.avrfreaks.net/modules/FreaksArticles/files/14/Multitasking on an AVR.pdf


----------



## antiworldx (Abr 29, 2010)

Contexto se refiere, a que cada aplicacion use sus registros y pila como si solo tuviera el microcontrolador para el solo.

Te platico que no es algo simple, vas a tener que ponerte a leer un buen rato y no te desesperes.


----------



## marquizto (Abr 29, 2010)

Chico3001 dijo:


> Efectivamente... cuando el PIC atiende una interrupcion no detiene la ejecucion de los otros modulos... a menos que se lo ordenes....


al aplicar una interupcion se detiene automaticamente lo que esta asiendo guardando la direccion actual y dirigiendose a la posicion 04 de la memoria, una vez que vuelve de la interupcion continua con la rutina principal, 1 ms no es mucha velocidad,mira si el pic trabaja con un cristal de 4 Mhz, cada instruccion se demora 1us. puedes ejecutar 999 lineas de comando y luego scanear por decirte un ejemplo basico puedes escanear 10 perifericos y si uno se activa puedes dar para realizar alguna rutina 100 instrucciones y todavia la velocidad de scaneo por cada periferico es menor a 1 ms.  

explica lo que haces y te ayudamos para tener una mejor idea.
y en assembler queda perfecto.

leyendo mas tu explicacion, si quieres controlar un teclado y unos led no necesitas para nada hacer rutinas en paralelo, la frecuencia es muy poca, para tu caso poner una instruccion bajo la otra para efectos practicos de lo que tu quieres realizar, tu veras los resultados en forma simultanea.  a menos que seas capaz de pulsar en un segundo un millon de veces un boton o ser capaz de ver un millon de cosas en un segundo, y si aun asi eres capaz utiliza un crystal de 20 Mhz, y tienes 0.2 us por cada instruccion .


----------



## Dr. Zoidberg (Abr 29, 2010)

Eclip-se dijo:


> Además hilos o thread por lo general se habla en lenguajes de programación que se ejecutan en sistemas operativos, y aquí en este tema de este blog se pregunta algo elemental.
> *No confundir con cosas que no vienen al tema.*



Creo que vas a tener que revisar un poco la tecnología actual, por que el RTOS del CCS ejecuta una suerte de hilos (solo que los llama Tasks) sobre cualquier PIC, con arraque y duración perfectamente definidos y sin tener que pelear con el stack ni con nada...solo con el problema que debe solucionar.

Y nadie confunde con nada...excepto quizás vos. La tecnología de procesamiento concurrente es exactamente la misma en un micro poderoso o en un microcontrolador, con o sin MMU...así que el concepto es COMPLETAMENTE APLICABLE...y más aún si ni siquiera tenés que pensar vos el código de task scheduling...


----------



## antiworldx (Abr 29, 2010)

Maestro obi wan... ilustrame! (es en serio)

Puedes explicar un poco mas ese asunto con los pics por favor? Yo hice mi propio administrador de tareas para AVR´s que es una plantilla donde estan definidos servicios y cosas que uso. Pero al parecer esto ya es un compilador ya hecho para hacerlo por si solo. Entiendo bien?


----------



## Dr. Zoidberg (Abr 29, 2010)

antiworldx dijo:


> Maestro obi wan... ilustrame! (es en serio)



   



antiworldx dijo:


> Puedes explicar un poco mas ese asunto con los pics por favor? Yo hice mi propio administrador de tareas para AVR´s que es una plantilla donde estan definidos servicios y cosas que uso. Pero al parecer esto ya es un compilador ya hecho para hacerlo por si solo. Entiendo bien?



El compilador CCS para el lenguaje C, entre las varias cosas que ofrece, trae la posibilidad de estructurar el código en *tareas*, que no son mas que funciones sin parámetros y que no retornan nada (void), así que vos estructurás tus programa en tareas separadas usando este tipo de declaarciones y precedés a cada una con una directiva *#task* con algunos parámetros que definen cada cuanto tiempo se ejecutan, cuanto es la maxima duración que puede permitírsele tener y con cual timer se controla la ejecución.

Luego tenés que preceder el main() con una directiva *#use rtos* que le indica al compilador que debe incluir el código de un micro sistema operativo de tiempo real que incluye el dispatcher que se encarga de ejecutar las tasks bajo los parámetros especificados.

La ventaja de este método es que no tenés que luchar con las interrupciones ni nada. Solo especificás los parámetros de ejecución temporal en la directiva #task y ya estás hecho: el RTOS las ejecuta por vos.

El único problema es que el scheduler no es preemptivo, sino cooperativo y un mal diseño de una tarea puede palmar la ejecución del scheduler...pero esta cosas se arreglan fácilmente.

Donde trabajo se está usando esta técnica para gestionar la ejecución de controladores PID para control de motores eléctricos, mas la comunicaciones en bus CAN, mas la odometría y lectura de los GPS en un cuatriciclo automatizado, mas otra parva de cosas enlazando como 8 PICs...y anda sin ningún problema....aunque a veces hay que usar interrupciones cuando esto no dá para más...


----------



## Beamspot (Abr 30, 2010)

O sea, que el CCS incluye un RTOS ya escrito? "No te acostarás sin saber una cosa más".

Yo también hice un RTOS para AVR (Mega128 con GCC y portado a Mega1281 con IAR), y las rutinas más importantes las escribí en ensamblador, no en C. Me basé en el fantástico documento explicado anteriormente. Muy muy instructivo y altamente recomendable como ejercicio a los programadores más avanzados.

Una vez tiener el kernel del RTOS y algo de práctica en usarlo, la cosa se vuelve mucho más fácil de programar, pero hace falta RAM, y a ser posible, más parámetros de control (tick de sistema, prioridades, espacio de pilas - stack, etc).

De hecho, una de las 'ventajas' de los AVR se convierte en desventaja cuando se usa un RTOS, y es que salvar 32 registros acumuladores hace que el tiempo de conmutación de tarea sea largo. Claro que el hecho de tener la pila en HW en lugar de RAM tampoco simplifica mucho las cosas que digamos.

Por cierto, un dispatcher no es un sistema operativo ni tiene porqué usarse en tal. De hecho, los dispatchers se usan bastante para programas que no necesitan mucha velocidad de reacción ni multitarea para sustituir a los (más pesados) sistemas operativos ya que son más sencillos y necesitan menos recursos.

Por cierto, hay varios tipos de sistemas operativos para microcontroladores, cuya principal y única misión es facilitar la multitarea: los cooperativos y los preventivos. Los primeros son más ligeros y necesitan menos stack, pero no son realmente tiempo real, y necesitan la cooperación del programador, a cambio, se pueden usar más facilmente en micros 'pequeños'. Los preventivos son más complejos y necesitan más recursos, pero son más seguros. Por eso se usan en los sistemas de automoción, y son la principal baza de los ARM, pues éstos están muy pensados para ser usados con RTOSes, tal y como se puede deducir de su arquitectura interna, especialmente de los Cortex M3.


----------



## Dr. Zoidberg (Abr 30, 2010)

Beamspot dijo:


> O sea, *que el CCS incluye un RTOS ya escrito?* "No te acostarás sin saber una cosa más".



Así es...ya viene listo y el compilador se encarga de armar todo para preparar la ejecución del dispatcher con la función *rtos_run()*.
Hay muchas funciones adicionales que te permiten comunicar las tareas mediante mensajes, liberar el control al scheduler con un yield(), habilitar y deshabilitar tareas para su ejecución, etc, etc...en fin, todo el soporte necesario para multitarea...cooperativo pero multitarea al fin....y sin transpirar nada


----------



## Beamspot (Abr 30, 2010)

¿Lleva también ventanas de control de estado de tareas, traza, control de gasto de pila, etc. al estilo PowerPAC de IAR? Interesante cuando menos.


----------



## Dr. Zoidberg (Abr 30, 2010)

Beamspot dijo:


> ¿Lleva también ventanas de control de estado de tareas, traza, control de gasto de pila, etc. al estilo PowerPAC de IAR? Interesante cuando menos.



No tiene tanto....pero puede llevar algunas estadísticas de ejecución. Te paso lo que dice el help:


			
				Help CCS dijo:
			
		

> Syntax:
> #use rtos *(options)*
> 
> Elements:
> ...


----------



## eidtech (Abr 30, 2010)

Beamspot dijo:


> Por cierto, hay varios tipos de sistemas operativos para microcontroladores, cuya principal y única misión es facilitar la multitarea: los cooperativos y los *preventivos*. Los primeros son más ligeros y necesitan menos stack, pero no son realmente tiempo real, y necesitan la cooperación del programador, a cambio, se pueden usar más facilmente en micros 'pequeños'. Los preventivos son más complejos y necesitan más recursos, pero son más seguros. Por eso se usan en los sistemas de automoción, y son la principal baza de los ARM, pues éstos están muy pensados para ser usados con RTOSes, tal y como se puede deducir de su arquitectura interna, especialmente de los Cortex M3.



No me parece la traducción mas de preemptive a preventivos ... tal vez pudiese quedar mucho mejor : prioritarios... aunque también la he escuchado traducida como expulsivos..


----------



## antiworldx (Abr 30, 2010)

Jaaaaaaaa, administras los hilos como en java... solo que en java le pones tread.

Precisamente las funciones que me describes son las que hago con mi administrador de tareas que hice en ensamblador.
Tengo rutinas ya listas para operar pantallas, teclados, sumas, restas, divisiones y multiplicaciones de 16 y 32 bits y adicionalmente puedo asignar el tamaño de la pila de cada tarea, tiempo de ejecucion y efectivamente, una funcion que libera la aplicacion para pasar a otra tarea. Pero todo en ensamblador.

Todo es perfecto, pero fijate que ahorita tengo mi nemesis, ya que precismante tengo que hacer un PID para controlar un motor. Coincidencias... Pero imaginate el problemon que estoy teniendo para hacer el punto fijo de la ecuacion de diferencias.
Una pregunta... el AVR studio soporta esas funciones???


----------



## Dr. Zoidberg (Abr 30, 2010)

antiworldx dijo:


> Todo es perfecto, pero fijate que ahorita tengo mi nemesis, ya que precismante tengo que hacer un PID para controlar un motor. Coincidencias... Pero imaginate el problemon que estoy teniendo para hacer el punto fijo de la ecuacion de diferencias.



Pero no habías encontrado una biblioteca de aritmética en punto fijo?
El compilador CCS no tiene punto fijo pero tiene una muy buena y rápida implementación de punto flotante. Si el tiempo de muestreo no es demasiado pequeño, el punto flotante es "usable" sin problemas.



antiworldx dijo:


> Una pregunta... el AVR studio soporta esas funciones???



No tengo la más minima idea, ya que no uso esos procesadores.


----------



## Beamspot (May 3, 2010)

El AVRStuio no lleva nada de esto integrado, a diferencia del CCS. Sin embargo, el FreeRTOS para AVR está escrito precisamente para el WinAVR-GCC del AVRStudio, así que se puede usar sin problemas (www.freertos.org creo).

Respecto de la coma flotante o fija, la librería de math.h del WinAVR es inmediata, y está comprobado que los AVR tienen un rendimiento de entre 60 y 100 KFLOPs a 16MHz. Aún así, las veces que he hecho DSP con AVR he acabado haciendo coma fija 'a mano', mirando los bits, overflows, acarreos y demás, y aunque ha sido un trabajo arduo, el resultado es más que generoso en cuanto a prestaciones. Para un PID, hacer todo el cálculo dentro de la ISR es factible si se hace este procedimiento, mientras que la coma flotante igual precisa de tiempos excesivos para ser ejecutada dentro de una interrupción.

Esto de acuerdo respecto de la traducción de preventivo - expulsivo. Pero quizás la mejor traducción (muy libre, eso sí) sería la de transparente, ya que de esta manera las tareas se ejecutan como si fuesen una sola de manera muy transparente y con menos necesidad de conocer los requerimientos de otras tareas o del SO.

Ah, se me olvidaba. Un pequeño comentario respecto del punto fijo: los DSP de punto fijo tienen más instrucciones de cálculo y complicaciones que los de coma flotante. Y requieren un esfuerzo de programación mayor por parte del programador y/o compilador debido a todas las historias de acumulación, desbordamiento, números de bits, redondeo, etc. Por algo será. Por algo las librerías de cálculo suelen ser sólo en coma flotante.

Por cierto, para hacer matemáticas en coma fija y flotante, te recomiendo que las hagas en C (es muy fácil) y luego las compiles. El WinAVR genera un código ensamblador muy bueno y optimizado que puedes usar luego en tu programa.


----------



## antiworldx (May 3, 2010)

Si por su puesto, si pense en hacerlo en C y al burro con los problemas del punto.
El detalle esta en que necesito controlar mas cosas, como una pantalla, teclado y cosillas asi. El asunto esta, que mi administrador de hilos, lo trabajaria perferctamente todo si no fuera por que tengo que trabajar decimales y negativos y demas. De hecho ya tengo trabajando el pid en C. Pero entonces, lo hago en C y no puedo hacer hilos, Lo hago en ensamblador pero no puedo trabajar los decimales. Tengo ese problema atorado y por eso es que estoy buscando alternativas y he ahi porque vine de metiche a este hilo y quise leer las opiniones de ezavalla.
Ahora. Las librerias que me comentan, son para C, mas seria genial encontrar algunas rutinas en ensamblador para punto fijo. Enn fin, no voy a desviar el tema con el punto flotante.

Ezavalla: No no he encontrado bibliotecas en punto fiijo, ya que los micros siempre los programo en ensamblador por los multihilos.


----------



## Beamspot (May 3, 2010)

Y donde está el problema en copiar el código resultante en ensamblador una vez compilado el programa en C? Ctrl+C, Ctrl+V. Sólo es cuestión de encontrar ese ensamblado, pero existe, ya que lo hice (hace muuucho tiempo, ya no me acuerdo como).


----------



## Dr. Zoidberg (May 3, 2010)

Beamspot dijo:


> Y donde está el problema en copiar el código resultante en ensamblador una vez compilado el programa en C? Ctrl+C, Ctrl+V. Sólo es cuestión de encontrar ese ensamblado, pero existe, ya que lo hice (hace muuucho tiempo, ya no me acuerdo como).



Esa es una excelente idea.   
Probablemente sea un poco mas complicado que solo copiarlo, pero así vas a tener una excelente referencia para hacerlo.


----------

