FW update using bootloader in XEP100 [HSC12X series] controller

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FW update using bootloader in XEP100 [HSC12X series] controller

1,554 Views
Vaibhav15
Contributor II

Hi,

I am trying to upload application firmware to flash memory using bootloader application. I am having MC9S12XEP100CVL controller.

Currently Our bootloader application is running in block 0 which performs following application

  • Erase complete flash memory.
  • Writing application firmware to flash memory
  • Switching from bootloader to application

The code snippets of the .prm file for bootloader which defines the memory assignment is added below.

 

 

ROM_4000 = READ_ONLY 0x4000 TO 0x7F0F;
ROM_C000 = READ_ONLY 0xDF00 TO 0xFEFF; [Bootloader Code]

BL_DATA = READ_ONLY 0xD800 TO 0xD805; [Bootloader - Application Verification section]

 

 

 

Our objective is to write the application to higher blocks of flash memory [like Block 2 and Block 1] and the switch to the application firmware.

Now my question is how to configure/distribute the flash memory in prm file of the application firmware? 

I have tried following memory configuration in prm file

 

 

SEGMENTS /* here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. All addresses are 'logical' */

/* Register space  */
/*    IO_SEG        = PAGED         0x0000 TO   0x07FF; intentionally not defined */

/* Non-paged EEPROM NOT USED*/
/*      EEPROM        = READ_ONLY     0x0C00 TO   0x0FFF;  */

/* Non-paged RAM (visible to both CPU and XGATE) */
      RAM_STACK_INT   = READ_WRITE    0x2000 TO   0x2001; // stack integrity area (stack magic)
      RAM_STACK       = READ_WRITE    0x2002 TO   0x27FF; // Stack area enlarged!
      RAM             = READ_WRITE    0x2880 TO   0x3EFF ALIGN 2[1:1]; /* word align for XGATE accesses */      
      RAM_NVM         = NO_INIT       0x3F00 TO   0x3F7F; // This area is foreseen for data that must be stored in NVM
                                                          // 0x2400.0x2407 must remain undefined for explicit usage by variables
      RAM_NO_INIT_SCHEDULER = NO_INIT 0x3F80 TO   0x3FBF; /* Variables that must survive a reset shall be placed here */
      RAM_NO_INIT           = NO_INIT 0x3FC0 TO   0x3FEF; /* Variables that must survive a reset shall be placed here */
      RAM_NO_INIT_FWU       = NO_INIT 0x3FF0 TO   0x3FF7; /* Variables that must survive a reset shall be placed here */

/* Non-banked FLASH */
      /* Leave space for Vector table from 0x7F10 to 0x7FFF;  */
      ROM_4000      = READ_ONLY     0x4000 TO   0x7F0F;
      
      /* Leave space for Bootloader from 0xD800 to 0xFFFF */
      /* Note: D800 to DBFF reserved for Application Verification info written by bootloader */
      ROM_C000      = READ_ONLY     0xE08000 TO   0xE7BFFF;

