This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Flash ECC error when using compiler optimization

Other Parts Discussed in Thread: RM48L952, HALCOGEN, NOWECC

Hello

I'm developing for RM48L952 using compiler 5.0.1.

My selftest function for the flash ECC runs fine without compiler optimizations (using CCS 5.3.0 for downloading and debugging). With compiler optimization -O3 the checks runs into flashClass2Error(). At this point  FEDACSTATUS is 0.

Thanks for help
Aedu

Here is my check function (generated with Halcogen, recommended modifications added):

void checkFlashECC(void)
{
    volatile uint32_t flashread = 0;

/* USER CODE BEGIN (63) */
    /* clear correctable error bits */
    flashWREG->FEDACSTATUS = 0x6U;
/* USER CODE END */
    
    flashWREG->FEDACCTRL1 = 0x000A060A;            
 
    flashWREG->FDIAGCTRL = 0x00050007;            
    
    flashWREG->FPAROVR = 0x00005A01; // halcogen_mod: Halcogen Bug, 0x00005401 is wrong
    
    flashWREG->FDIAGCTRL |= 0x01000000;            
    
    flashread = flashBadECC;    
    
    flashWREG->FDIAGCTRL = 0x000A0007;            

    /* this will have caused a single-bit error to be generated and corrected by CPU */
    /* single-bit error not captured in flash module */
    if (!(flashWREG->FEDACSTATUS & 0x2))        
    {
        flashClass2Error();
    }
    else
    {
        flashWREG->FEDACSTATUS = 0x2;                

        esmREG->ESTATUS1[0] = 0x40;                    

        flashWREG->FDIAGCTRL = 0x00050007;            
       
        flashWREG->FPAROVR = 0x00005A03;            
       
        flashWREG->FDIAGCTRL |= 0x01000000;            

        flashread = flashBadECC;                    
    }

/* USER CODE BEGIN (64) */
/* USER CODE END */
}

  • Aedu,

    Does this code work when compiled without -o3?

    Thanks and regards,

    Zhaohong

  • Zhaohong

    Yes, the code works without  -O3 (debug configuration). The Flash ECC selftest passes.

    Regards
    Aedu

  • Aedu,

    Would you please check if the global pointer "flashWREG" is defined as a volatile type?

    Thanks and regards,

    Zhaohong

  • Zhaohong,
    The global pointer "flashWREG" is defined like this:

    typedef volatile struct flashWBase
    {
     ...
    } flashWBASE_t;

    #define flashWREG ((flashWBASE_t *)(0xFFF87000U))

    That looks ok for me. Do you have any other suggestions?

    Regards
    Aedu

  • Aedu,

    this seems to be an timing issue, with the code executed to fast to recognize the failure in time when optimizations are used.

    I would propose to add a readback of register FDIAGCTRL in the code after enabling the diag mode:

        flashWREG->FEDACCTRL1 = 0x000A060A;            
     
        flashWREG->FDIAGCTRL = 0x00050007;            
        
        flashWREG->FPAROVR = 0x00005A01; // halcogen_mod: Halcogen Bug, 0x00005401 is wrong
        
        flashWREG->FDIAGCTRL |= 0x01000000;

            flashWREG->FDIAGCTRL; /* Read Back */
        
        flashread = flashBadECC;    
        
        flashWREG->FDIAGCTRL = 0x000A0007;   


    This should ensure, that the write to the FDIAGCTRL register has been propagated trough the bus matrix before reading the "faulty" data.
    I currently don't have a kit available to test this, can you please let us know if this does the trick?


    Best Regards,

    Christian

  • Aedu,

    I tried this on the bench, for me this test didn't worked at all so I dug deeper into this.

    The reason for me why this test always failed was, that there was no data at the flash location where the read happens and thus also no ECC data which caused an uncorrectable error instead of an correctable one.

    This might also be the case for you, if you got optimizations disabled your code might be huge and there is data at this location, if you enable optimizations your code shrunk and the test fails because of an uncorrectable error (data abort).

    The location where the read happens is defined as follow:

    #define flashBadECC        (*(volatile uint32 *)(0x20040000U))

    This is the mirrored flash image (bus 2 access).

    You should eigther specify an fill value in the Linker Command File, which causes the linker to fill the unused flash memory with an pattern or you should somehow ensure that some data is placed at 0x00040000.

    I would prefer the first option, because it is anyway good to fill unused flash memory and generate ECC for this, in order to avoid ECC faults during speculative fetches (prefetch abort).

    Anyway if you want to place some data at a specific location you can do this with the following lines of C code:

    #pragma RETAIN(forceData);
    #pragma LOCATION(forceData , 0x00040000);
    const uint64 forceData = 0x12345678ABCDEF12ULL;

    Please let us know if this solved your problem.

    Best Regards,
    Christian

  • Christian
    Thanks for your help. The problem you encountered on your test bench looks similar to mine.

    I had already specified a fill value in the linker command file, nevertheless I had the the problem.

    When I place some data at position 0x0004000 as you suggested, then the problem seems to be solved. The application and the flashECC selftest runs (using  -O3 optimization).

    In spite of having a fill value in the linker command file, it looks for me that the flash is not filled entirley with valid data with correct ECC. I'm not yet using the nowECC as post build step, but have the Auto ECC generation enabled (in the CCS project settings). Is there something more to consider using Auto ECC generation?

    Best regards
    Aedu

    btw: When I add  "forceData"  to the "Expressions" window in CCS, it shows me the wrong address (0x80000 instead of 0x40000). In the .map file, it is placed on the correct location.

  • Hello Aedu,

    specifying a fill value with ECC autogen in CCS 5.3.0 works for me, here is the memory directive for the LCF:

    MEMORY
    {
        VECTORS (X)  : origin=0x00000000 length=0x00000020
        FLASH0  (RX) : origin=0x00000020 length=0x0017FFE0 fill=0x0ECC0ECC
        FLASH1  (RX) : origin=0x00180000 length=0x00180000
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        RAM     (RW) : origin=0x08001500 length=0x0003EB00
    }

    I can also see, that the expression window in CCS shows the wrong address and value of this const, however the Linker placed it correct. I will report this as a bug in CCS.

    Best Regards,
    Christian

  • Hello Christian
    Now it works.
    I specified fill values for all flash section in the SECTIONS part of the LCF, but not in MEMORY part. That was the problem.

    Thanks a lot
    Aedu