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.

TMS570LS3137: FEE Block lost when writing during Power loss

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN

Hello,

I'm using FEE to save multiple Blocks of data onto emulated EEPROM. My ti_fee_cfg is found below.

I need a Virtual Sector of greater than 16K because the largest block that is written takes about 20K. So I use 2x2 Physical Sectors (i.e. the whole Bank 7) as 2 Virtual Sectors.

The large Block is written rarely (calibration information is stored here), whereas one of the smaller blocks (384Byte) is written much more frequently. During normal operation, everything works well:

  • When the smaller block is written, the previous valid block is marked invalid and the the new block becomes valid
  • When writing of the smaller block requires changing the virtual sector, everything works well too -> the other valid blocks are copied on the new virtual sector and the data is valid.

Bad things happen when a power loss occurs during writing the smaller block and a change of Virtual Sector is required. It seems the other valid blocks (especially the largest block) are not copied correctly to the new V-Sector. After restart, no valid block can be found for the large one. Another restart and the data seems to be corrupted completely (FEE driver finds a valid block but the data stored is corrupted).

I read out the whole bank (both virtual sectors) and found pieces of the large block (by searching for the block size and number which is quite unambiguously):

Offset        Block Status

069C       -> Start        Prev. Addr: 0xF020 0020
3BFC      -> Valid        Prev. Addr: 0xF020 0020
869C       -> Start        Prev. Addr: 0xF020 0020
A02C       -> Start        Prev. Addr: 0xF020 0020

On a correctly working FEE, there are only 2 hits (one within each V-Sector).

The "Valid" Block can't be correct, as there is not enough space on the V-Sector (0x3BFC + 0x4FFB > 0x8000), so it's clear that these data have to be corrupted.

There might be another reason for data loss:

My application consists of an modified version of the Safety-Bootloader and the Application itself. The Bootloader needs to access the FEE to get the Starting Address of the Application. That's why the Bootloader initializes the FEE driver and later jumps into the Application. The Application however initializes the FEE a second time.

Might this be an issue which could lead to this behaviour or is this a known issue caused by other problems?

My configuration below:

Thanks in advance


/** @struct Fee_VirtualSectorConfigType     */
/*  @brief Virtual Sector Configuration     */
const Fee_VirtualSectorConfigType Fee_VirtualSectorConfiguration[TI_FEE_NUMBER_OF_VIRTUAL_SECTORS] =
{

    /* Virtual Sector 1 */
    {
       /* Virtual sector number */      1U,
       /* Bank                  */      7U,      
       /* Start Sector          */      (Fapi_FlashSectorType)0U,
       /* End Sector            */      (Fapi_FlashSectorType)1U
    },
    /* Virtual Sector 2 */
    {
        /* Virtual sector number */     2U,
        /* Bank                  */     7U,
        /* Start Sector          */     (Fapi_FlashSectorType)2U,            
        /* End Sector            */     (Fapi_FlashSectorType)3U
    }
 
};


/* Block Configurations         */
/* SourceId : HL_Fee_SourceId_2 */
/* DesignId : HL_FEE_DesignId_3, HL_FEE_DesignId_8 */
/* Requirements : HL_FEE_SR2, HL_FEE_SR3, HL_FEE_SR4, HL_FEE_SR6, HL_FEE_SR85, HL_FEE_SR86
                  HL_FEE_SR87, HL_FEE_SR88, HL_FEE_SR89, HL_FEE_SR90, HL_FEE_SR91 */