/* Paged FLASH:                     0x8000 TO   0xBFFF; addressed through PPAGE */
      PAGE_E0       = READ_ONLY   0xE08000 TO 0xE0BFFF; 
      PAGE_E1       = READ_ONLY   0xE18000 TO 0xE1BFFF; 
      PAGE_E2       = READ_ONLY   0xE28000 TO 0xE2BFFF; 
      PAGE_E3       = READ_ONLY   0xE38000 TO 0xE3BFFF;         
      PAGE_E4       = READ_ONLY   0xE48000 TO 0xE4BFFF;        
      PAGE_E5       = READ_ONLY   0xE58000 TO 0xE5BFFF;       
      PAGE_E6       = READ_ONLY   0xE68000 TO 0xE6BFFF;        
      PAGE_E7       = READ_ONLY   0xE78000 TO 0xE7BFFF;         

      PAGE_E8       = READ_ONLY   0xE88000 TO 0xE8BFFF;
      PAGE_E9       = READ_ONLY   0xE98000 TO 0xE9BFFF;
      PAGE_EA       = READ_ONLY   0xEA8000 TO 0xEABFFF;
      PAGE_EB       = READ_ONLY   0xEB8000 TO 0xEBBFFF;
      PAGE_EC       = READ_ONLY   0xEC8000 TO 0xECBFFF;
      PAGE_ED       = READ_ONLY   0xED8000 TO 0xEDBFFF;
      PAGE_EE       = READ_ONLY   0xEE8000 TO 0xEEBFFF;
      PAGE_EF       = READ_ONLY   0xEF8000 TO 0xEFBFFF;

      PAGE_F0       = READ_ONLY   0xF08000 TO 0xF0BFFF;
      PAGE_F1       = READ_ONLY   0xF18000 TO 0xF1BFFF;
      PAGE_F2       = READ_ONLY   0xF28000 TO 0xF2BFFF;
      PAGE_F3       = READ_ONLY   0xF38000 TO 0xF3BFFF;
      PAGE_F4       = READ_ONLY   0xF48000 TO 0xF4BFFF;
      PAGE_F5       = READ_ONLY   0xF58000 TO 0xF5BFFF;
      PAGE_F6       = READ_ONLY   0xF68000 TO 0xF6BFFF;
      PAGE_F7       = READ_ONLY   0xF78000 TO 0xF7BFFF;

      PAGE_F8       = READ_ONLY   0xF88000 TO 0xF8BFFF;
      PAGE_F9       = READ_ONLY   0xF98000 TO 0xF9BFFF;
      PAGE_FA       = READ_ONLY   0xFA8000 TO 0xFABFFF;
      PAGE_FB       = READ_ONLY   0xFB8000 TO 0xFBBFFF;
      PAGE_FC       = READ_ONLY   0xFC8000 TO 0xFCBFFF;
/*    PAGE_FD       = READ_ONLY   0xFD8000 TO 0xFDBFFF;   intentionally not defined: equivalent to ROM_4000 */
      PAGE_FE       = READ_ONLY   0xFE8000 TO 0xFEBFFF;
/*    PAGE_FF       = READ_ONLY   0xFF8000 TO 0xFFBFFF;   intentionally not defined: equivalent to ROM_C000 */



	  /* External SRAM - 128 kBytes @ CS2 and CS3 (see hardware diagram)
       *
       * CS2 : GPAGE = 0x14 - 0x1F, page size is 65536 Bytes - not used currently
       * CS3 : RPAGE = 0x01 - 0xFB, page size is  4096 Bytes
       *
       * C-A-R-E-F-U-L!!! Objects larger than 4096 can't be allocated when using CS3!!
       *
       */
      EXT_RAM_G_0   = READ_WRITE  0x140000'G TO 0x14FFFF'G;
      EXT_RAM_G_1   = READ_WRITE  0x150000'G TO 0x15FFFF'G;
/* not used yet
      EXT_RAM_G_2   = READ_WRITE  0x160000'G TO 0x16FFFF'G;
      EXT_RAM_G_3   = READ_WRITE  0x170000'G TO 0x17FFFF'G;
*/

END

PLACEMENT /* here all predefined and user segments are placed into the SEGMENTS defined above. */
      _PRESTART,              /* Used in HIWARE format: jump to _Startup at the code start */
      STARTUP,                /* startup data structures */
//      ROM_VAR,                /* constant variables */
//      STRINGS,                /* string literals */
      VIRTUAL_TABLE_SEGMENT,  /* C++ virtual table segment */
      NON_BANKED,             /* runtime routines which must not be banked */
      COPY                    /* copy down information: how to initialize variables */
                              /* in case you want to use ROM_4000 here as well, make sure
                                 that all files (incl. library files) are compiled with the
                                 option: -OnB=b */
                        INTO  ROM_C000/*, ROM_4000*/;


/* Paged internal FLASH */
		STRINGS,
      ROM_VAR,                /* constant variables */
      DEFAULT_ROM       INTO           PAGE_FE,          PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8,
                               PAGE_F7, PAGE_F6, PAGE_F5, PAGE_F4, PAGE_F3, PAGE_F2, PAGE_F1, PAGE_F0, 
                              PAGE_EF, PAGE_EE, PAGE_ED, PAGE_EC, PAGE_EB, PAGE_EA, PAGE_E9, PAGE_E8, 
                              PAGE_E7, PAGE_E6, PAGE_E5, PAGE_E4, PAGE_E3, PAGE_E2, PAGE_E1, PAGE_E0;                 
                              
      SSTACK,                 /* allocate stack first to avoid overwriting variables */
                        INTO  RAM_STACK;

      STACK_INT,
                        INTO  RAM_STACK_INT;

      PAGED_RAM,
      DEFAULT_RAM             /* Default RAM, all variables */
                        INTO  EXT_RAM_G_0, EXT_RAM_G_1;

      SHARED_DATA,            /* variables that are shared between CPU12 and XGATE */
      NEAR_RAM,               /* all variables declared NEAR */
                        INTO  RAM;

      /* all variables declared NEAR_NO_INIT, must survive reset */
      NEAR_RAM_NO_INIT_FWU,
                        INTO  RAM_NO_INIT_FWU;
      NEAR_RAM_NO_INIT,
                        INTO  RAM_NO_INIT;
      NEAR_RAM_NO_INIT_SCHEDULER,
                        INTO  RAM_NO_INIT_SCHEDULER;
                        
      NEAR_RAM_NVM,           /* RAM copy of NVM variables (not used yet) */
                        INTO  RAM_NVM;
                        
