Autor Tema: Concurrencia en CCS PICC  (Leído 8049 veces)

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

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Concurrencia en CCS PICC
« Respuesta #30 en: 22 de Diciembre de 2004, 09:02:00 »
Lo de los 50ms es por el 5, ese número es un comodín a partir del cual se pueden conseguir muchas temporizaciones multiplicando adecuadamente. Por ejemplo:

500us=0,5ms -----> 0,5·2=1ms ---> 0,5·3=1,5ms ---> 0,5·4=2ms ... etc

Nocturno el output_bit(PIN_B2,!bit_test(port_b,3)); último ¿no estaría mal? eso estaría contínuamente oscilando, le haría falta delante un if ¿no?

Se podía también, haber hecho sin interrupción detectando la subida de T0IF (así no se gasta tiempo en entrar en la interrupción, aunque en este caso no es crítico).

Tornar cuando tengas un trocito de código muestralo, haz el favor.

Un saludo

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #31 en: 22 de Diciembre de 2004, 09:31:00 »
No, no está mal. Lo que hace esa línea no es invertir el mismo pin del led, sino lo que haya en el pin del interruptor. Por tanto, no cambia de estado mientras el interruptor no se toque.

Ahora entiendo lo de los 50ms. Vamos, que también lo podría haber hecho con una base de tiempos de 25, 10, 5, 2 o 1ms por ejemplo.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Concurrencia en CCS PICC
« Respuesta #32 en: 22 de Diciembre de 2004, 10:44:00 »
Sí es cierto está bien, no me había percatado del 3, si en lugar del 3 fuera un 2 entonces sí estaría mal.

Lo del 0,5 (o 50) es porque multiplicando esta cantidad por un número entero consigues todas las temporizaciones de números enteros. Si utilizaras como base un 2 y quisieras conseguir un total de 13 o  17, por ejemplo,  no hay ningún entero que multiplicado por 2 dé 13 o 17.

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: Concurrencia en CCS PICC
« Respuesta #33 en: 22 de Diciembre de 2004, 13:20:00 »
bien, bien... ya se van viendo progresos...
unas cosillas:

lo de la base de tiempo dependera de la exactitud que necesitemos en nuestro programa. hablamos de silmutanear procesos en los que la exactitud no es critica (para esas tareas tenemos otras interrupciones) por lo que una base de tiempo de 50 ms esta bien, el error maximo que tendremos sera el correspondiente al SCAN de nuestro programa, por eso los programas deben estar optimizados... ni un delay por encima de 50 ms...FlashFlashFlashFlash.

ojo, andamos buscando una solucion generica, esto es que se pueda usar para temporizar 10 led con cambios minimos o ir añadiendo tareas sin tener que tocar lo ya terminado... eso de rutinas gigantes dentro del codigo de la interrupcion no es buena idea para muchas tareas, aunque funciona muy bien con pocas tareas, como Manolo demuestra con su ejemplo.

saludos


Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #34 en: 23 de Diciembre de 2004, 07:28:00 »
Acabo de subir el ejercicio que hice el otro dia, que como os comente, simplemente cuenta y muestra por LCD el nº de instrucciones (aprox. 10) ejecutadas antes de producirse cada nueva interrupcion. Aki teneis el link:

http://miarroba.com/foros/ver.php?foroid=348538&temaid=2669749

Ahora el siguiente paso seria conseguir una rutina de interrupcion que en vez de devolvernos siempre al mismo proceso, nos cargase en la pila (donde esta cargado el valor de la direccion de memoria desde la que se produjo la interrupcion), el valor de memoria del siguiente proceso.

Mi idea es tener un array de enteros de una longitud igual al nº de procesos que keramos ejecutar concurrentemente, donde almacenemos la direccion siguiente de cada proceso. Ejemplo:

long int s[10];         //para ejecutar un maximo de 10 procesos concurrentemente

s[0]=xxxxx;            //Inicializamos todos los procesos con la direccion de su 1ª instruccion
s[1]=xxxxx;
.......
....
s[9]=xxxxx;


