TODOPIC
Microcontroladores PIC => dsPIC => Mensaje iniciado por: CheKeBo en 18 de Septiembre de 2007, 13:19:22
-
Hola a todos.
Estoy intentando modificar el BootLoader de Ingenia para hacer lo siguiente:
1.- Que no necesite iniciarse nada mas conectarse el dsPIC, ya que por ejemplo, mi aplicación funciona por USB y necesito que una vez esta en marcha funcione siempre.
2.- Que pueda llamarlo en el momento que yo quiera pasandole el control con un comando por el USB
3.- Que funcione, obviamente ;-)
He conseguido lo primero, lo segundo pero....
Tengo un problema al pasarle los datos. Soy capaz de mandarle comandos al bootloader y saber que versión ejecuta, que escriba comandos, etc.
Como estoy programando mi propio software en el PC (delphi) para que funcione a traves del usb, cuando intento enviar el CRC me devuelve un NACK, he sido incapaz de descifrar como se calcula el CRC, en teoria es la suma de todos los datos, lo pasas a HEX y te quedas con la parte baja de la palabra, o lo que es lo mismo. "suma(datos)-(ABS(Suma(datos)/256)*256))"
El problema es que no me reconoce ese CRC y no consigo que grabe la información.
La pregunta del millón.
¿Alguien sabe como interpreta el Bootloader de INGENIA el archivo .HEX (INTEL HEX32) y que transformación hace de este para que funcione?
Se interpretar el HEX, pero no se si debo enviarlo tal cual al bootloader o tengo que montar los datos de otra forma diferente. He probado todo lo que se me ocurre, pero nada de nada.
Ahi os dejo el reto.
Un saludo a tod@s.
CheKeBo.
-
Lo que estas haciendo no es un CRC, si no un CheckSum que es distinto. Hay un post que habla de como calcular el CRC y es bastante más complicado que CheckSum.
Un saludo
-
¿Puedes pegar aquí el trozo de código del bootloader donde se hacen los cálculos para echar un vistazo?
-
Hola Nocturno, esta es la parte del codigo que recibo los datos del bootloader de INGENIA
WriteMemCmd:
clr W4 ; Reset W4 = Checkbyte
rcall ReceiveChar ; Receive high byte of the initial address
mov W0, TBLPAG ; For latch loading and programming
mov W0, NVMADRU ; For erase cycle - in program are written auto. from TBLPAG
rcall ReceiveChar ; Receive medium byte of the initial address
mov.b WREG, NVMADR + 1
rcall ReceiveChar ; Receive low byte of the initial address
mov.b WREG, NVMADR
rcall ReceiveChar ; Receive the number of bytes to be received
mov W0, W3
mov #recBuf, W2 ; W2 = recBuf
FillBufLoop:
rcall ReceiveChar
mov.b W0, [W2++] ; Move received byte to recBuf
dec W3, W3
bra nz, FillBufLoop ; Fill reception buffer
cp0.b W4 ; Check (INTEL HEX8 Checksum - Sum modulo 256)
bra nz, SendNack ; if Checkbyte != 0 jump to SendNack
.
.
. Aqui va el codigo que escribe las paginas de memoria
.
;******************************************************************************
ReceiveChar:
mov #0xFFFF, W10 ; W10 = 0xFFFF
MajorLChar:
setm W11 ; W11 = 0xFFFF
MinorLChar:
btsc U1STA, #URXDA ; Character received ?
bra EndReceiveChar ; Yes -> Jump to Finish reception
dec W11, W11 ; W1--
bra NZ, MinorLChar ; if W1 != 0 jump MinorLChar
dec W10, W10 ; W2--
bra NZ, MajorLChar ; if W2 != 0 jump MajorLChar
MOV #__SP_init, W15 ; Initialize Stack Pointer
bra SendNack ; Timeout aprox. = 0xFFFF * 0xFFFF * 5 clocks -> Jump to Send Nack
EndReceiveChar:
mov.b U1RXREG, WREG ; W0 = U1RXREG
add.b W4, W0, W4 ; Checkbyte += W0 -> Performs a Sum modulo 256 checksum (INTEL HEX8)
return
;******************************************************************************
No entiendo mucho de ensamblador, pero me parece que simplemente suma todos los bytes recibidos en el registro W4, luego compara la parte baja con algo, que no tengo muy claro que registro es y como es diferente salta a enviar un NACK (error). No estoy muy seguro de que el funcionamiento sea este, en teoria aunque ellos lo llaman CRC, realmente creo que es un checksum.
Hes estado mirando lo que comento nuestro amigo jfh900, pero lo veo muy complicado para el funcionamiento que creo que hace.
CheKeBo
-
Mi relación con el ASM se parece a la que tengo con los curas, así que mejor me he metido con el HEX a hacer un poco de ingeniería inversa y creo que he deducido cómo funciona.
Pongo una línea de un HEX como ejemplo:
:100200002f812000609f2000000188000000000076
Si la fragmentamos en bytes:
10 02 00 00 2f 81 20 00 60 9f 20 00 00 01 88 00 00 00 00 00 76
Sumamos todos los bytes menos el último, que es el checksum.
El resultado es 650, que en hexadecimal es 0x28A.
Nos quedamos con el byte menos significativo, o sea, 0x8A.
Y ahora vemos cuánto le falta para llegar a 0x100, o sea, a 256. O lo que es igual, se resta de 0x100:
0x100 - 0x8A = 256 - 138 = 118
Si representamos ese número en hexadecimal no da, casualmente: 0x76
Quizás lo he complicado demasiado. Resumiendo: el último byte es tal que la suma de toda la línea arroja un resultado cuyo byte menos significativo es 0x00
-
Mira que yo pensaba que había hecho todas las combinaciones posibles y no me salia. Ahora ya sabemos como se calcula ese dato, gracias nocturno, pero sigue sin funcionar. Creo que tiene algo que ver con que el formato HEX de los dsPIC es HEX32, en cada linea tenemos hasta 8 palabras de 32bits, es decir, la longitud de datos dividido por 2, ya que el HEX normal es de 16bits.
Quizas estoy diciendole que le envio 16 datos de 16 bits, por ejemplo, cuando en realidad le estoy enviando 8 de 32bits, es posible que la cantidad de datos que le digo que le envio sea en realidad esa cantidad dividido por dos. No se si me he explicado bien.
En todo caso mañana lo probaré, que hoy no me da tiempo.
Seguiré investigando, al final encontraré/mos la solución.
Gracias.
-
jejeje Manolo, lo puedes explicar más alto, pero no más claro. Bueno, para aportar mi granito de arena, aquí está la explicación entre los distintos formatos de Intel (8, 16 y 32), por cierto según los comentarios del programa, es INT 8 :
http://en.wikipedia.org/wiki/Intel_HEX
Un saludo
-
Chekebo, esa línea que he puesto de ejemplo es de un HEX de un dsPIC.
Jesús, ¡ya podías haber avisado antes, hombre! :D
-
Hola Chekebo, el dspic está recibiendo el .hex por usb, quiere decir que tu aplicación está corriendo y tu programa se está ejecutando, pero ese .hex que le envias es un programa que se escribirá en la memoria de programa del dspic cuando llames al bootloader, no estarás modificando tu programa al recibir el .hex?
El programa bootloader se encuentra en las últimas posiciones de la memoria de programa y cuando recibe un nuevo .hex lo coloca en las primeras posiciones donde está tu programa corriendo, supongo que hay se debe estar alterando.
Si solo le quieres enviar datos al dspic no necesitas el bootloader, puedes hacerlo usando el PSV o usando acceso a tablas.
-
Hola de nuevo,
En la nota de aplicacion AN1094 (http://ww1.microchip.com/downloads/en/AppNotes/01094a.pdf) de Microchip, en el Apendice B, dice que el MPLAB ( lo que yo uso) trabaja con Intel HEX32 Format (INHX32).
Busque por la red como funcionaba este formato y conseguí descifrarlo (a excepción de lo que me ha explicado nocturno) en este post.
El problema que tengo ahora : No se como tengo que enviar los datos del PC al dsPIC y que el bootloader de ingenia los reconozca y los grabe.
Según el datasheet (http://www.ingenia-cat.com/reference/pdf/iBL.UG.EN.pdf) de ingenia, en la pagina 9 dice como tienes que enviarle los datoa:
- 0x02 : comando (8 bits)
- Address H (8 bits)
- Address M (8 bits)
- Address L (8 bits)
- Número de bytes (8 bits)
- N bytes (8 bits)
- CRC (8 bits) <---- aqui tengo el problema.
Según dicen ellos textualmente : "The frame ends with a CRC that is computed as the 256 module of all the data value addition"
Mi ingles no es muy bueno, pero creo entender que debo sumar el valor de todos los datos (solo los datos) y luego hacer el modulo 256 (esto no lo tengo claro) y creo que es lo que ha explicado antes nuestro amigo nocturno.
Al principio hice los siguiente, sumar el valor de todos los datos (resultado 24 bits / 32 bits) y quedarme con la parte baja. No funciona.
Luego he probado a hacer lo que ha comentado Nocturno, tampoco funciona.
Sigue devolviendo un NACK (error en el CRC)
Los datos del HEX ya los he sacado e interpretado, ahora los quiero enviar por USB/Ethernet o lo que sea, ya que mi intención es que funcione por donde queramos, con solo poner un chip a la salida de la uart del dsPIC que transforme la señal a usb o ethernet (esta parte la tengo y funciona a la perfección).
¿La pregunta: Como debo enviarle los datos al bootloader de INGENIA?
Lo que yo creo:
Datos del .HEX
(aprovechando el ejemplo de nocturno)
:100200002f812000609f2000000188000000000076
Cadena al bootloader: (hexadecimal) según el datasheet de INGENIA
02 00 02 00 10 00 2f 81 20 00 60 96 20 00 00 01 88 00 00 00 00 76
Resultado del envio (recepción de NACK)
Creo que me he explicado
Gracias a todos por vuestros esfuerzos
-
Gracias Renatox por tu aportación.
El programa del bootloader lo he modificado para que se grabe en la primera posición de memoria (0x100) del dsPIC6012A, ocupa hasta la posición si no recuerdo mal 0x0244. El programa que quiero grabar lo he configurado para que empiece en la posición 0x248, he revisado los .hex manualmente (para ser verdad he hecho un archivo excel que lo calcula por mi) y todo esta bien, estoy seguro que no se machacan las posiciones de memoria.
Lo que necesito es poder actualizar el firmware de mi aplicación, que puede estar trabajando en lugares poco accesibles, como tejados..., entonces, he hecho un circuito con el que puedo trabajar tanto con usb como con ethernet, pero no con puerto serie, ya que cada vez esta mas en desuso, de hecho ya ningún ordenador portatil lo incorpora de serie.
Un saludo
-
Y cuando llegas con USB o Ethernet, ¿cómo le entras al dsPIC?, ¿no conviertes a serie?
-
Puedes poner el datasheet de Ingenia?, para echarle un vistazo.
Un saludo
-
Hola nocturno, si no lo he hecho mal el datasheet esta puesto con un enlace en el post anterior, así como la nota de aplicación de microchip. de todas formas las pongo de nuevo:
- datasheet : http://www.ingenia-cat.com/reference/pdf/iBL.UG.EN.pdf
- AN1094 : http://ww1.microchip.com/downloads/en/AppNotes/01094a.pdf
Un saludo
CheKeBo
-
Hola de nuevo nocturno, respecto a tu pregunta de como le entro despues...
Si, convierto de usb/ethernet a serie, entonces no tengo problemas, ya que para el dspic es totalmente transparente. Llevo años trabajando con el USB de este modo y no he tenido nunca problemas. Con el ethernet me he puesto este año y tambien me funciona a la perfección.
Por si a alguien le interesa, yo utilizo para el usb un chip de la casa FTDIchip que se llama FT232BM, en su web hay mucha documentación, drivers para todos los windows, ademas de estar cifrados por microsoft, etc...
Para el etehrent utilizo un modulo, que no es muy barato, de la casa TIBBO, modelo EM100, tambien tienen mucha documentación, ejemplos y software de configuración, aunque se puede hacver todo desde la propia aplicación del dsPIC, aunque es mas facil programarse algo desde el PC.
Un saludo
CheKeBo
-
Está claro que el fallo lo tienes en la secuencia que le envias. Podrias poner esta parte del código?. ¿Has probado a utilizar el software de Ingenia para enviarle las tramas?. Por ciertos las tramas las estaras enviando en ASCII ¿verdad?.
Un saludo
-
La verdad es que le estoy enviando los datos transformados de hex a decimal, es decir cojo por ejemplo FA y lo traduzco a decimal (250) y este dato es el que envio al dspic mediante el usb.
No puedo usar el software de ingenia, ya que solo funciona por rs-232 y yo solo dispongo de usb o ethernet, así que esta descartado, tengo que programarlo yo mismo. Estoy utilizando DELPHI y la transformación de hex a dec la hago correctamente, este comprobado.
-
Por si a alguien le interesa, yo utilizo para el usb un chip de la casa FTDIchip que se llama FT232BM
Entonces no cambia nada , se traduce todo a RS232 .
Deverias fijarte como lo hace Ingenia si hay fuentes y tu hacer exactamente lo mismo en tu programa en delphi .
tampoco implementar la las funciones de auto grabacion en el dspic no cuesta mucho , quizas te saldria a cuenta rehacerlo todo y a tu gusto .
busco las funcines que son y las pego aqui (vete a saver ande andaran :( ... buscando).
-
Tienes que enviar los datos en hexadecimal y ascii, osea FF se enviaria como los caracteres "FF" ya que es lo que espera encontrar el programa. Los ficheros .hex son ficheros de texto plano y tu lo has de enviar igual.
Un saludo
-
Hola a todos,
me he estado rompiendo los cuernos con esto, y como bien dice ese dicho castellano "lo que hay que trabajar por no trabajar" he decidido programarlo por mismo. Despues de leer y reeler me veo capaz de afrontarlo.
Así que, muchas gracias por vuestra colaboración, con un poco de suerte en unos días lo tengo hecho. En cuanto tenga algo claro o si necesito vuestra ayuda lo iré colgando en este post.
Un saludo
CheKeBo
-
A mí me pasó lo mismo con un bootloader que tuve que programar; me harté de buscar versiones y adaptarlas, para al final terminar escribiendo uno entero.
Ya verás cómo te diviertes. Suerte.