ERIKC SADLER

MCF51QE128:  Problem using Flash, errors in CodeWarrior  (long post)

Discussion created by ERIKC SADLER on Jul 30, 2008
Latest reply on Oct 16, 2012 by gerardodiez
I have been working on a medical-related project that accumulates a few hundred bytes of data from a transducer and when the data are finally accumulated, it is stored in Flash and read back at next powerup.  Or, that is at least the intent.

I am using CodeWarrior 6.1 (the one that came with the DEMOQE128 kit), and programming the actual product board via BDM using the "USB HCS08/HCS12 Multilink Rev. C" programmer.

Problem 1:

When I try to compile the code (code in question attached) I get the following error messages out of CodeWarrior.

Message:
Link Error   : Overflow in segment: userram from section: .bssSegment reserved size is: 0x00002000 -- Overflow of: 0x00001fe4Link Error   : Overflow in segment: userram from section: .customSegment reserved size is: 0x00002000 -- Overflow of: 0x00001fe4Link Error   : Overflow in segment: userram from section: .rompSegment reserved size is: 0x00002000 -- Overflow of: 0x00001ffc

Problem 2:   This is weird, but it seems related, and I'm not sure I have language to describe it properly.

When I compile any of the statements below into my code, the "True-Time Simulator and Real-Time Debugger" that came with CodeWarrior jams.  It doesn't seem to completely load the code, (it "hangs" at the very end) so the target CPU cannot even be reset without a power cycle to clear the blockage. All of the statements involved either read or write to Flash.

Code:
Flash_Programme_One_Byte( i, Volume.flash_study[ i]);   // see end of codeFlash_Programme_One_Byte( i, Extra.flash_report[ i]);Volume.flash_study[ i] = flash_rom[ i];       // see end of codeExtra.flash_report[ i] = flash_rom[ i];

 These statements appear in the code presented below which contains the data definitions and the complete implementation of the Flash programming interface as needed by this project.

