TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: 5GTT en 18 de Febrero de 2007, 22:14:00
-
Hola, estoy otra vez a vueltas con el bootloader USB de microchip, me he basado en esta pagina :
http://pic18fusb.online.fr/wiki/wikka.php?wakka=UsbBootload
mi intencion es poder utilizarlo pero me gustaria hacer mis programas con CCS en vez de con C18. Con los ejemplo de C18 va perfecto, pero con CCS no lo consigo.
He intentado ya varias cosas, primeramente he hecho lo que comenta en este post cucaracha:
http://www.todopic.com.ar/foros/index.php?topic=5482.0
El comando #build(reset=0x1000, interrupt=0x1100) sirve para que el programa comience mas tarde y no machaque el bootloader, esto lo busque al leer este post, de alguien que lo consiguio con PBP
http://forum.microchip.com/printable.aspx?m=151137
Pero no funciona, me da errores y me machaca el bootloader.
He seguido buscando por el foro de CCS y me he topado con estos dos post, pero no consigo traducirlos completamente y no comprendo como consiguen el bootloader:
http://www.ccsinfo.com/forum/viewtopic.php?t=26705&highlight=bootloader+relocate
http://www.ccsinfo.com/forum/viewtopic.php?t=28210&highlight=usb+bootloader+microchip
Y es ahi donde os pido ayuda, o mejor aun, si alguien lo ha conseguido me podia hechar un poco de luz al asunto.
Muchas gracias a todos.
-
He leido la ayuda de Microchip y comenta que debo situar el reset en 0800 y las interrupciones en 0808. Esto es acorde con lo que decia el forero de Microchip que programaba en PBP, sin embargo metiendo esas direcciones de memoria en la sentencia #build consigo que inicie en 800, pero me acaba empezando el programa en 000.
Estoy usando este codigo simple, quiero alternar el color de un LED, simplemente para probar si funciona el bootloader o no:
#include <18f4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN,WRTB
#use delay (clock=20000000)
#build (reset=0x0800, interrupt=0x0808)
void main(void)
{
do{
output_low(PIN_B0);
delay_ms(200);
output_high(PIN_B0);
delay_ms(200);
}while(TRUE);
}
Utilizando las nuevas funionalidades de CCS, en las que te muestra tu codigo en ASM en pantalla, me encuentro con esto:
CCS PCH C Compiler, Version 4.023, 25097 19-feb-07 03:56
Filename: C:\Documents and Settings\Mariano\Escritorio\Prueba\Prueba.lst
ROM used: 86 bytes (0%)
Largest free fragment is 30716
RAM used: 5 (0%) at main() level
6 (0%) worst case
Stack: 1 locations
*
0800: GOTO 0026
....................
....................
.................... #include <18f4550.h>
.................... //////// Standard Header file for the PIC18F4550 device ////////////////
.................... #device PIC18F4550
.................... #list
....................
.................... #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN,WRTB
.................... #use delay (clock=20000000)
*
0000: CLRF FEA
0002: MOVLW 06
0004: MOVWF FE9
0006: MOVF FEF,W
0008: BZ 0024
000A: MOVLW 06
000C: MOVWF 01
000E: CLRF 00
0010: DECFSZ 00,F
0012: BRA 0010
0014: DECFSZ 01,F
0016: BRA 000E
0018: MOVLW 7B
001A: MOVWF 00
001C: DECFSZ 00,F
001E: BRA 001C
0020: DECFSZ FEF,F
0022: BRA 000A
0024: RETLW 00
....................
.................... #build (reset=0x0800, interrupt=0x0808)
....................
....................
.................... void main(void)
.................... {
0026: CLRF FF8
0028: BCF FD0.7
002A: CLRF FEA
002C: CLRF FE9
002E: MOVF FC1,W
0030: ANDLW C0
0032: IORLW 0F
0034: MOVWF FC1
0036: MOVLW 07
0038: MOVWF FB4
....................
.................... do{
.................... output_low(PIN_B0);
003A: BCF F93.0
003C: BCF F8A.0
.................... delay_ms(200);
003E: MOVLW C8
0040: MOVWF 06
0042: RCALL 0000
.................... output_high(PIN_B0);
0044: BCF F93.0
0046: BSF F8A.0
.................... delay_ms(200);
0048: MOVLW C8
004A: MOVWF 06
004C: RCALL 0000
.................... }while(TRUE);
.................... }
004E: BRA 003A
....................
0050: SLEEP
Configuration Fuses:
Word 1: 0E24 NOIESO NOFCMEN HSPLL PLL5 CPUDIV1 USBDIV
Word 2: 1E3E BROWNOUT NOWDT BORV20 PUT WDT32768 VREGEN
Word 3: 8100 NOPBADEN CCP2C1 MCLR NOLPT1OSC RESERVED
Word 4: 0081 STVREN NODEBUG NOLVP NOXINST NOICPRT RESERVED
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: A00F NOWRT NOWRTD NOWRTC WRTB
Word 7: 400F NOEBTR NOEBTRB
Es decir que si empieza en 800, pero me hace un GOTO a 0026 ¿sabe alguien por que?
Gracias de nuevo.
-
He conseguido algo, ahora ya consigo empezar fuera de la zona de bootloader segun CCS:
#include "C:\Documents and Settings\Mariano\Escritorio\Prueba2\Prueba2.h"
#build (reset=0x800, interrupt=0x0808)
#if defined(__PCM__)
#define LOADER_END 0x1FF
//#define LOADER_SIZE 0x1BF
#elif defined(__PCH__)
#define LOADER_END 0x900
//#define LOADER_SIZE 0x6FF
#endif
#ifndef _bootloader
#define _bootloader
#if defined(__PCM__)
#build(reset=LOADER_END+10, interrupt=LOADER_END+10)
#elif defined(__PCH__)
#build(reset=LOADER_END+20, interrupt=LOADER_END+18)
#endif
#org 0,LOADER_END void bootloader(void) {}
//#endif
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_oscillator(False);
// TODO: USER CODE!!
do{
output_low(PIN_B0);
delay_ms(200);
output_high(PIN_B0);
delay_ms(200);
}while(TRUE);
}
Y en ASM:
CCS PCH C Compiler, Version 4.023, 25097 20-feb-07 03:15
Filename: C:\Documents and Settings\Mariano\Escritorio\Prueba2\Prueba2.lst
ROM used: 164 bytes (1%)
Largest free fragment is 30278
RAM used: 5 (0%) at main() level
6 (0%) worst case
Stack: 2 worst case (1 in main + 1 for interrupts)
*
0914: GOTO 0944
.................... #include "C:\Documents and Settings\Mariano\Escritorio\Prueba2\Prueba2.h"
.................... #include <18F4550.h>
.................... //////// Standard Header file for the PIC18F4550 device ////////////////
.................... #device PIC18F4550
.................... #list
....................
.................... //#device adc=8
....................
.................... #FUSES NOWDT //No Watch Dog Timer
.................... #FUSES WDT32768 //Watch Dog Timer uses 1:128 Postscale
.................... #FUSES HSPLL //High Speed Crystal/Resonator with PLL enabled
.................... #FUSES NOPROTECT //Code not protected from reading
.................... #FUSES BROWNOUT //Reset when brownout detected
.................... #FUSES BORV20 //Brownout reset at 2.0V
.................... #FUSES NOPUT //No Power Up Timer
.................... #FUSES NOCPD //No EE protection
.................... #FUSES STVREN //Stack full/underflow will cause reset
.................... #FUSES NODEBUG //No Debug mode for ICD
.................... #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
.................... #FUSES NOWRT //Program memory not write protected
.................... #FUSES NOWRTD //Data EEPROM not write protected
.................... #FUSES NOIESO //Internal External Switch Over mode disabled
.................... #FUSES NOFCMEN //Fail-safe clock monitor disabled
.................... #FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
.................... #FUSES NOWRTC //configuration not registers write protected
.................... #FUSES WRTB //Boot block not write protected
.................... #FUSES NOEBTR //Memory not protected from table reads
.................... #FUSES NOEBTRB //Boot block not protected from table reads
.................... #FUSES NOCPB //No Boot Block code protection
.................... #FUSES MCLR //Master Clear pin enabled
.................... #FUSES NOLPT1OSC //Timer1 configured for higher power operation
.................... #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
.................... #FUSES PLL5 //DIVIDED BY 5 PLL PreScaler
.................... #FUSES USBDIV
.................... #fuses CPUDIV1,VREGEN,NOPBADEN,WRTB
.................... #use delay(clock=48000000)
*
091C: CLRF FEA
091E: MOVLW 06
0920: MOVWF FE9
0922: MOVF FEF,W
0924: BZ 0942
0926: MOVLW 0F
0928: MOVWF 01
092A: CLRF 00
092C: DECFSZ 00,F
092E: BRA 092C
0930: DECFSZ 01,F
0932: BRA 092A
0934: MOVLW 8F
0936: MOVWF 00
0938: DECFSZ 00,F
093A: BRA 0938
093C: NOP
093E: DECFSZ FEF,F
0940: BRA 0926
0942: RETLW 00
....................
....................
....................
.................... #build (reset=0x800, interrupt=0x0808)
.................... #if defined(__PCM__)
.................... #define LOADER_END 0x1FF
.................... //#define LOADER_SIZE 0x1BF
.................... #elif defined(__PCH__)
.................... #define LOADER_END 0x900
.................... //#define LOADER_SIZE 0x6FF
.................... #endif
....................
.................... #ifndef _bootloader
.................... #define _bootloader
.................... #if defined(__PCM__)
.................... #build(reset=LOADER_END+10, interrupt=LOADER_END+10)
.................... #elif defined(__PCH__)
.................... #build(reset=LOADER_END+20, interrupt=LOADER_END+18)
.................... #endif
....................
.................... #org 0,LOADER_END void bootloader(void) {}
*
0000: RETLW 00
....................
.................... //#endif
.................... void main()
.................... {
*
0944: CLRF FF8
0946: BCF FD0.7
0948: CLRF FEA
094A: CLRF FE9
094C: MOVF FC1,W
094E: ANDLW C0
0950: IORLW 0F
0952: MOVWF FC1
0954: MOVLW 07
0956: MOVWF FB4
....................
.................... setup_adc_ports(NO_ANALOGS|VSS_VDD);
0958: MOVF FC1,W
095A: ANDLW C0
095C: IORLW 0F
095E: MOVWF FC1
.................... setup_adc(ADC_OFF);
0960: BCF FC2.0
.................... setup_psp(PSP_DISABLED);
0962: BCF F96.4
.................... setup_spi(FALSE);
0964: BCF FC6.5
0966: BCF F94.7
0968: BSF F93.0
096A: BCF F93.1
096C: MOVLW 00
096E: MOVWF FC6
0970: MOVWF FC7
.................... setup_wdt(WDT_OFF);
0972: BCF FD1.0
.................... setup_timer_0(RTCC_INTERNAL);
0974: MOVLW 80
0976: MOVWF FD5
.................... setup_timer_1(T1_DISABLED);
0978: CLRF FCD
.................... setup_timer_2(T2_DISABLED,0,1);
097A: MOVLW 00
097C: MOVWF FCA
097E: MOVLW 00
0980: MOVWF FCB
.................... setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
0982: MOVF FB1,W
0984: ANDLW 48
0986: MOVWF FB1
.................... setup_comparator(NC_NC_NC_NC);
0988: MOVLW 07
098A: MOVWF FB4
098C: MOVF F92,W
098E: MOVLW 27
0990: MOVWF 00
0992: DECFSZ 00,F
0994: BRA 0992
0996: BRA 0998
0998: MOVF FB4,W
099A: BCF FA1.6
.................... setup_vref(FALSE);
099C: CLRF FB5
.................... setup_oscillator(False);
099E: CLRF FD3
09A0: MOVF FD3,W
....................
.................... // TODO: USER CODE!!
.................... do{
.................... output_low(PIN_B0);
09A2: BCF F93.0
09A4: BCF F8A.0
.................... delay_ms(200);
09A6: MOVLW C8
09A8: MOVWF 06
09AA: RCALL 091C
.................... output_high(PIN_B0);
09AC: BCF F93.0
09AE: BSF F8A.0
.................... delay_ms(200);
09B0: MOVLW C8
09B2: MOVWF 06
09B4: RCALL 091C
.................... }while(TRUE);
.................... }
09B6: BRA 09A2
....................
09B8: SLEEP
Configuration Fuses:
Word 1: 0E24 NOIESO NOFCMEN HSPLL PLL5 CPUDIV1 USBDIV
Word 2: 1E3F BROWNOUT NOWDT BORV20 NOPUT WDT32768 VREGEN
Word 3: 8100 NOPBADEN CCP2C1 MCLR NOLPT1OSC RESERVED
Word 4: 0081 STVREN NODEBUG NOLVP NOXINST NOICPRT RESERVED
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: A00F NOWRT NOWRTD NOWRTC WRTB
Word 7: 400F NOEBTR NOEBTRB
Parece que todo el programa discurre por fuera del bootloader, excepto esta linea:
0000: RETLW 00
Y en winpic
(http://img83.imageshack.us/img83/2/memoriawg4.jpg) (http://imageshack.us)
En la direccion 0000 aparece algo y es lo que me hace polvo el bootloader.
-
has intentado a meterle a mano el LOADER_END? igual no activas bien esas directivas que saltan con ifdef y te toma el final del loader en 0.
Porcierto lo muevo a lenguaje c para microcontroladores... seguro que allí va bastante mejor.
1 saludo
-
Gracias elmasvital, no sabia cual era su lugar mas correcto. A ver si aqui consigo encontrar el fallo.
Ya he probado a meter a mano el LOADER_END con el mismo resultado que antes, todo el meollo del asusnto esta en el #org 0,LOADER_END void bootloader(void) {}
Seguire investigando y ya os cuento.
Saludos y gracias.
-
Ahora que miro a ver en todo caso estaría en
#org 0,LOADER_END
porque
void bootloader (void) {}
es la declaración de un proceso.
y también limpiaria esto
#if defined(__PCM__)
#define LOADER_END 0x1FF
//#define LOADER_SIZE 0x1BF
#elif defined(__PCH__)
#define LOADER_END 0x900
//#define LOADER_SIZE 0x6FF
#endif
#ifndef _bootloader
#define _bootloader
#if defined(__PCM__)
#build(reset=LOADER_END+10, interrupt=LOADER_END+10)
#elif defined(__PCH__)
#build(reset=LOADER_END+20, interrupt=LOADER_END+18)
#endif
por esto otro
#define _bootloader
#define LOADER_END 0x1FF //cambiando la dirección de memoria donde acaba el bootloader
#build(reset=LOADER_END+10, interrupt=LOADER_END+10) //con las direcciones de donde están las funciones de reset y la interrupción que imagino hace que el bootloader tome el control
Mas que nada por limpiar el codigo un poquito...
-
Tienes razon en la limpieza de codigo, ya lo he limpiado un poco, ese codigo lo puse tal cual decian en el foro de microchip que funcionaba, pero ya vemos que no es tan facil jajaja.
En realidad la funcion bootloader no esta definida siquiera, simplemente la directiva #ORG reserva un rango de memoria definido por el primer parametro y el segundo que le metes para la funcion que escribas despues. El compilador no se pone a buscarla, simplementa reserva la memoria y si llamas a esa funcion en algun momento la mete en ese rango de memoria reservada.
Esto es lo que hace la funcion #ORG en teoria. Pero yo tampoco estaba muy convencido con ello asi que lo he sustitudo por:
#org 0, LOADER_END {}
De esa manera ya el codigo no va a la direccion 0000 ni a ninguna en la que este el bootloader ¡Pero sigue sin funcionar!
Me he puesto a revisar los fuses ya que en la ayuda de microchip dice que deben ser los mismos en el programa que hagas, que los que tiene el propio firmware del bootloader.
Estos son mis bits de configuracion:
CONFIGURATION MEMORY:
300000 24 0E 3F 1E 00 81 81 00 0F C0 0F A0 0F 40
Y estos los que tiene el propio firm del bootloader:
CONFIGURATION MEMORY:
300000 24 0E 3F 1E 00 81 81 00 0F C0 0F A0 0F 40
3FFFFE 02
3FFFFF 12
Los que estan en la direccion 300000 son los relativos a los fuses o bits de configuracion. Lo que no se es a que se refieren esos bits de la direccion 3FFFFF.
Seguire investigando, ya anda cerca, aunque por si no lo conseguia me he puesto a programar en C18 y funciona de perlas, pero me sigue picando el hacerlo con CCS.
Saludos y gracias.