hola amis:
para mi invento he hecho unos comandos, los envio por consola, y el ardu los interpreta y ejecuta.
la 1ª idea fue una cascadas de:
if(bufer_entrada =="ORDEN1"){ orden1(); }
,,,, con todas las ordenes,
esto me ahorraria mucho tiempo, pero no memoria ni me parece elegante.
2ª idea: una tabla de saltos. con una compacta rutina de comparacion,
void (*pf[ordenes_top])(void) = {//ESTA ES LA TABLA DE SALTOS
_in_OFF, //MANTENER SINCRONIZADOS LOS SALTOS CON CADENAS DE COMPARACION, (EN .H)
_in_ON,
_in_AUTO_T,
_in_AUTO_N,
} //hay otras 40 mas
char ordenes[][ordenes_top]= {//MANTENER SINCRONIZADOS LAS CADENAS DE COMPARACION, CON TABLA DE SALTOS
//CONTROL ACCION
"OFF", //stop, unica permitida en ejecucion
"ON", //reset y pone a ejecutar
//DEFINIR ACCION
"AUTO T=", //"AUTO T=ho:mi:se" def. t entre vendimias, MIN 3seg
"AUTO N=", //"AUTO N=12" define numero de vendimias, de 00 a 99
}
,,, ordenes[k][in_ptr] //k es el numero de orden, in_ptr es el puntero del interprete a la letra a comparar
,,, pfk; //ESTE ES EL SALTO DE LA TABLA DE SALTOS
la cosa funciona bien en el prototipo de 4 ordenes, con las 40 peta el UNO, no el MEGA, por lo que supongo que agota memoria
3º idea, meter las cadenas de comparacion en memoria de programa, creo que era (por algun rar lo tendre,,,)
PROGMEM void (*pf[ordenes_top])(void) = {,,,,
y el caracter se leia con un pgm_read_byte( ordenes[k][in_ptr]);
4º idea, como hay que tener sincronizadas la tabla de saltos y de comparaciones, y son dos separadas, pense que seria mejor agruparlas en una estructura:
typedef void (*fptr) (void); //luego cuento esto
PROGMEM struct {
void (*pf)(void); //salta a una funcion generica
char ordenes[10]; //string de orden generica MAX 9 caract, mejor 8
}tabsal[ordenes_top] = { //tabla de saltos [numero de ordenes, definido en .h]
_in_off, "off", //salto a of(); , y su orden
_in_on, "on", //salto a on(); y su orden
_in_auto_t, "auto t=",
_in_auto_n, "auto n=",
};
mem = tabsal[k].ordenes; //mem lleva la direcion donde empieza la orden[k]
bucle(){,,,,,
in_k=pgm_read_byte(mem); //lee de memo prog
mem++;
el interprete funciona perfecto. el problema viene cuando ha de saltar. que siempre me saluda tras reset.
antes sin progmem con un pfk; arreglado. pero ahora hay que leer el salto de la progmem al igual que los caracteres de comparacion.
buceando por google di con uno que tenia problema con esto al migrar a atmegas grandes.
segun deduje tengo que poner
f = (fptr)pgm_read_word(tabsal[k].pf);
f();
por eso el typedef void (*fptr) (void); antes de la estructura
parece que carga la direcion de salto a otra funcion generica normal, y salta a traves de ella.
ayer y hoy me pase el dia estudiando el tema, no hay manera,
en tools\avr\bin hay un aladino que uso como consola,
tel temporal donde trabaja el ardu copio alli el .elf
escribo avr-objdump -h -S demo.elf > demo.lst
y me aparece un .lst que es desensamblado
PERDON CONFUNDI ENTRE VARIOS DESENSAMBLADOS QUE TENIA, ESTA MEJOR DE LO QUE CREIA.
000008f6 <tabsal>:
8f6: b2 04 6f 66 66 00 00 00 00 00 00 00 b4 08 6f 6e ..off.........on
...
90e: f9 07 61 75 74 6f 20 74 3d 00 00 00 eb 07 61 75 ..auto t=.....au
91e: 74 6f 20 6e 3d 00 00 00 to n=...
00000926 <__ctors_end>:
HAY ESTA MI TABLA DE SALTOS
segun esto empieza en 08f6, con su salto a 04b2 y su off sobre 10 caract, salto a 08B4 y su on, 07F9 y su auto t=, 07EB auto n=
f = (fptr)pgm_read_word(tabsal[1].pf);
fbe: 84 eb ldi r24, 0xB4 ; 180
fc0: 98 e0 ldi r25, 0x08 ; 8
fc2: fc 01 movw r30, r24
fc4: 25 91 lpm r18, Z+
fc6: 34 91 lpm r19, Z+
f();
fc8: f9 01 movw r30, r18
fca: 09 95 icall
_interprete_fin:
esto el desemsamblado del salto, observese que no es a una K generica, sino que la cambie a 1 para simplificar el codigo.
segun esto el salto a orden [1], que es "on", esta en 08b4
segun mis cuentas esta en 0902, ¿NO?, donde dice él cae en mitad de la parrafada de la orden help.
00000964 <_Z7_in_offv>:
00001168 <_Z6_in_onv>:
00000fd6 <_Z10_in_auto_nv>
00000ff2 <_Z10_in_auto_tv>:
y estas son la direciones donde estan las rutinas
que son el doble de lo que pone en la tabsal, puede ser.
una de mis ordenes estandar es PEEK, me fue util variarla para que me dijese que numerito devuelve pgm_read_word(tabsal[k].pf)
lo dificil, que aun no controlo, es interpretar el tipo,
unsigned int addr;
addr = (fptr)pgm_read_word(tabsal[1].pf); invalid conversion from 'void ()()' to 'unsigned int'
addr = pgm_read_word(tabsal[1].pf); compila sin problema
addr =tabsal[1].pf; invalid conversion from 'void ()()' to 'unsigned int'
addr =(int)tabsal[1].pf; compila sin problema
ya no recuerdo y las tengo desmontadas ahora, pero cuando no daban siempre ffff, daban unos numeros rarisimos por disparatados, siempre los mismos para cada orden.
EDITADO: SOLUCIONADO
faltaba el & dolar, como explican PROGMEM - Arduino Reference
f = (fptr)pgm_read_word(&(tabsal[1].pf));
fbe: 82 e0 ldi r24, 0x02 ; 2
fc0: 99 e0 ldi r25, 0x09 ; 9
fc2: fc 01 movw r30, r24
fc4: 25 91 lpm r18, Z+
fc6: 34 91 lpm r19, Z+
f();
fc8: f9 01 movw r30, r18
fca: 09 95 icall
ahora ya apunta a 0902