Optimizando el código del Receptor GPS de Parallax

8
Optimizando el código del receptor GPS de Parallax 1/8 Optimizando el código del Receptor GPS de Parallax Por Héctor García Hace no mucho tiempo, Parallax, en asociación con Grand Idea Studio tuvieron la brillante idea de producir un módulo receptor de GPS controlado por un microcontrolador de la serie SX. Lo maravilloso de ésta unión fue, que decidieron dejar el micro libre para ser programado, y publicaron el código hecho en SXB bajo licencia open-source. http://www.parallax.com/Store/Sensors/CompassGPS/tabid/173/CategoryID/48/List/0/Le vel/a/ProductID/396/Default.aspx?SortField=ProductName%2cProductName No ha faltado quien, por experimentación o por necesidad se han dado a la tarea de cambiar y adaptar el código a diferentes situaciones. Uno de éstos trabajos, y quizás el más documentado, es el que publicó Jon Williams en la revista Nuts & Volts del mes de Noviembre de 2006, “139, Hacking The Parallax GPS Module”. http://www.parallax.com/dl/docs/cols/nv/vol7/col/NV139.pdf Donde explica las modificaciones realizadas, y el esquema eléctrico del módulo donde se pueden apreciar los pines en la tarjeta del módulo usados para programar el SX, usando cualquiera de las dos herramientas existentes para la serie: el SX-Key, o su primo SX- Blitz, sin capacidades de depuración “ICD”. Pues bien, en ésta ocasión tenemos otra modificación a dicho código, siendo mi primera experiencia con Parallax, y en respuesta a la necesidad de conectar el susodicho módulo a un módem GPRS. Se usó un programador SX/Blitz, conectado a los pines de Fig.1. Pines de Programación del Módulo GPS.

description

Consigue ganar memoria disponible optimizando el código de programa del dispositivo. Autor: Héctor García.

Transcript of Optimizando el código del Receptor GPS de Parallax

Page 1: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

1/8

Optimizando el código del Receptor GPS de Parallax

Por Héctor García

Hace no mucho tiempo, Parallax, en asociación con Grand Idea Studio tuvieron la brillante idea de producir un módulo receptor de GPS controlado por un microcontrolador de la serie SX. Lo maravilloso de ésta unión fue, que decidieron dejar el micro libre para ser programado, y publicaron el código hecho en SXB bajo licencia open-source. http://www.parallax.com/Store/Sensors/CompassGPS/tabid/173/CategoryID/48/List/0/Level/a/ProductID/396/Default.aspx?SortField=ProductName%2cProductName No ha faltado quien, por experimentación o por necesidad se han dado a la tarea de cambiar y adaptar el código a diferentes situaciones. Uno de éstos trabajos, y quizás el más documentado, es el que publicó Jon Williams en la revista Nuts & Volts del mes de Noviembre de 2006, “139, Hacking The Parallax GPS Module”. http://www.parallax.com/dl/docs/cols/nv/vol7/col/NV139.pdf Donde explica las modificaciones realizadas, y el esquema eléctrico del módulo donde se pueden apreciar los pines en la tarjeta del módulo usados para programar el SX, usando cualquiera de las dos herramientas existentes para la serie: el SX-Key, o su primo SX-Blitz, sin capacidades de depuración “ICD”.

Pues bien, en ésta ocasión tenemos otra modificación a dicho código, siendo mi primera experiencia con Parallax, y en respuesta a la necesidad de conectar el susodicho módulo a un módem GPRS. Se usó un programador SX/Blitz, conectado a los pines de

Fig.1. Pines de Programación del Módulo GPS.

Page 2: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

2/8

programación mediante 4 pines tipo Jumper soldados a ellos. Y programando el código con el SX-Key IDE ver. 3.2.3 (SX 1.51.03), provisto por Parallax.

El micro integrado en el modulo es el SX20AC/SS-G, con memoria limitada a 2k. El código del módulo deja libres 119 words o bytes de memoria para instrucciones adicionales. Dado que los módem GPRS requieren una serie de instrucciones para establecer una conexión, son necesarios aproximadamente 150 bytes para almacenar los caracteres ASCII requeridos, así como las instrucciones y temporizadores necesarios para enviar dichas cadenas de configuración. Claramente, este requerimiento extralimita la memoria libre disponible en el SX. El primer paso es, averiguar la cantidad de memoria que tenemos disponible. La mejor forma de hacerlo es con un pequeño truco, usando la instrucción NOP (No Operation), que ocupa un solo byte, se ejecuta en un solo ciclo y no tiene otro efecto sobre la programación. Se colocan, dentro de cualquier rutina, una serie de NOP’s y se compila el código, incrementando el numero de instrucciones NOP, hasta que se genere un error de desbordamiento de memoria.

