kinetis k60 flashx write doesn't work

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

kinetis k60 flashx write doesn't work

Jump to solution
1,803 Views
dingo
Contributor III

I wrote an experimental bootloader that load the user application in binary format at the address 0xe000 of the k60N512 the file have more than 400KB and fill Block0 and Block1 of the flash , the declared size of flashx is (0x80000-0xE000) ie whole space after the bootloader.

This application work fine with MQX3.7 but with MQX3.8.1 the flashx write()  seems do not work correct when switching from Block0 to Block1 at this point the Function _io_flashx_find_correct_sectors() give an incorrect "location" that rise an unhandled interrupt when try to write() at this location (a huge number).

The flow of the porgram is:

..

..

..

fseek(flash_hdl, sectorOffset, IO_SEEK_SET);

write(flash_hdl, tempBuf, sizeof(tempBuf));

..

..

the   "sectorOffset" is the liniar offest of the sector relative to the start of the binary file and to the start of flashx (0xe000).

When sectorOffset=204800 the write function rise an unhandled interrupt,  the corresponding address in the flash space of K60N512 is 204800 +0xE000= 0x40000 ie the start of Block1.

Could someone help with this issue?

Thanks

Stefan Tripac

0 Kudos
1 Solution
742 Views
Martin_
NXP Employee
NXP Employee

I tried your example and see the error. It is in _io_flashx_find_correct_sectors() function in MQX 3.8.1. We've identified the root cause and fixed it for MQX 4.0 which is shortly out.


This problem occurs for flashx configuration is which a flashx_file (defined by structure FLASHX_FILE_BLOCK) spreads over more than one flashx_blocks (as defined by FLASHX_BLOCK_INFO_STRUCT). It does not occur if a flashx_file fits to one flashx_block.

View solution in original post

0 Kudos
7 Replies
741 Views
dingo
Contributor III

To make the problem more accesible for the community  I have modified the "flashx" example project in MQX3.8.1 I have also posted the problem to Service Request , I pasted the text here:

I work with twrk60n512, IAR Ewarm 6.3, MQX3.8.1 ,using the flashx example project modified (attached archive) :

I open a file in flashx with size : 0x80000-0xB800 (modification in twrk60n512.h and recompile the BSP)

In the "flash_demo.c " file I have modified:

FLASH_NAME "flashx:"

also the fseek() for example write() was modified to:

fseek(flash_file, 215040, IO_SEEK_SET);

the location 215040 is relative to the start of flashx file and match the Block1 start address: 215040 +0xB800=0x40000 in flash map.

when trying to execute the write() function, an unhandled interrupt is triggered.

Cause ? in function : _io_flashx_find_correct_sectors() (file: flashx.c)
the "location" variable have a huge unaccepted value=4294920191.

This problem didn't appear when using MQX3.7.

0 Kudos
741 Views
Martin_
NXP Employee
NXP Employee

I met similar problem on different compiler (CodeWarrior for Power Architecture). The problem was that the break on line 626 was compiled as return, so the if statement was skipped. It was some compiler optimization. For myself the following modification to the _io_flashx_find_correct_sectors() worked:

void _io_flashx_find_correct_sectors

   (

      /* [IN] The device handle */

      MQX_FILE_PTR         fd_ptr,

      /* [IN] The linear address within the file */

      _mqx_uint            location,

      /* [IN/OUT] The HW start block for the write */

      _mqx_uint _PTR_      start_block_ptr,

      /* [IN/OUT] The start sector in the start_block */

      _mqx_uint _PTR_      start_sector_ptr,

      /* [IN/OUT] The offset within the first sector */

      _mqx_uint _PTR_      offset_ptr,

      /* [IN/OUT] The relative sector number within the file */

      _mqx_uint _PTR_      file_sector_ptr

   )

