Sebastian Paul

Bootloader and Application in one Project - tips and problems

Discussion created by Sebastian Paul on Feb 3, 2012
Latest reply on Feb 13, 2012 by Sebastian Paul

Hi @all,

 

i want to programm a CAN bootloader for a HCS08 (MC9S08DV-series) in CW 5.9.0.  I have read a lot of usefull things in this forum (especially https://community.freescale.com/message/29324#29324, https://community.freescale.com/message/74968#74968) and some ANs (AN2295, AN1828, AN3312, AN2153) from freescale about bootloaders, but there are still some open questions and problems. First let me explain my project :smileyhappy:

 

About my bootloader project:

I know, the bootloader gurus suggest to devide bootloader and app to get a strictly isolation between them. But my problem is that i can't debug the app when my controller runs with bootloader code in Real Time Debugger and i don't know how to combine these 2 projects for debugging. So i decide to put bootloader and application in one project. It is also the easiest way and more error-free in the development phase i think. 

 

Characteristics till now:

- After Reset the Controller jumps to bootloader startup code. Main MCU inits (clock) are set and a bootloader_flag is checked, if it is "1" or "0".

- When this flag is "0" the bootloaders startup code ends and there's a jump to app startup code (complete MCU init, all registers) and after that the app started.

- When this flag is "1" the further bootloader code starts (with COP Watchdog off, CAN init) and then waiting for flash-data via CAN BUS.

- FLASH Segmentation is done in the *.prm file:

SEGMENTS
    Z_RAM             =  READ_WRITE   0x0080 TO 0x00FF; //128 Bytes STACK
    RAM               =  READ_WRITE   0x0100 TO 0x087F; //1920 Bytes RAM
    FUNKTIONEN_DELETE =  READ_ONLY    0x7C00 TO 0xD5FF; //Applicationcode
    BOOTLOADER        =  READ_ONLY    0xD600 TO 0xF9FF; //Bootloadercode
    FLASH_TO_RAM      =  READ_ONLY    0xFA00 TO 0xFA7F RELOCATE_TO 0x0800;  //Functions that runs out of RAM
    INTVECTS          =  READ_ONLY    0xFFC0 TO 0xFFFF; //Startvector
END

PLACEMENT
    DEFAULT_RAM                 INTO  RAM;
    _PRESTART,                          /* startup code */
    STARTUP,                            /* startup data structures */
    ROM_VAR,                            /* constant variables */
    STRINGS,                            /* string literals */
    VIRTUAL_TABLE_SEGMENT,              /* C++ virtual table segment */
    DEFAULT_ROM,                        /* normaler Code, Konstanten, Strings, DEFAULT_ROM == .text*/
    COPY                                /* copy down information: how to initialize variables */
                                        INTO  FUNKTIONEN_DELETE;
    BOOT_CODE,
    BOOT_DATA,
    BOOT_CONST,
    BOOT_STRING                INTO BOOTLOADER;
    FLASH_ROUTINES            INTO FLASH_TO_RAM;
    _DATA_ZEROPAGE,                     /* zero page variables */
    MY_ZEROPAGE                INTO Z_RAM;
END

- Bootloader don't use interrupts! So i can use standard vector redirection by setting NVOPT and NVPROT. Do so, i also protect the Flash up the BOOTLOADER-Segment (0xD600), so the redirected Interrupt table is right below, in the end of FUNKTIONEN_DELETE Segment.

- in the code i use the #pragma CODE_SEG instruction, to devide bootloader and app code

- for flashing app code a Windows software reads out the S19 File, only the code segment of app (0x7C00-D5FF), and sends this data sectorvise per CAN-BUS into the hardware

 

Thats it so far. I can still flash some little functions with this code, but there are still some sources of error!

 

- problems with global variables in BOOTLOADER Segment. If i understand it correctly, only the functions are put into Segment via #pragma CODE_SEG, but not the global vars, aren't they? Global vars belongs to COPYDOWN, and therefor they will be written into my FUNKTIONEN_DELETE Segment... but thats a problem! If i flash the app code with a new app, where COPYDOWN is in other addresses as before, my bootloader will fail. Is this correct? I need the global var "bootloader_flag" in bootloader and app code, how can i manage it? By the way, when i debug from beginning of the code, i can't find the point where bootloader_flag is initialisized. There is no copydown code, like in the app startup (the standard _Startup code which CW creates)... where is this init value copied from FLASH to RAM?

 

-how can i check at bootloader mode, if an app is present and if the app is ok / completely? Perhaps there was an an error by flashing before. I read something about using checksum, but i can't checksum the whole app at startup... that takes too long

 

-have you still some tips for me, or are there some failures i don't care till now?

Outcomes