END

ENTRIES

END

STACKSIZE 0x400           /* size of the stack */

// VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */

 

 

 

I am getting error following error

 

 

ERROR L1100: Segments ROM_C000 (0xC08000) and PAGE_E0 (0xE08000) overlap

 

 

 

So how to configure the memory map i.e. prm file for application firmware is the question?

Any kind of pointers will be helpful, Thanks in advance

 

Tags (2)
0 Kudos
5 Replies

1,425 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

It looks like you understand the placement of the data and code and connection to the prm file.


The code which is placed into C000 segment is too large so you will have to put part of it to another segment. You can play a game with placement of the code using

For example:
Prm file…. Another MCU with less FLASH pages but the principle is the same

PLACEMENT


// DEFAULT_ROM INTO PAGE_FE, PAGE_FC, PAGE_FB, PAGE_FA, PAGE_F9, PAGE_F8; // an original, full memory
DEFAULT_ROM INTO PAGE_FE, PAGE_FC, PAGE_FB;   // reduced default memory placement posibilities
MY_CODE_SPACE_XXX INTO PAGE_FA;                          // space for forced placement of the code

// you can see I also removed some from prm file to be able to use them directly by SW. In this way the CW does not use them for its purpose. I have removed them also fro SEGMENTS part of the prm file. This was only issue not relate comment.

in the file.c rhen I use the space....

 

#pragma CODE_SEG MY_CODE_SPACE_XXX


void near Send_Command(void) // near to be sure it will be launched by JSR and finished by RTS
{
FSTAT_CCIF = 1; // launch command
while(FSTAT_CCIF == 0); // wait for done
}

#pragma CODE_SEG DEFAULT

So check what is put into the page which is not big enough and try to reorganize the code placement in the C code. Usually the interrupt functions are placed to the near space. If they are too big it is necessary to split some of them and call function from far space.

If you are not familiar with placement of code in flash it is good to create small test project and play with it and look at the result S19 file or any place where the placement is clearly visible.

 

Best regards,

Ladislav

0 Kudos

1,321 Views
Vaibhav15
Contributor II

Hi Lama,

Thanks for the response.

Now I am able to compile code by reducing the default memory placement.

I have few more quires regarding the placing the code and running bootloader and user application in blocks.

The Bootloader is running in block 0 [bottom few sectors]. It uses address range [0x7FDF00 - 0x7FFFE0] and S19 file of application also includes the remaining addresses from the block 0.

Limitation : The issue is XEP100 does not allow to perform any operation like erase and write on the unused flash addresses of particular Block where the code is running.

In our case we are using Block 0[256KB] for bootloader application which uses around 12 sectors[code and verification data] so we are not able to use remaining sectors of block 0 because of above mentioned limitation. 

So there are two options we can think of 

1. Using other blocks for running the user application code.

   - Can you please share any example code or what all things we need to take care for running user     application from different blocks?

2. finding a to way to use the remaining block of the block 0.

   - Is there any way we can write to unused sectors of block 0 where my bootloader application is running?

Can you please suggest any way to fix these issues?

0 Kudos

1,537 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

Could you please think about principle by reading AN4258. Attached.

Best regards, Ladislav

0 Kudos

1,499 Views
Vaibhav15
Contributor II

Hi Lama,

I have referred provided examples but I am having some issues with compilation. 

Memory mapping of the XEP100 in terms of blocks are mentioned below