{  /* Body */

    IO_FLASHX_STRUCT_PTR dev_ptr = (IO_FLASHX_STRUCT_PTR) fd_ptr->DEV_PTR->DRIVER_INIT_PTR;

    IO_FLASHX_FILE_STRUCT_PTR file_ptr = (IO_FLASHX_FILE_STRUCT_PTR) fd_ptr->DEV_DATA_PTR;

    FLASHX_BLOCK_INFO_STRUCT_PTR b;

    volatile FLASHX_BLOCK_INFO_STRUCT_PTR b_temp;

    _mem_size sfa; /* start file address */

    _mem_size bsa, bea; /* block start address, block end address */

    *file_sector_ptr = 0;

    *start_block_ptr = 0;      

    if (file_ptr->FILE_BLOCK == NULL) {

        sfa = 0;

    }

    else {

        sfa = file_ptr->FILE_BLOCK->START_ADDR;

    }

    /* Go through all blocks in HW map and find the first one that matches */   

    for (b = dev_ptr->HW_BLOCK; b->NUM_SECTORS != 0; b++)

    {   

        bsa = dev_ptr->BASE_ADDR + b->START_ADDR;

        bea = bsa + b->NUM_SECTORS * b->SECTOR_SIZE - 1;

        b_temp = b;

        if ((sfa >= bsa) && (sfa <= bea))

        {           

            break; /* start address of the file is inside the block */

        }

        *start_block_ptr += 1;

    }

    if (b_temp->NUM_SECTORS != 0) {   

        /* Rebase location so that is counts from the beginning of this block */

        location += sfa - bsa;

        /* We are at the beginning of the file, seek to the location */

        for (b = b_temp ; b->NUM_SECTORS != 0; b++)

        {

            if (b->NUM_SECTORS * b->SECTOR_SIZE > location)

            {

                *start_sector_ptr = location / b->SECTOR_SIZE;

                *offset_ptr = location % b->SECTOR_SIZE;

                /* recreate the location back, perhaps we will decrement the value */

                location -= sfa - bsa;

                *file_sector_ptr += location / b->SECTOR_SIZE;

                break;

            }

           

            location -= b->SECTOR_SIZE * b->NUM_SECTORS;

            *file_sector_ptr += b->NUM_SECTORS;

            *start_block_ptr += 1;

        }

    }

} /* Endbody */

Can you try to build MQX 3.8.1 libs with the modificaiton above and tell if this modification helps or not ?

0 Kudos
741 Views
dingo
Contributor III

Hi Martin,

I have made the changes but the result is the same "location" variable has a huge value when is reached the first sector of Block1, if you have twrk60n512 you can check the modified "flasx" example posted by me in the second reply.

Thank you,

Best regards,

Stefan T

0 Kudos
743 Views
Martin_
NXP Employee
NXP Employee

I tried your example and see the error. It is in _io_flashx_find_correct_sectors() function in MQX 3.8.1. We've identified the root cause and fixed it for MQX 4.0 which is shortly out.


This problem occurs for flashx configuration is which a flashx_file (defined by structure FLASHX_FILE_BLOCK) spreads over more than one flashx_blocks (as defined by FLASHX_BLOCK_INFO_STRUCT). It does not occur if a flashx_file fits to one flashx_block.

0 Kudos
741 Views
timias
Contributor IV

This defect is not completely corrected in MQX 4.0.

My psuedo code:

1- flashx write of 76 bytes

2- fseek back to where the write started. ( a few bytes before the bank1 boundary begins)

3- read the buffer again

4- do a buffer compare on the two.

Error:

The buffer from the read starts at the beginning of bank 1, not at the location where it should have.

0 Kudos
741 Views
Martin_
NXP Employee
NXP Employee

Hi Robert, thanks for the report!

I can reproduce the problem, it seems as something in the read function, because if I read the written data back by loading data directly from flash memory addresses, the written data are correct. Will report to the responsible team. 

0 Kudos
741 Views
dingo
Contributor III

Thank you Martin.

Best regards,

Stefan T

0 Kudos