AnsweredAssumed Answered

MQX Flashx driver bug in K64/K70

Question asked by S.z. Liang Employee on Sep 23, 2015

     Several customers reported they met MQX Flashx writing issue in K64/K70 device. After some digging in Flashx driver code,FAE found the root cause:

 

     Flash data must be in the erased state before being programmed. In case of both FTFL and FTFE modules we program flash by aligned phrases. If we want program by smaller chunks (e.g by bytes), FTFL module will allow you write into this phrase even if it is not recommended. However FTFE module will cause bus fault in case of second write into the same phrase.

   The K60 writes long words to Flash and the K64/K70 writes phases (8 bytes). But the function "_io_flashx_check_free_space" just handles 4 bytes buffer, doesn't aligned to phrases(8 bytes buffer)!! In function "ftfe_flash_write_sector",it will overwrite some non 0xff area. For this scenario:

    ret = write(flashx_fp, write_buffer, 12);

    ret = write(flashx_fp, write_buffer, 4);

The second write to the same location would fail in K64/K70.

 

Patch code for K64/K70( red part):

 

_mem_size _io_flashx_check_free_space(

    /* [IN] source pointer */

    char    *src_ptr,

    /* [IN] number of bytes to check */

    _mem_size   num_bytes_to_check

)

{

    #define BLANK_MEM 0xFF

    uint32_t used_mem_position;

    uint32_t addr;

 

    //aligned to phrases(8 bytes)

    unsigned char       byte_data_counter = 0;

    uint32_t            offset = ((uint32_t)src_ptr) & 0x00000007;

 

    /* read address mod 8 correction */

    if (offset)

    {

        /* align pointer to writable address */

        src_ptr -= offset;

       

        /* jump over old data */

        num_bytes_to_check += offset;

    }   

 

    /* Is the write area erased ? */

    for(used_mem_position = num_bytes_to_check; used_mem_position > 0; used_mem_position--)

    {

        /* Workaround for bug in CodeWarrior: do not optimize following two lines! */

        char *tested_byte = src_ptr + used_mem_position - 1;

        if((char) *tested_byte != (char) BLANK_MEM)

            /* return last non-free byte possition */

            return used_mem_position;

    }

    /* space is free */

    return 0;

}

flashx.PNG

Outcomes