please explain about FFCOB register.in that command ,address and data's are there .what they mean ?
Hi,
I am developing bootloader for my controller.as part of i want to edit the linker file .i need to some of the information about linker file editing.
please explain each in placement
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 */
//.ostext, /* OSEK */
NON_BANKED, /* runtime routines which must not be banked */
DEFAULT_ROM,
COPY INTO ROM;
SHADOW_ROM INTO SHADOW_ROM_S;
i am refering AN4723 example code in that i configured linker as ROM starting address 0xFD0000.but start up address is changed to some other address (0XFD003E)with reference to map file.why there is small gap in address ?
STARTUP SECTION
---------------------------------------------------------------------------------------------
Entry point: 0xFD002E (_Startup)
_startupData is allocated at 0xFD003E and uses 20 Bytes
extern struct _tagStartup {
unsigned nofZeroOut 1
_Range pZeroOut 0x1100 4793
_Copy *toCopyDownBeg 0xFDBDB5
int nofInitBodies 0
_Cpp *initBodies 0xFD0059
int nofFiniBodies 0
_Cpp *finiBodies 0xFD0059
} _startupData;
please explain about Entry point address 0xFD002E .what does location means anything reserved for 2E bytes.
SECTION-ALLOCATION SECTION
Section Name Size Type From To Segment
---------------------------------------------------------------------------------------------
.init 62 R 0xFD0000 0xFD003D ROM
.startData 27 R 0xFD003E 0xFD0058 ROM
.rodata 1736 R 0xFD0059 0xFD0720 ROM
.text 45695 R 0xFD0721 0xFDB99F ROM
.copy 529 R 0xFDB9A0 0xFDBBB0 ROM
.stack 256 R/W 0x1000 0x10FF RAM
.data 578 R/W 0x1100 0x1341 RAM
will .init change based on application code ?
please explain .init,.startData ,.rodata
can u explain with a small example of bootloader code ,and what all the precautions has to be taken as taking care of linker file.
Thanks,
if i want to write by bytes (8 different bytes) in to 1 phrase .is it possible ?.i checked it shows some magic values in memory of every high registers(FCCOB1HI,FCCOB2HI....).What may be the reason ?
Hi Sathish,
Yes, you could (rather say you have to) program P-Flash per 8 bytes = 4 words.
There are no magic numbers. Please look at Table 22-26. FCCOB - NVM Command Mode (Typical Usage) in RM. There you could see that FCCOB1HI have to contain Global address [15:8] = (middle byte from global address). The FCCOB2HI have to consist Data 0 [15:8] = higher byte from first word.
If you use PFLASH_Program() function from my example code, input should be array filed by words.
If you want that input buffer is byte array, you have to convert it into word array prior use PFLASH_Program() function or you have to directly modify (or create your own) PFLASH_Program() function.
In second case, input parameter should be “unsigned char *ptr” and commands
FCCOB2 = ptr[0];
FCCOB3 = ptr[1];
FCCOB4 = ptr[2];
FCCOB5 = ptr[3];
Have to be replaced by
FCCOB2LO = ptr[0];
FCCOB2HI = ptr[1];
FCCOB3LO = ptr[2];
FCCOB3HI = ptr[3];
FCCOB4LO = ptr[4];
FCCOB4HI = ptr[5];
FCCOB5LO = ptr[6];
FCCOB5HI = ptr[7];
Note: Optionally you could use some simple loop with pointers instead of this sequence of commands.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Is it possible to program as a single word in flash memory as in eeprom .? then i am getting access error while erasing flash memory what may be reason ?
Hi Sathish,
Minimum part for P-Flash erase is sectors (aligned 512B for S12ZVC).
Minimum part for P-Flash program is phrase (aligned 8B for S12ZVC).
So, even if your data is just one word, you have to program 4 words. Area in P-Flash for these 4 words must be in erased state (all bytes are 0xFF) prior programming. You should check these words prior programming and these words has to be aligned (lowest three bits from address has to be 0).
Please check Table 22-41. Program P-Flash Command Error Handling and Table 22-50. Erase P-Flash Sector Command Error Handling in RM.
There you could see error conditions which results as ACCERR error flag.
At least critical part (start flash command and wait until command finish) of code must be executed from RAM.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I Tried your program with code warrior,
1)I am not able to erase the memory location.I checked with the MGSTAT flags they are stays clear so it indicates that blank check passed.(not reflecting in memory regions)
2)I am able to write the FFCOB data registers,but how to check whether the data successfully written in flash memory ?
3)With reference to your code,in erase function if i am giving address it has to erase memory of 512 bytes starting from that ,Is nt it?
4)How to know the free memory in flash,Is it visible in code warrior debugger.
5) I found some points from other forum about the code warrior debugger.
How do verify that flash contents doesn't change? If it's Codewarrior debugger, you should keep in mind that by default it caches flash and EEPROM contents and doesn't display actual flash contents, unless you make modifications to debugger memory map (in debugger go to Multtilink menu)
What this means ?
6) Guide me step by step procedure to check the memory regions in debugger.
Hi sathish,
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi
1) yes .i checked the erase function with memory regions where the memory locations are already flashed by application.Will it take time to reflect in debugger address map ?
2) If i use PFLASH_Read_Byte() to read the memory locations I am not possible to get the data from locations where the locations are already programmed by application.
5)Right now i am stepping the debugger to see the change in memory map.Do i need to do anything else to see the programmed memory region ?
7)i am not moving my code to ram will it be a problem to erase and program flash memory ?If yes explain the reason.
" Erasing a sector will set all its bits to 1. After erasing a sector, the FTMRZ can try to write data into it but this can’t be done
while executing code from Flash, since Flash can’t be read-from and written-to at the same time. To write to a Flash sector,
the application must be executing code from RAM"
What this means ?
Hi sathish,
1)Yes, see Table K-2. NVM Timing Characteristics 32 MHz in RM. Erase P-Flash Sector takes 20ms. Also reading trough BDM interface takes some time.
2)That is strange. Could you please let me know which address you erase and try program?
5) no, that should be enough.
7) Yes, it is a problem. It is not possible to read from P-Flash memory while some commands are executing on the same P-Flash block. If a Flash block is read during execution of an algorithm (CCIF = 0) on that same block, the read operation may return invalid data resulting in an illegal access. So, there is high chance that CPU will execute something different instead of main code. Debugger will be confused and/or MCU could go into reset due to Illegal opcode or Illegal address.
CW10 typically reports that issue by opening new window with some numbers. Only way how to back synchronize debugger with MCU is trough MCU reset.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi ,
I tried to erase a memory location which contained flashed code.In that location i am not able to erase as well as program.
how to get the address from prm file can you explain with an example ?
Hi sathish,
Prm file defines available RAM/EEPROM/Flash space for linker.
So, if we want use some part of flash for our data, we should exclude this part of flash from linker memory map otherwise we could meet with situation that we will rewrite our code – this typically means crash of code.
Example:
Default Flash range for S12ZVC is defined as:
ROM = READ_ONLY 0xFD0000 TO 0xFFFDFF;
Note: Range 0xFFFE00 to 0xFFFFFF is used for vectors.
We want use for example range 0xFE0000 to 0xFE7FFF (32kB) to storage our user data. In that case we should define Flash as:
ROM1 = READ_ONLY 0xFD0000 TO 0xFDFFFF;
ROM2 = READ_ONLY 0xFE0000 TO 0xFE7FFF;
ROM3 = READ_ONLY 0xFE8000 TO 0xFFFDFF;
And section “PLACEMENT” will contain:
…
DEFAULT_ROM,
COPY INTO ROM1, ROM3;
In that case, default code cannot be placed into ROM2 area since this area is not in default placement.
When we want store also some data (code or constants) into ROM2 area as part of our project, we could create our own segment in section “PLACEMENT”. For example:
MY_DATA INTO ROM2;
In our C file we could place our data into this segment by pragmas. For example:
#pragma CONST_SEG MY_DATA
const unsigned char test1 = 0xAA;
#pragma CONST_SEG DEFAULT
Note: CONST_SEG pragmas are used for constants placement. CODE_SEG pragmas are used for code placement. DATA_SEG pragmas are used for variables placement.
Note: these pragmas are not limited by end of file, therefore I would like to strictly recommend return to default settings (#pragma xxxx_SEG DEFAULT) inside this file.
This way we could simply drive placement of code/constants/variables in MCU memory map.
Note: If possible, I would like to recommend do not use direct placement like:
const unsigned char temp1 @0xFE0000 = 0xAA;
without exclude this area from linker memory map. Linker does not aware about that data in code placement and any overlapping just lead to warning message. Unfortunately default CW10.6 project has disabled these warnings due to 24bit register constructions in S12Z derivative header file.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi,
thanks alot for the explanation.
Can you explain how to open and see the linker file from codewarrior for particular project.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi My linker file is defined as below.I need to know the free address for writing data .How to edit this file ?
/* This is a linker parameter file for the MC9S12ZVC64 */
NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
/* Register space */
/* IO_SEG = PAGED 0x000000 TO 0x000FFF; intentionally not defined */
/* RAM */
RAM = READ_WRITE 0x001000 TO 0x001FFF;
/* EEPROM */
EEPROM = READ_ONLY 0x100000 TO 0x1003FF;
/* non-paged FLASHs */
ROM = READ_ONLY 0xFF0000 TO 0xFFFDFF;
/* VECTORS = READ_ONLY 0xFFFE00 TO 0xFFFFFF; intentionally not defined: used for VECTOR commands below */
//OSVECTORS = READ_ONLY 0xFFFE10 TO 0xFFFFFF; /* OSEK interrupt vectors (use your vector.o) */
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 */
//.ostext, /* OSEK */
NON_BANKED, /* runtime routines which must not be banked */
DEFAULT_ROM,
COPY INTO ROM;
//.stackstart, /* eventually used for OSEK kernel awareness: Main-Stack Start */
SSTACK, /* allocate stack first to avoid overwriting variables on overflow */
//.stackend, /* eventually used for OSEK kernel awareness: Main-Stack End */
DEFAULT_RAM INTO RAM;
//.vectors INTO OSVECTORS; /* OSEK */
END
ENTRIES /* keep the following unreferenced variables */
/* OSEK: always allocate the vector table and all dependent objects */
//_vectab OsBuildNumber _OsOrtiStackStart _OsOrtiStart
END
STACKSIZE 0x100
VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */
//VECTOR 0 Entry /* reset vector: this is the default entry point for an Assembly application. */
//INIT Entry /* for assembly applications: that this is as well the initialization entry point */
Hi sathish,
Please use procedure four posts above for modification in your prm file.
EEPROM or P-Flash (marked as ROM for linker) could be used for storage your data.
User data placement depends on your needs however I would like to recommend keeps user segments (which you plan to rewrite by code) aligned with sector size.
More details about linker and prm file could be found in file:
"c:\Freescale\CW MCU v10.6\MCU\Help\PDF\MCU_Build_Tools_Utilities.pdf"
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi ,
Still not able to erase as well as write to flash memory .i shared my code please have a look at this with reference to .prm file
1) i used pragmas for moving code in to ram .correct me if i am wrong.
///////////////////////////////////////////////////////////////////
/* RAM */
RAM = READ_WRITE 0x001000 TO 0x001FFF;
/* EEPROM */
EEPROM = READ_ONLY 0x100000 TO 0x1003FF;
/* non-paged FLASHs */
ROM = READ_ONLY 0xFF0000 TO 0xFFFDFF;
/* VECTORS = READ_ONLY 0xFFFE00 TO 0xFFFFFF; intentionally not defined: used for VECTOR commands below */
//OSVECTORS = READ_ONLY 0xFFFE10 TO 0xFFFFFF; /* OSEK interrupt vectors (use your vector.o) */
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 */
//.ostext, /* OSEK */
NON_BANKED, /* runtime routines which must not be banked */
DEFAULT_ROM,
COPY INTO ROM;
//.stackstart, /* eventually used for OSEK kernel awareness: Main-Stack Start */
SSTACK, /* allocate stack first to avoid overwriting variables on overflow */
//.stackend, /* eventually used for OSEK kernel awareness: Main-Stack End */
DEFAULT_RAM INTO RAM;
////////////////////////////////////////////////////////////////////////////////////
Hi sathish,
I shortly checked your files.
You didn’t use either Send_Command() or PFLASH_Send_Command() function from example code (from my first reply to this thread).
Send_Command() missing in your code and PFLASH_Send_Command() is commented out.
One of these functions has to be used for trigger flash command (by clearing CCIF flag).
You code just modify FCCOBx registers, but it never starts such flash command.
Please use one of commands (PFLASH_Send_Command(); or asm JSR Send_Command;) in your LLD_FLS_Erase_Verify_Section(),LLD_FLS_Program() and LLD_FLS_Erase_Sector() functions.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi ,
Thanks alot for pointing out the mistake.
I modified the flash program file as you said .If it has mistake correct me.Which is in bold colour.Why we are using that PFLASH_Send_Command(); function.
Do i need to change anything in main.
//////////////////////////////////////////////////////////
#include <hidef.h>
#include "lld_flash.h"
//or we can use linker pragmas for placing this function into RAM:
#pragma CODE_SEG DEFAULT_RAM
void PFLASH_Send_Command(void)
{
DisableInterrupts;
FSTAT_CCIF = 1; //launch command
while(FSTAT_CCIF == 0){}; //wait for done
EnableInterrupts;
}
#pragma CODE_SEG DEFAULT
//==============================================================================
//LLD_FLS_Erase_Verify_Section
//==============================================================================
u8 LLD_FLS_Erase_Verify_Section(u32 address, u32 number_of_phrases)
{
//check if address is aligned (global address [2:0] = 000)
if((address & 0x00000007) != 0)
return MISALIGNED_ADDRESS;
while(FSTAT_CCIF == 0){}; //wait if command in progress
FSTAT = 0x30; //clear ACCERR and PVIOL
FCCOBIX = 0x02; //we will write command up to FCCOB2
FCCOB0HI = 0x03;
FCCOB0LO = ((address & 0x00FF0000)>>16);
FCCOB1 = (address & 0x0000FFFF);
FCCOB2 = number_of_phrases;
PFLASH_Send_Command();
if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0)
return ACCESS_ERROR;
//check if phrases are erased and return result
if(FSTAT_MGSTAT != 0)
return NON_ERASED;
else
return ERASED;
}
//==============================================================================
//LLD_FLS_Program
//==============================================================================
u8 LLD_FLS_Program(u32 address, u8 *ptr)
{
u8 i;
//check if address is aligned (global address [2:0] != 000)
if((address & 0x00000007) != 0)
return MISALIGNED_ADDRESS;
//check if the phrase is erased
if((LLD_FLS_Erase_Verify_Section(address, 1)) == NON_ERASED)
return NON_ERASED;
while(FSTAT_CCIF == 0){}; //wait if command in progress
FSTAT = 0x30; //clear ACCERR and PVIOL
FCCOBIX = 0x05; //we will write command up to FCCOB5
FCCOB0HI = 0x06;
FCCOB0LO = ((address & 0x00FF0000)>>16);
FCCOB1 = (address & 0x0000FFFF);
FCCOB2 = ptr[0];
FCCOB3 = ptr[1];
FCCOB4 = ptr[2];
FCCOB5 = ptr[3];
PFLASH_Send_Command();
if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0)
return ACCESS_ERROR;
else
return OK;
}
//==============================================================================
//LLD_FLS_Erase_Sector
//==============================================================================
u8 LLD_FLS_Erase_Sector(u32 address)
{
//size of sector is 512B
//check if address is aligned (global address [2:0] != 000)
if((address & 0x00000007) != 0)
return MISALIGNED_ADDRESS;
while(FSTAT_CCIF == 0){}; //wait if command in progress
FSTAT = 0x30; //clear ACCERR and PVIOL
FCCOBIX = 0x01; //we will write command up to FCCOB1
FCCOB0HI = 0x0A;
FCCOB0LO = ((address & 0x00FF0000)>>16);
FCCOB1 = (address & 0x0000FFFF);
PFLASH_Send_Command();
if((FSTAT & (FSTAT_ACCERR_MASK | FSTAT_FPVIOL_MASK)) != 0)
return ACCESS_ERROR;
else
return OK;
}
//==============================================================================
//LLD_FLS_Read_Byte
//==============================================================================
u8 LLD_FLS_Read_Byte(u32 address)
{
u8 data8;
data8 = *(u8 *)address;
return data8;
}
//==============================================================================
//LLD_FLS_Read_Word
//==============================================================================
u32 LLD_FLS_Read_Word(u32 address)
{
u32 data16;
data16 = *(u32 *)address;
return data16;
}
//==============================================================================
//LLD_FLS_Init
//==============================================================================
void LLD_FLS_Init(u8 fdiv)
{
while(FSTAT_CCIF == 0){}; //wait if command in progress
FCLKDIV = fdiv; //osc = ? MHz
}
Hi sathish,
I am sorry, but I didn’t check your main code.
Please delete these lines in main():
#pragma CODE_SEG DEFAULT_RAM
DisableInterrupts;
FSTAT_CCIF = 1; //launch command
while(FSTAT_CCIF == 0){}; //wait for done
EnableInterrupts;
#pragma CODE_SEG DEFAULT
They have no sense here since we didn’t configure FCCOBx registers before that code.
This part of code is called as PFLASH_Send_Command().
We cannot execute code flash block which we currently erase/program. Therefore we just configure flash command, jump to code in RAM (PFLASH_Send_Command()) and start execution of flash command from there. We also waits until flash command finish and return back to code in flash.
Since default vector table and interrupt routines are stored in the same flash block, we should also disable interrupts during execution of flash command. If time critical interrupts has to be executed during flash command, we have to also move vector table and interrupt routines into RAM (in that case we will not disable interrupt during flash command execution).
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi ,
Is it possible to erase and program in a single program ?