Ahora en la rutina de interrupcion, si el proceso que ha realizado la interrupcion es s[0], guardamos la direccion de memoria de la ultima instruccion de nuestro proceso (dicha direccion estara en la pila) en s[0], y cargamos el valor que haya en s[1] a dicha pila; luego cuando se produzca la interrupcion en s[1], guardamos el valor de la pila en s[1] (ese valor, sera la direccion de la ultima instruccion de proceso 1 ejecutada),y cargamos el valor que haya en s[2] en nuestra pila, y asi sucesivamente, luego cuando lleguemos a s[9], volvemos a refererirnos a los valores almacenados en s[1], y de esta forma realizamos concurrencia simulada, teniendo cada proceso una cantidad de tiempo el control del micro.

Si alguien me ayuda para crear esta rutina de interrupcion se lo agradeceria, una vez que tengamos hecho esto, el siguiente paso es crear el tipo abstracto de datos semaforo, que ya le tengo practicamente implementado en casa, para conseguir la comunicacion entre procesos.

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: Concurrencia en CCS PICC
« Respuesta #35 en: 25 de Diciembre de 2004, 15:20:00 »
esta interesante Tonar.... pero yo opto por una forma mucho mas sencilla:

tratar de ejecutar los procesos uno detras de otro pero sin interrumpir el micro con delays... basicamente la forma de trabajar de un PLC. para cada tarea tenemos una estructura con sus datos y si otra tarea los necesita simplemente se usan, como las tarea se ejecutan de forma integra antes de iniciar la siguiente los datos en las estructuras son correctos.

claro, hablamos de procesos en los que el tiempo de scan no es critico.. si existe una tarea critica la metes en una interrupcion.

basicamente es realizar un programa en state machine....

si necesitas realmente un rtos mejor usar el picos18 o el salvo... ademas ccs ya incorpora un multitasking pero quien se atreveAvergonzadoAvergonzadoAvergonzado

saludos

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #36 en: 27 de Diciembre de 2004, 03:08:00 »
¿Que tipo de multitarea trae ya implementada CCS? Quizas sea lo que ando buscando y ya solo deberia implementar semaforos o un mecanismo de sincronizacion de procesos.

Pq respecto a lo que postee anteriormente, el principal problema seria que solo se podria usar con micros PIC18xxxx ya que son los unicos que permiten cierto manejo en la pila de interrupciones, puesto que en los demas PIC"s el control de la pila es totalmente invisible al usuario y no se puede ni si kiera meter o sacar valores de la pila.


Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #37 en: 28 de Diciembre de 2004, 03:59:00 »
Al mirar las News de CCS, he visto que estan trabajando en un nuevo RTOS para CCS, asi que kizas lo mas sensato sea esperar para obtener un codigo optimizado y eficiente, pero aun asi, si obtengo algo interesante, posteare el codigo.

Aki teneis la noticia de CCS:

CCS is also testing our new RTOS and our new linker this month. If you would like to participate in testing either of these features AND you have active PCW maintenance e-mail support@ccsinfo.com.


Y aki el enlace a las News de CCS, por si kereis verificar la notica por vosotros mismos:

http://www.ccsinfo.com/news.shtml

Desconectado Tec_Claudio_Perez

  • PIC12
  • **
  • Mensajes: 62
RE: Concurrencia en CCS PICC
« Respuesta #38 en: 29 de Diciembre de 2004, 08:13:00 »
Hola,
Fijense en este tema sobre la implementación de multitarea aun en micros pequeños, sin acceso a la pila.
http://miarroba.com/foros/ver.php?foroid=6510&temaid=1416423

Está pensado en assembler, pero no sería dificil hacerlo en CSS (En esa epoca solo programaba en ASM).

Algo interesante para agregar son las prioridades.
Supongamos un proceso que sea un led que tiene que titilar a una frecuencia exacta, y otro proceso no tan critico que sea leer el estado de un pulsador.
Como los procesos no tienen la misma prioridad sería interesante poder ejecutarlas con mayor o menor frecuencia de acuerdo a su importancia.
Por supuesto que si la tarea es crítica, lo mejor es usar una interrupcion.
No hace falta que los dos procesos se ejecuten con la misma velocidad. Por lo que se puede agregar un contador adicional que se decremente cada vez que se entra a la rutina. Si el contador llego a 0, se ingresa y se ejecuta el estado correspondiente, sino se sale, y se pasa a ejecutar la siguiente rutina. De esta forma se puede hacer con un contador en 10 para el pulsador, por cada diez veces que se ejecute la rutina del led, se ejecute una vez la lectura del pulsador.

Saludos.