Global AddressLogical AddressBlockSize
0x70_0000 - 0x73_FFFFC08000 - CFBFFFB3256K
0x74_0000 - 0x77_FFFFD08000 - DFBFFFB2256K
0x78_0000 - 0x79_FFFFE08000 - E7BFFFB1S128K
0x7A_0000 - 0x7B_FFFFE88000 - EFBFFFB1N128K
0x7C_0000 - 0x7F_FFFFF08000 - FFFFB0256K

 

We have bootloader and application to place in above blocks. Currently the arrangements of memory is mentioned below.

We want to arrange the memory as shown below. The bootloader code is around 18KB and user application is around 700KB.

 

Application TypeGlobal AddressLogical AddressDescription
User application Start0x7FC000C000ROM_C000 address range assignment for user application
User application End0x7FD7FFD7FFROM_C000 address range assignment for user application
User application vector Table[Start]0x7F7F107F10User application vector table range assignment
User application vector Table[End]0x7F7FFF7FFFUser application vector table range assignment
Bootloader Date Start0x7FD800D800Verification Data Range assignment
Bootloader Date End0x7FD805D805Verification Data Range assignment
Bootloader Code start0x7FDF00DF00ROM_C000 address range assignment for bootloader application
Bootloader code end0x7FFEFFFEFFROM_C000 address range assignment for bootloader application
Bootloader vector Table[Start]0x7FFF10FF10Bootloader vector table Range assignment
Bootloader vector Table[End]0x7FFFFFFFFFBootloader vector table Range assignment

 

Please find the code snippets of parameter file[prm] where ranges are defined  

For Bootloader:

      ROM_4000      = READ_ONLY     0x4000 TO   0x7F0F;
      ROM_C000      = READ_ONLY     0xDF00 TO   0xFEFF;  
        
      BL_DATA        = READ_ONLY    0xD800 TO   0xD805;  

For User Application:

/* Non-banked FLASH */
      /* Leave space for Vector table from 0x7F10 to 0x7FFF;  */
      ROM_4000      = READ_ONLY   DATA_NEAR IBCC_NEAR  0x4000 TO   0x7F0F;
      
      /* Leave space for Bootloader from 0xD800 to 0xFFFF */
      /* Note: D800 to DBFF reserved for Application Verification info written by bootloader */
      ROM_C000      = READ_ONLY   DATA_NEAR IBCC_NEAR  0xC000 TO   0xD7FF;

Note: I have attached the prm file for both bootloader and user application for more information.

with above setting I am able to compile bootloader application but with user application I am getting some linker errors

Error:

ERROR L1102: Out of allocation space in segment ROM_C000 at address 0xDBF3

Question:

1. What is this exact issue here and how to resolve it ?

2. What is the correct way of preparing the parameter file above mentioned case?

0 Kudos

1,163 Views
lama
NXP TechSupport
NXP TechSupport

Hi,

I am sorry for delay because I was not available.

 

Have you read AN4258 I sent before? AN4258SW\Bootloader_S12X\Sources

 

There is entire solution. It is good to download SW and look at it.

 

The AN4258 code moves whole Flash routines into RAM (There is CopyCodeToRAM() function and the linker know about code placement from prm linker file – see segment with RELOCATE_TO 0x3D00; parameter).

 

I do not know your routine for programming the flash but you can always do something like this.

  1. a) either run part of the write code from another type of flash/eeprom memory but this approach require to have the code waiting for flash operation stored in it.

 

  1. b) or solve it “dynamically”. The bootloader allocates some part of ram then copy there a code which is responsible for waiting for flash operation end and then it uses it .

The part of RAM can be allocated as a static part when bootloader creates an array in the RAM where the PIT code (position independent code) is copied and there run by pointer to a function.

 

There is also another code for flashing attached. It allocates some RAM array which is in reality the code used for flash E/W. The copy of the code to the ram is done automatically by CW as for initialized variable. It is then called as a function in the flash routines.

 

The most important is a part of the code:

static unsigned char Send_Command[]=

{

  0x1C, 0x01, 0x06, 0x80, 0x1F, 0x01, 0x06, 0x80, 0xFB, 0x3D

};

 

In the past, for older family of the devices, the approach called DoOnStack was used. The part of the code which is run out of RAM (see code just above this paragraph) is before usage always get from flash and put onto the stack. (It is enough to push the code from previous example) Then it is executed out of the stack. Finally SP is returned back to original value which was before loading the function onto it.

 

 

Best regards,

Ladislav

0 Kudos