Fig. 2 El módulo GPS visto por detrás, con los pines soldados y el SX/Blitz conectado.

Fig.3 Error de desbordamiento en SX-Key IDE.

Page 3: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

3/8

Paso seguido se elimina una a una las instrucciones NOP hasta que la compilación no marque error. El número de instrucciones contadas será el espacio libre que tenemos en memoria. Ahora que sabemos el espacio disponible, comencemos con la optimización del código. Si leemos el código completo, notaremos que existen, en la mayoría de las subrutinas GPS (Get_Valid, Get_Time, Get_Date, Get_Lat, Get_Long, Get_Speed y Get_Head), llamadas a la rutina WAIT_FOR_GPS, para filtrar todas las cadenas del módulo GPS que contengan en el inicio las letras “GPRMC”. También notaremos que, en las otras rutinas (Get_Sats y Get_Alt) existe la misma llamada para filtrar las cadenas que contienen “GPGGA”. Veamos el resultado de dichas llamadas en memoria. En la figura 4, vemos las 5 llamadas a WAIT_FOR_GPS en SX/B, para filtrar las cadenas que contienen la subcadena “GPRMC”; el ejemplo corresponde a la subrutina Get_Long.

En la figura 5, vemos el mismo código ASM, generado por el ensamblador SASM del SX-Key IDE.

Fig. 4 Llamadas de espera en SXB

Fig. 4 Llamadas de espera en ASM

Page 4: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

4/8

A simple vista podemos deducir que se crean 2 instrucciones por cada literal, de las cuales MOV fr, #literal, ocupa 2 words y 2 ciclos; y CALL addr8, ocupa 1 Word y 3 ciclos. Tenemos –Según mis cálculos- 15 words de instrucción + 5 bytes de literales en cada subrutina que llama a la misma validación. En 7 subrutinas se están usando 140 words para la misma validación + 40 words correspondientes a la validación de la cadena “GPGGA”. Solución Una subrutina (declaración SUB) se compila en sólo una parte del código, permitiendo que pueda ser llamada desde cualquier otra parte del mismo código, apuntando a la dirección de memoria correspondiente a la SUB. El mismo comportamiento ocurre con una tabla de datos, y en las condiciones adecuadas, se puede pasar su puntero a una SUB, a fin de que ésta subrutina lea los datos directamente de la tabla en forma secuencial y los procese, hasta que se cumpla una condición establecida por el programador –Esos somos nosotros-. Así, de nuevo recurrimos a Jon Williams, ésta vez al documento titulado “SX/B Syntax Reference Manual”. http://forums.parallax.com/forums/attach.aspx?a=14085 Allí encontramos la siguiente subrutina: ' --------------------------------------------------------------------- ' Use: TX_STR [string | label] ' -- "string" is an embedded string constant ' -- "label" is DATA statement label for stored z-String SUB TX_STR tmpW1 = __WPARAM12 ' get offset/base DO READ tmpW1, char ' read a character IF char = 0 THEN EXIT ' if 0, string complete TX_BYTE char ' send character INC tmpW1 ' point to next character LOOP ENDSUB Su declaración es: TX_STR SUB 2 ' strings use two parameters Ésta rutina, espera 2 parámetros; veamos: En todos los lenguajes de programación que he conocido - los llamados de “Alto nivel”, como Basic o C, cuyos códigos tienen que ser convertidos en ASM antes de ser compilados- el manejo de cadenas entre procedimientos es, en realidad un paso de

Page 5: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

5/8

punteros; nunca se pasa la cadena completa, sólo se pasa la dirección de memoria donde está alojada dicha cadena. Así, el primer parámetro que recibe ésta subrutina es el puntero a la cadena de caracteres. El segundo parámetro será un “Offset” o posición del caracter dentro de la cadena referida. La llamada a la subrutina TX_STR sólo incluirá el nombre de la tabla de caracteres o, directamente una cadena de más de un carácter. EL SXB se encargará del puntero y el Offset comentados. La operación de TX_STR consiste en, recibir el parámetro de cadena/tabla de datos en tmpW, mediante un ciclo, leer cada carácter en la variable char y enviarlo por RS232 usando la rutina TX_BYTE, hasta que se encuentre un carácter 0 en la cadena. De esta manera, cuando se declara la tabla de datos, será necesario terminarla con un 0, a fin de cumplir la condición. Cuando se pasa sólo la cadena como parámetro, el compilador SXB se encargará de agregar el código 0 al final de dicha cadena. Nuestra rutina de validación será muy similar a TX_STR, pero en lugar de llamar a TX_BYTE, llamaremos a la rutina de validación de un solo caracter WAIT_FOR_GPS para reutilizar los recursos disponibles. Declaración de la subrutina: EsperaGPS SUB 2 Declaración de la variable tmpW1: tmpW1 VAR Word