Téc. Claudio J. Pérez
Ciberar-Sistemas & Desarrollos
Jujuy-Argentina

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #39 en: 03 de Enero de 2005, 05:04:00 »
Finalmente he conseguido algo de codigo que realiza concurrencia de la forma que plantee anteriormente usando cualquier PICF18xxx, me gustaria que la gente me fuera diciendo los distintos fallos que ven en el, para corregirlos antes de empezar la implementacion de semaforos para sincronizacion de procesos.

El numero de procesos que he puesto es 5 (procesos 0..4), aunke se pueden añadir mas, simplemente modificando las partes pertinentes del codigo y añadiendo el nuevo proceso, podemos trabajar con cualquier numero de procesos, siempre que no nos comamos toda la memoria de nuestro PIC.

Otro apunte, el codigo que va entre los WHILE (1) {  printf(lcd_putc,"x"Giño;      } puede ser modificado a gusto del usuario, ya que es el codigo de cada proceso, esos printf solo estan puestos ahi, para realizar pruebas a la hora de programar. Todos los fallos que encontreis ir posteandolos aki, a ver si entre todos podemos hacer una herramienta de concurrencia simulada que sea eficiente y sencilla, ya que creo que es algo muy interesante para cualquiera que este interesado en el mundillo de los microcontroladores. Se pueden aplicar a campos de I.A., para ejecutar varias tareas mientras esperamos el fin de una espera activa, etc.

Este es el link, he subido tanto el codigo, como su compilacion y su simulacion en Proteus.

http://miarroba.com/foros/ver.php?foroid=348538&temaid=2706546


Agradeceria de veras cualquier sugerencia, Saludos.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Concurrencia en CCS PICC
« Respuesta #40 en: 03 de Enero de 2005, 05:21:00 »
No consigo ver nada en el LCD del simulador Tornar, ¿en qué versión de Proteus lo has hecho?

De todas formas, he estado mirando por encima el código y tiene una pinta acojonante, enhorabuena.

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #41 en: 03 de Enero de 2005, 05:26:00 »
Hola Nocturno, la version de Proteus que he usado es la 6.3 SP1. Y deberia salir por LCD los procesos que esta ejecutando en cada momento. Si no os funciona o no disponeis de esta version de Proteus, dejarme un privado, pq a mi la verdad s que me va bastante bien.

Has probado al seleccionar con Proteus en el PIC la nueva ubicacion donde esta el archivo .HEX una vez descomprimido el archivo .RAR?


Saludos. Giño

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Concurrencia en CCS PICC
« Respuesta #42 en: 03 de Enero de 2005, 05:31:00 »
Parece que el timer interrumpe cada 200 us mas o menos.Con ese margen de tiempo no parece crítico,pero ten en cuenta que si se precisa una temporización menor,la rutina de interrupción hay que reducirla al máximo,está demasiado cargada a mi parecer.
Por ejemplo,el "if" que te hace volver al primer proceso tras ejecutar el último podrías implementarlo en el código de ese último proceso.
Saludos

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #43 en: 03 de Enero de 2005, 10:38:00 »
Cierto Modulay, esta noche me pondre con ello, para tratar de reducir al minimo el codigo de interrupcion, en principio lo del IF-ELSE parece facil de sacar y meterlo en el main. Pero ahora mismo lo que mas me importa  es saber si falla, en algun momento, al ejecutar varios procesos que realicen diversas tareas.

Antes de implementar los semaforos para la sincronizacion de los procesos, me pasare 2 semanas, probando este codigo y mezclando diversos procesos de manejo de Led"s, LCD, motores, etc. Si alguien me puede ayudar a detectar fallos se lo agradeceria.

Desconectado tornar

  • PIC18
  • ****
  • Mensajes: 342
RE: Concurrencia en CCS PICC
« Respuesta #44 en: 04 de Enero de 2005, 04:41:00 »
He realizado unas pocas mejoras al codigo, para que trabaje mas eficientemente, he reducido un poco el tamaño del codigo de interrupcion y tambien he kitado la espera activa de interrupcion, para que en vez de esperar, empiece a ejecutar el primer proceso inmediatamente despues de cargar todos en la cola de procesos. Y por ultimo he cambiado las variable "x" y "proceso" a variables locales del main(), y en el caso de la variable "proceso", ahora es de tipo BOOLEAN, para que el codigo sea mas claro y gaste algo menos de memoria.  


Aki esta el codigo:

#include <18f452.h>
#fuses NOWDT,NOPROTECT,XT
#use delay (clock=4000000)
#include <LCD.C>

#byte TOSU = 0xFFF
#byte TOSH = 0xFFE
#byte TOSL = 0xFFD
#byte STATUS = 0xFD8
#byte BSR = 0xFE0
#byte STKPTR = 0xFFC

int cola_proc[5][3];  //Concurrencia para 5 procesos
int W_temp[5];
int BSR_temp[5];
int STATUS_temp[5];

int save_W;
int save_STATUS;
int save_BSR;

int i=0;

// ----------------Rutina de interrupcion para cambio de proceso----------------

#INT_RTCC FAST //FAST - para controlar nosotros mismos SAVE,RESTORE(BSR,W,etc.)
void cambio_proceso ()
{
 //Almacenamos estado actual del procesador
 #asm
 MOVWF save_W
 MOVFF STATUS, save_STATUS
 MOVFF BSR, save_BSR
 #endasm

 W_temp=save_W;
 STATUS_temp=save_STATUS;
 BSR_temp=save_BSR;

 cola_proc[0]=TOSU; //Salvamos la direccion de la ultima sentencia
 cola_proc[1]=TOSH; //ejecutada del proceso i
 cola_proc[2]=TOSL;

 lcd_putc("f");

 i+=1;

 IF (i>4) i=0; //Cuando hemos ejecutado todos los procesos, volvemos al primero

 TOSU=cola_proc[0]; //Cargamos en la cima de la pila, la direccion de la
 TOSH=cola_proc[1]; //siguiente instruccion a ejecutar del proceso i
 TOSL=cola_proc[2];

 //Restauramos estado del procesador para el proceso i
 save_W=W_temp;
 save_STATUS=STATUS_temp;
 save_BSR=BSR_temp;

 #asm
 MOVF save_W, W
 MOVFF save_STATUS, STATUS
 MOVFF save_BSR, BSR
 #endasm
}
// -----------------------------------------------------------------------------


main()
{
 BOOLEAN proceso=FALSE; //Deshabilitamos entrada a procesos
 int x;

 lcd_init();
 setup_counters(rtcc_internal,rtcc_div_1);
 enable_interrupts(INT_TIMER0);
 enable_interrupts(GLOBAL);
 set_rtcc(0);

// --------------------PROCESO 0--------------------
 #asm
 push
 #endasm
 cola_proc[0][0]=TOSU; //Salvamos la 1ª sentencia del proceso 0
 cola_proc[0][1]=TOSH;
 cola_proc[0][2]=TOSL;
 WHILE (proceso)
 {
  printf(lcd_putc,"0");
 }
//           -----------------------------


// --------------------PROCESO 1--------------------
 #asm
 push
 #endasm
 cola_proc[1][0]=TOSU; //Salvamos la 1ª sentencia del proceso 1
 cola_proc[1][1]=TOSH;
 cola_proc[1][2]=TOSL;
 WHILE (proceso)
 {
  printf(lcd_putc,"1");
 }
//           -----------------------------


// --------------------PROCESO 2--------------------
 #asm
 push
 #endasm
 cola_proc[2][0]=TOSU; //Salvamos la 1ª sentencia del proceso 2
 cola_proc[2][1]=TOSH;
 cola_proc[2][2]=TOSL;
 WHILE (proceso)
 {
  printf(lcd_putc,"2");
 }
//           -----------------------------


// --------------------PROCESO 3--------------------
 #asm
 push
 #endasm
 cola_proc[3][0]=TOSU; //Salvamos la 1ª sentencia del proceso 3
 cola_proc[3][1]=TOSH;
 cola_proc[3][2]=TOSL;
 WHILE (proceso)
 {
  printf(lcd_putc,"3");
 }
//           -----------------------------


// --------------------PROCESO 4--------------------
 #asm
 push
 #endasm
 cola_proc[4][0]=TOSU; //Salvamos la 1ª sentencia del proceso 4
 cola_proc[4][1]=TOSH;
 cola_proc[4][2]=TOSL;
 WHILE (proceso)
 {
  printf(lcd_putc,"4");
 }
//           -----------------------------

 proceso=TRUE; //Habilitamos entrada a procesos

 FOR (x=1;x<5;x++) //Cargamos la direccion del primer proceso y limpiamos pila
 {
  #asm
  pop
  #endasm
 }
 
 goto_address(*STKPTR); //Ejecutamos proceso 0,que se encuentra en cima de pila
}