const Fee_BlockConfigType Fee_BlockConfiguration[TI_FEE_NUMBER_OF_BLOCKS] =
{
        /*      Block 1 */
        {
               /* Block number                          */     1U,
               /* Block size                            */     64U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }

        ,
        /*      Block 2 */
        {
               /* Block number                          */     2U,
               /* Block size                            */     384U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,           
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 3 */
        {
               /* Block number                          */     3U,
               /* Block size                            */     384U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 4 */
        {
               /* Block number                          */     4U,
               /* Block size                            */     384U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 5 */
        {
               /* Block number                          */     5U,
               /* Block size                            */     64U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 6 */
        {
               /* Block number                          */     6U,
               /* Block size                            */     64U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 7 */
        {
               /* Block number                          */     7U,
               /* Block size                            */     128U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 8 */
        {
               /* Block number                          */     8U,
               /* Block size                            */     20475U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 9 */
        {
               /* Block number                          */     9U,
               /* Block size                            */     4095U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,               
               /* EEP number                            */     0U               
        }
        ,
        /*      Block 10 */
        {
               /* Block number                          */     10U,
               /* Block size                            */     512U,
               /* Block immediate data used             */     TRUE,               
               /* Number of write cycles                */     0x8U,
               /* Device Index                          */     0x00000000U,
               /* Number of DataSets                    */     1U,           
               /* EEP number                            */     0U               
        }
        ,
        /* If project needs more than 16 blocks, add additional blocks here and also
           modify TI_FEE_TOTAL_BLOCKS_DATASETS and TI_FEE_NUMBER_OF_BLOCKS in ti_fee_cfg.h     */
/* USER CODE BEGIN (1) */
/* USER CODE END */
 

  • Hello Marco,

    It should be fine to initialize the FEE driver in application if the RA/Stack/Registers are also initialized in application. 

    Does any data block contain more than 8 bytes of zero?

  • Hello Wang,

    I am sure they do. The Blocks contain reserved sections for future use, and as the structures initially reside in BSS Section, they are zeroed out.
    I had a look into the readout of the bank and found a lot of consecutive zero bytes.

    But I guess this could be prevented by simply filling them with 0xFF before writing.

    I also found 12 zero bytes at the start - are the zero bytes used for finding the start of a Sector?

    Thanks for quick response.

  • Can you please dump the content of the virtual sectors when failure occurs?

  • Here is the dumped Bank 7.

    1385.fee_dump.zip

  • Hello,

    could you find any issue with the dump?

    Can you provide more information about the 8 Zero bytes? If I understand the ti_fee code right (especially TI_FeeInternal_UpdateBlockOffsetArray), the found sector is scanned for Invalid or corrupted blocks by searching for 8 consecutive zero bytes.

    Unfortunately, it is not as easy as I thought to prevent the occurence of 8 consecutive 0x00 Bytes.

    I think one solution for this could be, to replace all the Zeroes used for encoding the Block state by e.g. 0x11 or 0x55. A pattern of eight 0x11 bytes or 0x55 bytes is unlikely enough in our application (rather than zeroes).

    I would simply modify the Macros in ti_fee.h to be:

    #define EmptyBlockHi                 0xFFFFFFFFU
    #define EmptyBlockLo                0xFFFFFFFFU
    #define StartProgramBlockHi	 0xFFFF5555U
    #define StartProgramBlockLo	 0xFFFFFFFFU
    #define ValidBlockHi		         0x55555555U
    #define ValidBlockLo		         0xFFFFFFFFU
    #define InvalidBlockHi		 0x55555555U
    #define InvalidBlockLo		 0xFFFF5555U
    #define CorruptBlockHi		 0x55555555U
    #define CorruptBlockLo		 0x55555555U

  • Hello,

    I am sorry for late response. I am analyzing your data:

    0572.test.txt

  • I noticed that the programming of block 8 was corrupted couple times, how many power cycles during the FEE programming?

  • Typically, before device is turned off, block 2, 3 or 4 is written once. If this requires copying all valid blocks to the new virtual sector, than after next start, block 8 will be lost.

    Maybe I have turned device on and off again before dumping the content but I don't know.

    Why is the valid marked block 8 starting at a location, where there is not enough space is left in the sector?

    I really need to fix the problem within the next days. Can you please say something about the proposed solution with changing the encoding for the block status (not use Zeroes anymore)? Otherwise I would simply try this and hope the problem is fixed.

  • Hello Marco,

    I guess that the driver might write the block 8 to VS0 and VS1 (cross the sector boundary) successfully, and mark the header as Valid. After writing block 8, the VS1 is erased, and other valid blocks (1->7) in VS0 are copied to VS1.

    The driver should not write the data of one block cross the VS boundary, otherwise it is a SW bug. 

  • When will the new VS marked as ACTIVE? I would think the new VS should be marked as COPY as long as not all valid blocks have been copied.

    In case of Power loss during copying, the new VS would have to be erased and copying should start again.

    Instead it seems it won't be erased but be programmed further, even if the blocks won't fit on the VS.

    If my assumption is right, is there any possibility to detect this misbehaviour and restart copying after initialization?

    Something like -> If one sector is ACTIVE and other is COPY -> Erase COPY Sector, restart copying all valid blocks and afterwards mark as ACTIVE / old one as ReadyForErase?

    Therefore the old Sector / old blocks must not have been touched (e.g. marked invalid) until the new Sector becomes ACTIVE.

  • I am checking with FEE driver developer, and it may take couple days to get feedback.

  • Hello Wang,

    If I don't find a solution for this problem, I will have to use an external EEPROM / NVRAM instead of the FEE.

    Is there any possibility to detect the situation, when the FEE will write the big block over the VS Boundary?

  • Hello Marco,

    If there is power loss during the virtual sector copy which contains big block exceeding the VS biundary, the current FEE driver may loss a big block during copying. I needs our developer's confirmation, but we don't have plan to update the driver. If it is a SW bug, we will add the recommended workaround to HALCoGen release note.

  • Hello Marco,

    To avoid this issue, my suggestion is to split the big block into multiple smaller blocks.