Page 6: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

6/8

Subrutina: ' ---------------------------------------------------- ' Espera hasta la recepción de la cadena especificada, ' la cadena debe de definirse en una tabla (DATA) y terminar con un 0 ' Ejemplo : ' Cadena: ' DATA "Cadena", 0 ' Ejemplo de llamada ' EsperaGPS Cadena SUB EsperaGPS tmpW1 = __WPARAM12 DO READ tmpW1, temp3 IF temp3 = 0 THEN EXIT WAIT_FOR_GPS temp3 INC tmpW1 LOOP RETURN Ahora podremos definir las dos tablas de datos usadas en la validación, recordando terminarlas con un carácter 0: GPRMC: DATA "GPRMC", 0 GPGGA: DATA "GPGGA", 0 Y la llamada a la subrutina de validación quedará: Para las validaciones de “GPGGA”: Get_Sats: ' command = $02 EsperaGPS GPGGA Para las validaciones de “GPRMC”: Get_Long: ' command = $06 ' wait for $GPRMC header from GPS module EsperaGPS GPRMC Veamos los resultados en ASM: En la Fig. 5 vemos el código de la validación en ASM, dentro de la rutina Get_Long, donde podemos notar , que ensamblan 3 instrucciones por la validación de la cadena completa, también notamos que se pasan (mediante ennmascarado de bits) el puntero y Offset de la tabla de datos en la direccion de memoria #GPRMC. El peso de las llamadas es de 5 words, la tercera parte de lo que representa el código original.

Page 7: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

7/8

En la Fig.6 Vemos la declaración de tmpW1 en ASM. Donde se observa la división de la variable en _LSB y _MSB, correspondientes a los bytes bajo y alto que ocupa dicha variable.

En la Fig. 7 la subrutina EsperaGPS, con el manejo de los dos parámetros, el ciclo de lectura a memoria (IREAD) y la llamada a @__WAIT_FOR_GPS por cada carácter.

Fig.5 El resultado ASM de la validación optimizada

Fig.6. La variable de dos bytes tmpW1, en ASM.

Fig.7. La rutina EsperaGPS en ASM.

Page 8: Optimizando el código del Receptor GPS de Parallax

Optimizando el código del receptor GPS de Parallax

8/8

El Resultado Después del cambio en el código, contamos el numero de NOP adicionales que nos permite agregar sin que se dispare el error de desbordamiento. En total, 207 NOP, lo que quiere decir que con nuestro código liberamos 88 words de memoria. 207 words libres nos permitirán hacer del módulo GPS un dispositivo robusto y adaptado a nuestras posibilidades (dentro de sus propias capacidades, claro). Conclusiones Dejemos las conclusiones a tu propio criterio, yo solo agregaré el siguiente comentario: En programación, el reciclaje tiene gran importancia, cuando este reciclaje va mas alla del “copy and paste”, modificando los códigos para mejorarlos. Las subrutinas, nos permiten reutilizar código, liberando valiosa memoria y recursos de nuestra aplicación final. GOTO y GOSUB también representan un detalle adicional en el uso de recursos, y ya son instrucciones obsoletas. Actualmente es más recomendable el uso de declaraciones SUB…RETURN para las subrutinas. Dejo la optimización de éstos códigos a criterio del lector. Agradecimientos. El mérito de éste artículo no es mío, yo solamente expresé el conocimiento en éstas líneas.

• A Parallax Inc., a Grand Idea Studio y a Joe Grand, de Grand Idea Studio, por haber diseñado el módulo GPS, y especialmente por haber liberado su código bajo el esquema open-source.

• A Jon Williams, de Parallax, por la excelente documentación sobre SXB, su

Articulo en Nuts & Volts que sirvió de disparador para hacer ésta prueba, y a su paciente y sabio consejo en los foros de Parallax, sin el cual no habría llegado al resultado obtenido.

• A Arístides Vega http://www.microsparallax.com.ar y administrador del foro

oficial de Parallax en Español http://espanol.groups.yahoo.com/group/ParallaxenEspanol ) y a Lorenzo M. Oliver ( http://www.todomicrostamp.com ), por su gran espíritu de colaboración, y su desinteresada dedicación a promover el uso las tecnologías Parallax en la comunidad Hispana.

• A ti, estimado lector, por tu interés en estas líneas.

Héctor García, Diciembre de 2007.