Code:
/* study_data.c *//****************************************************************************        Defines data structures for Microflo and provides a means of saving and    recovering a study in flash.****************************************************************************//****************************************************************************        Assorted variable and constant declarations.****************************************************************************/// time declarations#define THIRTY_SECONDS  30*8#define ONE_MINUTE      60*8#define TWO_MINUTES     120*8#define ONE_HALF_SECOND 4#define STARTUP_FLOW    24bool collector_still_busy = TRUE;short max_flow;                 // maximum flow.long autozero_total;short autozero_samples; /****************************************************************************    ADC variables and storage area.****************************************************************************/#define ADC_SAMPLES  64         // size of averagerstruct Convertor{    short offset15;             // weight of empty GUB.    short previous15;           // immediately preceding sample.    short raw15;                // a->d reading without offsetting    short volume15;             // volume enhanced to 15 bits.    short i;                    // index to adc_samples.                 long  total;                // sum of last 64 samples.    short data[ ADC_SAMPLES];   // holds last samples. } ADC;  /****************************************************************************    Flow averaging variables and storage area.****************************************************************************/#define FLOW_SAMPLES  8struct FlowAverager {    short raw;                  // calculated flow rate    short smoothed;             // after heavy averaging    short previous;             // saved flow value    short i;                    // index to flow samples    short total;                // sum of last 8 flow samples    short data[ FLOW_SAMPLES];  // holds last 8 flow samples} Flow; /****************************************************************************    Volume recording variables and storage area.    This gets stored in flash.****************************************************************************/#define RECORD_LENGTH 3*62*8    struct VolumeMemory{    short i;                            // index to recorded study    short stop;                         // index < RECORD_LENGTH where record stops.    short final_volume;                 // final value of volume    short recording[ RECORD_LENGTH];    // body of study } Study;// Determine number of long words needed to save the study in flash.#define STUDY_SIZE (sizeof( Study) + sizeof( long) / sizeof( long))// Translate between record format and linear long format for storage.union volume_union{    struct VolumeMemory Study;    long   flash_study[ STUDY_SIZE];} Volume;/****************************************************************************    Patient report fields and variables.    This contains only "finished" values.    This gets stored in flash.****************************************************************************/struct PatientReport{    short Vvol;                 // voided volume    short TtoMax;               // time to maximum flow.        short Tvoid;                // total time it took patient to piss.    short Tflow;                // total time patient actually spent pissing.        short Qmax;                 // maximum flow    short Qavg;                 // average flow        bool  flow_pattern;         // "CONTINUOUS" or "INTERMITTENT"} Report;// Determine number of long words needed to save the report in flash.#define REPORT_SIZE  ((sizeof( Report) + sizeof( long)) / sizeof( long))// Translate between record format and linear long format for storage.union report_union{    struct PatientReport  Report;    long   flash_report[ REPORT_SIZE];} Extra;/****************************************************************************    Empty out the study area after reset or starting a new study.****************************************************************************/void Clear_Study( void){    short i;        for( i = 0; i < RECORD_LENGTH; i++) Study.recording[ i] = 0;} /* Clear_Study *//****************************************************************************    Test routine to report on amount of memory allocation for the    study and report.  Not used in product.****************************************************************************/void Test_Show_Allocated_Data_Sizes( void){    Printer_Enable();    PrintH( "Study size  = ", STUDY_SIZE);    PrintH( "Report size = ", REPORT_SIZE);    Printer_Disable();} /* Test_Show_Allocated_Data_Sizes *//****************************************************************************    Test the study area and see if it is empty.    Return TRUE if this is the case and FALSE otherwise.****************************************************************************/bool Empty_Study( void){    short i;    short notzero = 0;        for( i = 0; i < RECORD_LENGTH; i++) notzero |= Study.recording[ i];        if(notzero)    {        Message( "Study area has data.");         Advance_For_Spacing();         return FALSE;    }    else    {        Message( "Study area is blank.");         Advance_For_Spacing();         return TRUE;    }} /* Empty_Study *//****************************************************************************    Starting address of code related to flash memory.    Flash is organised as longwords (32-bits).    In this application, it is unprotected.        Taken from pp81..86 of MCF51QE128 Reference Manual, Rev 3****************************************************************************/extern long volatile flash_rom[ REPORT_SIZE] @0x0001F000;   // last 4 sectors./****************************************************************************    Flash commands****************************************************************************/#define ERASE_VERIFY        0x25#define PROGRAM_ONE_LONG    0x20#define BURST_PROGRAM       0x25#define SECTOR_ERASE        0x40#define MASS_ERASE          0x41/****************************************************************    This is the global initialisation routine for the flash    memory.  It is used by all the flash commands.        [1] Writes the proper divisor into the FCDIV register.    The flash programmer requires a reference frequency in the    range of 195 KHz to 200 KHz.  Using a divisor of 21 gives a     flash reference frequency of 4194304 / 21 = 199728 Hz which    is within specification.  Bit 7 of FCDIV is written "1" to     ensure future writability to this register.        [2] No backdoor key is used, so this is set to zero.        [3] All but the uppermost 4K of flash are protected against    inadvertent writes.****************************************************************/void Flash_Common_Code( void){    FCDIV = 0x80 + 21;    FCNFG = 0;                  // interpret write commands as actual writes.    FPROT = 0x41;               // protect all but uppermost 4K.    while(!(FSTAT & FSTAT_FCBEF_MASK)) {};  // wait for command buffer empty        if( FSTAT & (FSTAT_FACCERR_MASK | FSTAT_FPVIOL_MASK)) FSTAT = 0x30;} /* Flash_Common_Code *//****************************************************************    Checks a block of flash to see it if is erased:    Returns TRUE if operation is successful, FALSE otherwise.****************************************************************/bool Flash_Erase_Verify( short index){    Cpu_DisableInt();     Flash_Common_Code();        flash_rom[ index] = 0;        // command write sequence    FCMD = ERASE_VERIFY;    FSTAT = 0x80;        while(!(FSTAT & FSTAT_FCCF_MASK)) {};   // wait for command buffer empty         if( FSTAT & FSTAT_FBLANK_MASK) return TRUE; else return FALSE;    Cpu_EnableInt();} /* Flash_Erase_Verify *//****************************************************************    Erases a single sector (1024 bytes or 256 longs)    Returns TRUE if operation is successful, FALSE otherwise.****************************************************************/void Flash_Sector_Erase( short index){    Cpu_DisableInt();     Flash_Common_Code();         flash_rom[ index] = 0;    FCMD = SECTOR_ERASE;    FSTAT = 0x80;        while(!(FSTAT & FSTAT_FCCF_MASK)) {};           // wait for command buffer empty      Cpu_EnableInt();} /* Flash_Sector_Erase *//****************************************************************    Programs a single address in flash.****************************************************************/void Flash_Programme_One_Byte( short index, long data){    Cpu_DisableInt();     Flash_Common_Code();         flash_rom[ index] = data;            FCMD = BURST_PROGRAM;    FSTAT = 0x80;                   while(!(FSTAT & FSTAT_FCCF_MASK)) {};   // wait for command completion    Cpu_EnableInt();} /* Flash_Programme_One_Byte *//****************************************************************    Erase the study area of flash and verify the erasure.    Return TRUE if the erasure of all three sectors is good,    FALSE otherwise.****************************************************************/bool Erase_And_Verify_Data_Flash( void){    Flash_Sector_Erase( 0);    if( Flash_Erase_Verify( 0))    {                Flash_Sector_Erase( 0x100);        if( Flash_Erase_Verify( 0x100))        {            Flash_Sector_Erase( 0x200);            if( Flash_Erase_Verify( 0x200))            {                error = 0;                return TRUE;            }            else error = 29;     // block 3 failed erasure        }        else error = 28;         // block 2 failed erasure    }    else error = 27;             // block 1 failed erasure    return FALSE;} /* Erase_And_Verify_Data_Flash *//****************************************************************    Saves a study in flash.    ****************************************************************/void Save_Study_In_Flash( void){    short i;        if( Erase_And_Verify_Data_Flash())    {        for( i = 0; i < STUDY_SIZE; i++)         { //             Flash_Programme_One_Byte( i, Volume.flash_study[ i]);   // one of the problems        }        for( i = STUDY_SIZE; i < STUDY_SIZE + REPORT_SIZE; i++)        {             Flash_Programme_One_Byte( i, Extra.flash_report[ i]);        }    }     else    // something wrong so print an error message.    {        Printer_Enable();        Print_Error( error);        Printer_Disable();    }} /* Save_Study_In_Flash *//****************************************************************    Retrieves the last study from flash****************************************************************/void Restore_Study_From_Flash( void){    short i;        for( i = 0; i < STUDY_SIZE; i++)    { //       Volume.flash_study[ i] = flash_rom[ i];       // one of the problems    }        for( i = STUDY_SIZE; i < STUDY_SIZE + REPORT_SIZE; i++)    {        Extra.flash_report[ i] = flash_rom[ i];    }} /* Restore_Study_From_Flash *//*    These two statements result in the errors listed below.     //       Flash_Programme_One_Byte( i, Volume.flash_study[ i]); //       Volume.flash_study[ i] = flash_rom[ i]; Link Error   : Overflow in segment: userram from section: .bssSegment reserved size is: 0x00002000 -- Overflow of: 0x00001f5cLink Error   : Overflow in segment: userram from section: .customSegment reserved size is: 0x00002000 -- Overflow of: 0x00001f5cLink Error   : Overflow in segment: userram from section: .rompSegment reserved size is: 0x00002000 -- Overflow of: 0x00001f74Link failed.*/

 





Message Edited by fireweaver on 2008-07-30 07:14 PM

Outcomes