Autor Tema: Bootloader y aplicación. ¿Como hago para que compartan las rutinas en común?  (Leído 3786 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
Hola a todos. Mi consula es la siguiente:
Estoy programando con el pic c de ccs y mi dispositivo tiene un bootloader por usb y usa un display. La aplicación también utiliza estos recursos. ¿Como hago para que la aplicación utilize las rutinas del lcd y del usb que están en el bootloader ya que ambos programas se compilan por separado?.Gracias

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
¿Tienes el código fuente del bootloader y puedes modificarlo?
Si es así, pégalo por aquí y vemos cómo podemos hacerlo.

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
gracias por tu interés. Todavía no lo terminé al bootload. Me faltan ajustar algunos detalles. En general me basé en un ejemplo que trae el pic c v 4.059. que es un bootloader por usb usando el modo cdc. MI codigo trabaja de otra forma y a esto le agregué la libreria LCD.h para manejar un display. Mi consulta nace por la necesidad (por proligidad no por falta de memoria) de no duplicar las rutinas del lcd y las del usb que vienen en el usb_cdc.h. Apenas termine el bootload lo agrego.
Un saludo desde Argentina

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
 aqui está el codigo del bootloader, la idea sería utilizar las rutinas del lcd y del usb en la aplicación. Si alguien sabe como se hace se los agradecería. Saludos
Código: C
  1. /*
  2.         *****************************
  3.         *  Bootloader USB  
  4.         *                    Versión 1.0                 *
  5.        *****************************
  6. */
  7. //#define DEBUG_ICD
  8.  
  9. #define __USB_PIC_PERIF__ 1
  10. #if !defined(__PCH__)
  11.  #error USB CDC Library requires PIC18
  12. #endif
  13.  
  14. #include <18F4550.h>
  15. #ifdef DEBUG_ICD
  16. #device ICD=TRUE
  17. #fuses XTPLL,NOWDT,NOPROTECT,NOLVP,DEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
  18. #else
  19. #fuses XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
  20. #endif
  21.  
  22.  
  23. #use delay(clock=48000000)
  24.  
  25. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  26. /////////////////////////////////////////////////////////////////////////////
  27. //
  28. // If you are using a USB connection sense pin, define it here.  If you are
  29. // not using connection sense, comment out this line.  Without connection
  30. // sense you will not know if the device gets disconnected.
  31. //       (connection sense should look like this:
  32. //                             100k
  33. //            VBUS-----+----/\/\/\/\/\----- (I/O PIN ON PIC)
  34. //                     |
  35. //                     +----/\/\/\/\/\-----GND
  36. //                             100k
  37. //        (where VBUS is pin1 of the USB connector)
  38. //
  39. /////////////////////////////////////////////////////////////////////////////
  40. ///only the 18F4550 development kit has this pin
  41. #if __USB_PIC_PERIF__ && defined(__PCH__)
  42.  #define USB_CON_SENSE_PIN PIN_C1
  43. #endif
  44.  
  45. // Archivos y librerías asociadas
  46. #include <LCD.C>
  47. #define _bootloader
  48. #include <usb_bootloader pablo.h>
  49.  
  50.  
  51. #define LOADER_ISR 0x28
  52. #build(interrupt=LOADER_ISR)
  53.  
  54. #include <usb_cdc boot.h>
  55. // Valor en EEPROM que activa modo carga otro ejecuta la aplicación
  56. #rom 0xF000FF={0x97}
  57.  
  58. // Configuración de Pines
  59. #define LED PIN_B4
  60. #define LED_OFF output_low
  61. #define LED_ON output_high
  62.  
  63. // El puerto D es configurado para el LCD en el archivo LCD.C como sigue:
  64. //     D0  enable
  65. //     D1  rs
  66. //     D2  rw
  67. //     D4  D4
  68. //     D5  D5
  69. //     D6  D6
  70. //     D7  D7
  71.  
  72. //Definición de constantes
  73. #define VER (LOADER_SIZE -5)
  74. #rom VER={0,3,8} //Versión del bootloader y ID del equipo
  75.  
  76. /*
  77. Salta a la isr que corresponda, bootloader o aplicacion
  78. */
  79. #org 0x08,0x17
  80. void high_isr(void)
  81. {
  82.    if (bit_test(g_InBootloader,0))
  83.    {
  84.     #ASM
  85.      goto LOADER_ISR
  86.     #ENDASM
  87.    }
  88.    else
  89.    {
  90.     #ASM
  91.      goto APPLICATION_ISR
  92.     #ENDASM
  93.    }
  94. }
  95.  
  96. #org 0x18,0x27
  97. void low_isr(void)
  98. {
  99.    if (bit_test(g_InBootloader,0))
  100.    {
  101.     #ASM
  102.      goto LOADER_ISR+0x10
  103.     #ENDASM
  104.    }
  105.    else
  106.    {
  107.     #ASM
  108.      goto APPLICATION_ISR+0x10
  109.     #ENDASM
  110.    }
  111. }
  112.  
  113. // Envía la versión de bootloader por USB
  114. void Version(void)
  115. {
  116.         int8 Buffer [3];
  117.         int8 i;
  118.         read_program_memory((VER),Buffer,3);
  119.         //usb_cdc_putc('v');
  120.         for(i=0; i<3; i=i+2)
  121.         {
  122.                 usb_cdc_putc(Buffer[i]);
  123.         }
  124. }
  125.  
  126. // Envia el ID del equipo
  127. void ID_Equipo(void)
  128. {
  129.         int8 Buffer[1] ;
  130.         read_program_memory((VER+4),Buffer,1);
  131.         usb_cdc_putc(Buffer[0]);
  132. }
  133.  
  134. void Bootloader(void)
  135. {
  136.         char c;
  137.         BYTE Buffer[256];
  138.         int32 address_flash;   //Direccion memoria flash
  139.         int16 cant_datos;       //Cantidad de datos a TX o RX
  140.         int16 i;                                //Contador para bucles
  141.         BYTE address_eeprom;
  142.                
  143.         lcd_putc("\f");
  144.         lcd_gotoxy(4,1);
  145.         printf(lcd_putc,"Modo Carga");
  146.         usb_cdc_init(); //Inicializa USB
  147.         usb_init();
  148.          while(!usb_enumerated());
  149.          
  150.         do
  151.         {
  152.                 usb_task();  //Sensa si se conectó al USB, si se usa el PIN de sensado
  153.                 if (usb_enumerated())
  154.                 {
  155.                         if (usb_cdc_kbhit())
  156.                         {
  157.                                 c=usb_cdc_getc();
  158.                                 switch (c)
  159.                                 {
  160.                                         case 'A':
  161.                                                 //Envia versión de bootloader y ID equipo
  162.                                                 Version();
  163.                                                 ID_Equipo();
  164.                                                 break;
  165.                                         case 'B':
  166.                                                 //Lee flash (hasta 256Bytes)
  167.                                                 address_flash=65536 * usb_cdc_getc();
  168.                                                 address_flash+=256 * usb_cdc_getc();
  169.                                                 address_flash+=usb_cdc_getc();
  170.                                                 cant_datos=usb_cdc_getc();
  171.                                                 if (cant_datos==0) {cant_datos=256;}
  172.                                                 read_program_memory(address_flash,Buffer,cant_datos);
  173.                                                 for(i=0; i<cant_datos; i++)
  174.                                                 {
  175.                                                         usb_cdc_putc(Buffer[i]);
  176.                                                 }
  177.                                                 break;
  178.                                         case 'C':
  179.                                                 //Escribe Flash (HASTA 256Bytes EN BLOQUES DE 8BYTES)
  180.                                                 address_flash=65536 * usb_cdc_getc();
  181.                                                 address_flash+=256 * usb_cdc_getc();
  182.                                                 address_flash+=usb_cdc_getc();
  183.                                                 cant_datos=usb_cdc_getc();
  184.                                                 if (cant_datos==0) {cant_datos=256;}
  185.                                                 for (i=0;i<cant_datos;i++)
  186.                                                 {
  187.                                                         Buffer[i]=usb_cdc_getc();
  188.                                                 }
  189.                                                 write_program_memory(address_flash,buffer,cant_datos); 
  190.                                                 usb_cdc_putc('J');                             
  191.                                                 break;
  192.                                         case 'D':
  193.                                                 //Borra Flash (64 bytes)
  194.                                                 address_flash=65536* usb_cdc_getc();
  195.                                                 address_flash+=256 * usb_cdc_getc();
  196.                                                 address_flash+=usb_cdc_getc();
  197.                                                 erase_program_eeprom(address_flash);
  198.                                                 usb_cdc_putc('J');
  199.                                                 break;
  200.                                         case 'E':
  201.                                                 //Lee EEPROM
  202.                                                 usb_cdc_putc(read_eeprom(usb_cdc_getc()));
  203.                                                 break;
  204.                                         case 'F':
  205.                                                 //Escribe EEPROM
  206.                                                 address_eeprom=usb_cdc_getc();
  207.                                                 write_eeprom(address_eeprom,usb_cdc_getc());  
  208.                                                 usb_cdc_putc('J');
  209.                                                 break;
  210.                                         case 'J':
  211.                                                 //Ejecuta Programa
  212.                                                 write_eeprom(0xFF,0);
  213.                                                 delay_ms(2000);
  214.                                                 reset_cpu();
  215.                                                 break;
  216.                                 }
  217.                         }
  218.                 }
  219.         } while (TRUE);        
  220. }
  221.  
  222.  
  223. void main(void)
  224. {
  225.         g_InBootloader = TRUE;
  226.         LED_ON(LED);
  227.                
  228.         lcd_init();       //Inicializa LCD
  229.         delay_ms(6);
  230.         if (read_eeprom(0xFF)==0x97)
  231.         {
  232.                 Bootloader();
  233.         }
  234.        
  235.         g_InBootloader = FALSE;
  236.         LED_OFF(LED);
  237.         #ASM
  238.         goto APPLICATION_START
  239.         #ENDASM
  240. }
  241.  
  242.  
  243. //************************************
  244. //     usb_bootloader pablo.h
  245. //************************************
  246. //how big is the bootloader?
  247. //the bootloader will reside from address 0x0000 to this location.  the
  248. //application will then sit at this location+1 to the end of program memory.
  249. #define LOADER_SIZE        (0x17FF)
  250.  
  251. //the loader and application need a common flag that determines if we are in
  252. //the bootloader or application, that way the ISR knows where to go.  this
  253. //is the location in ram that is reserved for this flag.
  254. #define LOC_IN_LOADER_FLAG  0x25
  255.  
  256. //// --- end configuration --- ////////////////////////////////////////////
  257.  
  258. #reserve LOC_IN_LOADER_FLAG
  259.  
  260. int8 g_InBootloader;
  261. #locate g_InBootloader=LOC_IN_LOADER_FLAG
  262.  
  263. #define LOADER_START       (0)
  264. #define LOADER_END         (LOADER_SIZE)
  265. #define APPLICATION_START  (LOADER_SIZE+1)
  266. #define APPLICATION_END    (getenv("PROGRAM_MEMORY")-1)
  267. #define APPLICATION_ISR    (APPLICATION_START+8)
  268.  
  269. #ifdef _bootloader
  270.  /*
  271.   Provide an empty application, so if you load this .HEX file into the pic
  272.   without an application this will prevent the pic from executing unknown code.
  273.  */
  274.  #org APPLICATION_START,APPLICATION_START+0xF
  275.  void aplicacion(void)
  276.  {
  277.         while(TRUE);
  278.  }
  279.  
  280.  //we need to prevent the loader from using application space
  281.  #if APPLICATION_END>0xFFFF
  282.    #org APPLICATION_START+0x10, 0xFFFF {}
  283.    #if APPLICATION_END>0x1FFFF
  284.       #org 0xFFFF, 0x1FFFF {}
  285.    #else
  286.       #org 0xFFFF, APPLICATION_END {}
  287.    #endif
  288.  #else
  289.    #org APPLICATION_START+0x10, APPLICATION_END {}
  290.  #endif
  291. #endif
  292.  
  293. #ifndef _bootloader
  294.  //in the application, this moves the reset and isr vector out of the bootload
  295.  //space.  it then reserves the loader space from being used by the application.
  296.  #build(reset=APPLICATION_START, interrupt=APPLICATION_ISR)
  297.  #org 0, LOADER_END {}
  298. #endif

Modificado por Nocturno: he editado tu mensaje para meter el programa en formato Geshi, ya que no se veía bien
« Última modificación: 16 de Abril de 2008, 11:49:07 por un Moderador »

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
Hola, encontré una probable solución en el foro de ccs a ver que les parece:

Make sure the routines are declared as 'separate'.
Use the #ORG directive, to put the subroutine(s) required, into the _same_ area of memory, in both the bootloader code, and the main code.
Use as normal.

So your memory layout becomes:

Bootloader

Shared area used by both programs

Main code

Then _provided_ the same compiler version is used to build the main code, and the bootloader code - be careful on this...., both sets of code contain identical definitions for the 'shared' functions. Normally you modify the bootloader, so it won't overwrite stuff in the 'shared' area, so the code from the 'main', when reloaded, doesn't overwrite this code.


Y otro le respondío:

Ttelmah's solution will work for some time but eventually (after several years) compiler versions will have to change. An improvement to the proposed scheme would be to define a strict prescribed interface: a jump table and fixed addresses for the function parameters. A bit like how the BIOS functions in a DOS-PC are called.

Es como dice el segundo?, depende de la versión del compilador? Como se podría implementar lo que sugiere la segunda respuesta ya que parece independiente de la versión del compilador?
Gracias....  :shock:

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
Bueno. Estoy al horno con papas con esto. Implementé una zona de memoria común al bootloader y a la aplicación en donde coloqué las rutinas en común a los dos programas. Compilo el bootloader y queda todo bien. Cuando compilo la aplicación estas rutinas se ubican en la zona de memoria esperada pero en otro orden. ¿Alguien sabe por que pasa esto?. ¿Como puedo hacer para que en ambos casos se ubiquen en las mismas posiciones de memoria?.
Si alguien me puede tirar un salvavidas se lo agradeceré.
Gracias

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
Como me abandonaron con esto....

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Hola, te voy a ser sincero no soy experto en CCS ni en PICS, pero voy a tratar de darte una mano, el problema que tenes es un problema de linkeo, es decir, cuando el linker aloca funciones en un area o segmento la va llenando en demanda, cuando vos queres que una funcion o grupo de funciones se coloquen en una dirección absoluta deberias hacerlo con un pragma, deberias verificar en la documentación del CCS para verificar de que manera una funcion o bloque de código se fije en una dirección absoluta. La idea seria asi:

Código: [Seleccionar]
#pragma section SECTION1
void MyFunction1( void )
{
}

#pragma section SECTION2
void MyFunction2( void )
{
}
Despues en el archivo de configuración del linker deberias especificar las direcciones absolutas de estas secciones y asi todas las funciones quedarian bajo la misma direccion,pero como te dije antes desconozco el CCS asi que relamente nose si es posible hacerlo ...
Saludos !


« Última modificación: 20 de Mayo de 2008, 17:01:51 por RICHI777 »

Desconectado PFER90

  • PIC10
  • *
  • Mensajes: 17
ok, gracias por escribir, me parece que en este punto el compilador de ccs hace agua, estaba probando con el compilador de microchip que es un poco mas complicado me parece para linkear codigo pero es mas flexible en estas cosas
Gracias de nuevo

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
ok, gracias por escribir, me parece que en este punto el compilador de ccs hace agua, estaba probando con el compilador de microchip que es un poco mas complicado me parece para linkear codigo pero es mas flexible en estas cosas
Gracias de nuevo

Hola pfer90, recién leo tu hilo.  El problema que tienes no es de compilador ni de los pics, es de que tienes que saber más cosas de C.  No culpes al resto de que te abandonaron.

Es importante que aclares algo. Las rutinas 'comunes', las piensas sobreescribir con el bootloader? o las piensas dejar fijas? si son fijas, entonces no veo porqué tanto problema.

Saludos
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)


 

anything