Diferencia entre revisiones de «Grupo HotPlug»
(→Desarrollo del problema :) |
(→Desarrollo del problema :) |
||
Línea 73: | Línea 73: | ||
time_last2 = time_act; | time_last2 = time_act; | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | Este código realiza las siguientes acciones: | ||
+ | |||
+ | 1)Recorremos los conectores, y guardamos su tipo y sub-tipo anteriores. | ||
+ | |||
+ | 2)Si no había un conector en la lista de handlers y además, los tipos y sub-tipos son distintos, agregamos el conector llamando a '''add_module(f);''' de PnP.pde | ||
+ | |||
+ | 3)Sino, debemos borrar del handler el módulo que acabamos de desconectar. Debemos implementar esta función, a la que llamaremos '''remove_module.''' | ||
+ | |||
+ | ---- | ||
+ | |||
+ | * Para implementar remove_module, exploramos el handler, buscando el módulo a borrar y lo sustituimos por el módulo que se encuentra en la última posición ocupada del handler. Actualizamos, también, la cantidad de módulos. Incluimos la primera versión de nuestro código: | ||
+ | |||
+ | <source lang="c"> | ||
+ | void remove_module (byte num_conector) { | ||
+ | |||
+ | int i=8; //Comenzamos a recorrer desde el 8 ya que desde el 8 se comienzan a agregar los nuevos conectores. | ||
+ | while ( (i< num_modules) && (handler[i].num_conector != num_conector) ) //Buscamos el conector con "num_conector" en el arreglo. | ||
+ | i++; | ||
+ | if (i< num_modules) //El conector con "num_conector" no es el ultimo. | ||
+ | { | ||
+ | //Hacemos el intercambio, dejando en la posicion i, al conector que se encontraba en la ultima posicion (num_modules). | ||
+ | strcpy (handler[i].nombre, handler[num_modules].nombre); | ||
+ | handler[i].funcion = handler[num_modules].funcion; | ||
+ | handler[i].num_conector = handler[num_modules].num_conector; | ||
+ | } | ||
+ | num_modules--; | ||
+ | |||
+ | } | ||
</source> | </source> | ||
Revisión del 09:35 14 dic 2011
Contenido
Integrantes:
- Juan La Cruz
- Sofía Maiolo
- Mathias Battistella
Tema elegido:
Firmware + Software : soporte HotPlug.
Objetivos:
Que la actualización de los módulos de usuario y drivers del Butiá sea "on the fly" es decir, dinámico. Se desea que durante la ejecución del Bobot-Server, podamos conectar y tener disponible para su uso sensores o actuadores.
Desarrollo del problema :
Se detalla a continuación un breve resumen de las etapas por las que pasó nuestro trabajo:
- En primer lugar modificamos el código del módulo butia, incluido en el archivo modulos.pde, para incluir una nueva operación que actualice los dispositivos conectados al Butiá. Esta nueva operacion consta de un for, donde se recorren los conectores, revisando su estado. Anexamos el código añadido
for (k=0; k<NUM_CONNECTORS; k++)
{
if (conector[k].get_type() != 0)
{add_module(k) };
}
- Al anexar esta nueva operación, debemos modificar también los drivers, incluidos en la carpeta bobot. Cambiamos, en particular, el archivo butia.lua, para poder invocar a la nueva función, que llamamos get_hot_plug. Incluimos el código:
api.hot_plug = {}
api.hot_plug.parameters = {} -- no se envian parámetros
api.hot_plug.returns = {} --nos devuelve el estado de los conectores
api.hot_plug.call = function ()
device:send(HOT_PLUG) --envío el código de operación
end
- Luego de realizar varias pruebas (detalladas en la próxima sesión) decidimos cambiar el enfoque y optamos por quitar el FOR agregado inicialmente en el módulo butiá. Lo sustituimos por el siguiente código incluido en el archivo butia_firmware_mega_0_2.pde:
if (time_act-time_last2 >= 5000) { // cada 20ms llamamos a la sample(). Ojo porque esto afecta al "cuentapasos"
// explora los conectores
for (byte f=0; f<NUM_CONNECTORS; f++) {
byte tipoOld = conector[f].get_type();
byte subtipoOld = conector[f].get_subtype();
conector[f].update_config ();
// conecte algo donde no habia nada, o cambie lo que estaba conectado
if (conector[f].get_type() != 0 &&
(conector[f].get_type() != tipoOld || conector[f].get_subtype() != subtipoOld))
{
//primero borrar el viejo en la lista de handlers si es que
//el viejo no era el tipo 0 (el caso q no hay nada)
add_module(f);
}else if (conector[f].get_type() == 0 && //desconecte algo
(conector[f].get_type() != tipoOld || conector[f].get_subtype() != subtipoOld))){
//borrar el modulo que se acaba de desconectar
} // si hay algo en el conector, agrega 1 módulo PnP para él
}
time_last2 = time_act;
}
Este código realiza las siguientes acciones:
1)Recorremos los conectores, y guardamos su tipo y sub-tipo anteriores.
2)Si no había un conector en la lista de handlers y además, los tipos y sub-tipos son distintos, agregamos el conector llamando a add_module(f); de PnP.pde
3)Sino, debemos borrar del handler el módulo que acabamos de desconectar. Debemos implementar esta función, a la que llamaremos remove_module.
- Para implementar remove_module, exploramos el handler, buscando el módulo a borrar y lo sustituimos por el módulo que se encuentra en la última posición ocupada del handler. Actualizamos, también, la cantidad de módulos. Incluimos la primera versión de nuestro código:
void remove_module (byte num_conector) {
int i=8; //Comenzamos a recorrer desde el 8 ya que desde el 8 se comienzan a agregar los nuevos conectores.
while ( (i< num_modules) && (handler[i].num_conector != num_conector) ) //Buscamos el conector con "num_conector" en el arreglo.
i++;
if (i< num_modules) //El conector con "num_conector" no es el ultimo.
{
//Hacemos el intercambio, dejando en la posicion i, al conector que se encontraba en la ultima posicion (num_modules).
strcpy (handler[i].nombre, handler[num_modules].nombre);
handler[i].funcion = handler[num_modules].funcion;
handler[i].num_conector = handler[num_modules].num_conector;
}
num_modules--;
}
Pruebas realizadas:
- Ahora estamos probando nuestra implementación conectando un boton y un sensor de distancia. Hacemos un LIST y los reconoce bien.
Los desconectamos, llamamos a nuestra operación y al INIT. Sin embargo, al usar el comando LIST, los sensores y el botón siguen apareciendo, lo cual nos hace pensar que la placa no fue reseteada
Probando y consultando con docentes, nos dimos cuenta de que faltaba actualizar el tipo de los conectores, antes de hacer la recorrida en el for. Para ello, usamos una función implementada en conector.cpp, llamada update_config ().
Incluimos el código de dicha función.
void Conector::update_config () {
byte id = digitalRead (pin_id0) + 2*digitalRead (pin_id1);
switch (id) {
case 3: // NADA
pinMode (pin_dig0, INPUT);
pinMode (pin_dig1, INPUT);
type = 0;
subtype = 0;
break;
case 2: // sensor analógico
pinMode (pin_dig0, INPUT);
pinMode (pin_dig1, INPUT);
digitalWrite (pin_dig0, HIGH); // activa los pull-ups
digitalWrite (pin_dig1, HIGH); // activa los pull-ups
type = 1;
subtype = digitalRead (pin_dig0) + 2*digitalRead (pin_dig1);
break;
case 1: // sensor analógico c/pin de control
pinMode (pin_dig0, OUTPUT);
pinMode (pin_dig1, INPUT);
digitalWrite (pin_dig1, HIGH); // activa los pull-ups
type = 2;
subtype = digitalRead (pin_dig1);
break;
case 0: // sensor o actuador digital
{
int analog_id = analogRead (pin_analog);
byte i;
for (i=0; i<NUM_VALORES; i++) {
if (abs(analog_id-values[i]) <= TOLERANCIA) {break;}
}
switch (i) {
case 0: case 1: case 2: case 3: case 4:
pinMode (pin_dig0, INPUT);
pinMode (pin_dig1, INPUT);
type = 3; // sensor digital
subtype = i;
break;
case 5: case 6: case 7: case 8:
pinMode (pin_dig0, OUTPUT);
pinMode (pin_dig1, INPUT);
type = 4;
subtype = i-5;
break;
case 9: case 10: case 11: case 12:
pinMode (pin_dig0, OUTPUT);
pinMode (pin_dig1, OUTPUT);
type = 5; // sensor digital c/pin de control
subtype = i-9;
break;
case NUM_VALORES: // si la red de resistencias no coincide con ningun valor, se deja en modo manual
pinMode (pin_dig0, INPUT);
pinMode (pin_dig1, INPUT);
type = 0;
subtype = 0;
break;
}
}
}