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.

FlashProgram() and FlashSectorErase() functions in flash.c not working

Hi,
i want to write data of 150 bytes to the location 0x0000d000 in flash. i choose this address after refering .map and icf files of App project. for writing data i did the following within my task


 uint8_t test[150] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
  ,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,
 77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36
  ,37,38,39,40,41,42,43,44,45,46,47,48,49,50};

  FlashTest = FlashSectorErase(0x0d000);
  FlashTest1 = FlashProgram(test, 0x0d000, 150);

But when i couldnt see any data on this address when debugging. why these functions not working???
(please doont suggest osal_snv_read, write functions, i want to write other flash locations NOT SNV)

  • Hi
    I could resolve this by adding disableCache() function
  • Yes, as mentioned in other posts, the nvocop.c file (used when OSAL_SNV=1) can serve as an example for direct writes to flash.

    Best wishes
  • Hi Abhijith,

    The flash memory address space must not be accessed by CPU while programming the flash memory. So, FlashSectorErase() and FlashProgram() must be run in ROM or SRAM. And during the API calls, the CPU should not be switched to other tasks which is running on flash memory. So, the interrupts should be disabled.

    I have been using FlashSectorErase() and FlashProgram() with interrupts disabled for couple of months. Everything seems fine.
  • hi,
    do you know how to read flash memory??. i could find only one function "FlashEfuseReadRow ". But it reads a row only.

  • Hi
    I cant read falsh using FlashEfuseReadRow . i tried this function like this, it writes successfully but reads nothing
    state = disableCache();
    FlashTest1 = FlashProgram((uint8_t*)&x, Wrtptr, sizeof(x));
    rstatus = FlashEfuseReadRow ((uint32_t*)&y, FLASH_READPTR_MIN); // #define FLASH_READPTR_MIN 45056
    enableCache(state);
    Wrtptr = Wrtptr + sizeof(x);
  • This is my debugg window. here i want to read data written to 0b000. for that i have added row no of 2816 (decimal of 0b000/16) in FlashEfuseRead(). but i cant read that data to testrx (as pointed by Up arrow)

  • Hi Abhijith,

    Reading flash memory is like normal memory access. You can declare a pointer pointing to the desired flash memory address and then use memcpy() to copy data to a buffer.

  • Hi rcfocus
    Thank You for your reply, I could copy data from flash using memcpy.
  • and one more thing i wnat to know is , how to make sure a sector is not previously erased before doing an erase?

  • Hi Abhijith,

    It is OK to erase a sector repeatedly. An erase operation is actually to set all bits to '1'. And a program operation is to clear necessary bits to '0'.

    In fact, what you need to consider seriously is "how to prevent data corruption if power lost during flash programming". Usually I use ping-pong buffers for reliability. For example, you can preserve two sectors (total 8KB) to save data. By defining a serial number at the first byte of both sectors, you compare the first byte to know which one is newest. When updating data, you erase and program the older one. Please note that 0xFF should not be used as serial number due to it is the same value when a sector is erased.

    To prevent data corruption, I also implement checksum of both sectors. When loading data from one of the sectors, I will calculate and compare checksum. If it is not matched then I will load data form the other sector.
  • HI ,
    I am doing like this. i am using 3 sectors. here test[1024] nad testrx[512] are 2 character arrays. flag is set to one inside a periodic event handling function.but there is an issue. write pointer (wrtptr and dwrtptr) increments even if "test" array not contain any value(empty).
    if(flag == 1)
    {
    state = disableCache();

    /* Erasing Next Sector to be written */

    if( dWrtptr >= FLASH_SECTR3_END )
    {
    SYS_START = 0; /* First cycle completed */
    dWrtptr = FLASH_SECTR1_START; /* dWrtptr points to the next sector to be erased */
    FlashTest = FlashSectorErase(dWrtptr);
    Sec3EraseFlag = 0; /* Status: Sector 3 written , Sector 2 written , Sector 1 Erased */

    /* If read pointer is in Erased sector , push it to next sector */

    if((Rdptr >= FLASH_SECTR1_START) && (Rdptr <= FLASH_SECTR1_END )&&( SYS_START == 0 ) )
    {
    Rdptr = FLASH_SECTR2_START;
    }
    }
    else if((dWrtptr >= FLASH_SECTR2_START) && (dWrtptr <= FLASH_SECTR2_END)&&(SYS_START == 0)&&(Sec2EraseFlag == 0))
    {
    dWrtptr_temp = dWrtptr;
    dWrtptr = FLASH_SECTR2_START;
    FlashTest = FlashSectorErase(dWrtptr);
    dWrtptr = dWrtptr_temp;
    Sec2EraseFlag = 1; /* Status: Sector 3 written , Sector 2 Erased , Sector 1 Written */

    /* If read pointer is in Erased sector , push it to next sector */

    if((Rdptr >= FLASH_SECTR2_START) && (Rdptr <= FLASH_SECTR2_END )&&( SYS_START == 0 ) )
    {
    Rdptr = FLASH_SECTR3_START;
    }
    }
    else if((dWrtptr >= FLASH_SECTR3_START) && (dWrtptr <= FLASH_SECTR3_END)&&(SYS_START == 0)&&(Sec3EraseFlag == 0) )
    {
    dWrtptr_temp = dWrtptr;
    dWrtptr = FLASH_SECTR3_START;
    FlashTest = FlashSectorErase(dWrtptr);
    dWrtptr = dWrtptr_temp;
    Sec2EraseFlag = 0; /* Status: Sector 3 Erased , Sector 2 Written , Sector 1 Written */
    Sec3EraseFlag = 1;

    /* If read pointer is in Erased sector , push it to next sector */

    if((Rdptr >= FLASH_SECTR3_START) && (Rdptr <= FLASH_SECTR3_END )&&( SYS_START == 0 ) )
    {
    Rdptr = FLASH_SECTR1_START;
    }
    }

    /* Read & Write pointers back to start position */

    if( Rdptr >= FLASH_SECTR3_END )
    {
    Rdptr = FLASH_SECTR1_START;
    }
    if(dWrtptr == FLASH_SECTR1_START)
    {
    Wrtptr = FLASH_SECTR1_START;
    dWrtptr = dWrtptr + sizeof(test);
    }

    /* Program Flash and increment Wrtptr & dWrtptr */

    if( FlashProgram(test, Wrtptr, sizeof(test))== FAPI_STATUS_SUCCESS)
    {
    Wrtptr = Wrtptr + sizeof(test);
    dWrtptr = dWrtptr + sizeof(test);
    }
    enableCache(state);

    /* Current write setctor pointer */

    if ((Wrtptr >= FLASH_SECTR1_START )&&(Wrtptr <= FLASH_SECTR1_END ))
    {
    WrtSecPtr = 1;
    }
    else if((Wrtptr >= FLASH_SECTR2_START )&&(Wrtptr <= FLASH_SECTR2_END ))
    {
    WrtSecPtr = 2;
    }
    else if((Wrtptr >= FLASH_SECTR3_START )&&(Wrtptr <= FLASH_SECTR3_END ))
    {
    WrtSecPtr = 3;
    }

    /* Current Read setctor pointer */

    if ((Rdptr >= FLASH_SECTR1_START )&&(Rdptr <= FLASH_SECTR1_END ))
    {
    RdSecPtr = 1;
    }
    else if((Rdptr >= FLASH_SECTR2_START )&&(Rdptr <= FLASH_SECTR2_END ))
    {
    RdSecPtr = 2;
    }
    else if((Rdptr >= FLASH_SECTR3_START )&&(Rdptr <= FLASH_SECTR3_END ))
    {
    RdSecPtr = 3;
    }

    /* Check Read & Write pointers are in same sector */

    if( WrtSecPtr == RdSecPtr)
    {
    /* Read data only upto write pointer */
    if( Rdptr < Wrtptr )
    {
    memcpy((uint32_t*)testrx,(void *)Rdptr,sizeof(testrx));
    Rdptr = Rdptr + sizeof(testrx);
    }
    else
    {
    while(1);/* No Data to read */
    }

    }
    else
    {
    memcpy((uint32_t*)testrx,(void *)Rdptr,sizeof(testrx));
    Rdptr = Rdptr + sizeof(testrx);

    }

    flag = 0;
    }
  • hI
    I have another problem . i am trying to read the flash and send it to mobile app whenever a req comes from app. for that i ahve used mempy function. But device get disconnected when control hits memcpy.
  • Hi,
    i want to send data from flash to mobile app as notifications. for that i used memcpy. but the problem is device get disconnected when it tries to execute memcpy. do you know the reason????. i have not faced any other issue in using memcpy.
  • Hi,

    Suggest you to try to copy a small amount of data at first. If copy 1 byte is OK then test 2 bytes. If 2 bytes is OK then test 10 bytes.... What is the data about when it fails?

    Btw, you don't need to post the same issue across forums.
  • Hi,

    Maybe a lot of time later but now I working on something like this.

    After digging deep into hal_flash.h, flash.h, nvocop.c, hal_flash_wrapper.h I realize that you can not write a flash address if that address does not contain 0xFF because writing to flash is a bit AND operation following the rule that 1 can remain 1 o can be changed to 0, but if 0 cannot be changed to 1. For example if at address 0x0000C000 you have 0xFE (b'11111110) and try to write 0x01 (b'00000001) the LSB '0' AND '1' gives '0' but you are trying to write '1' so rule is not followed and no write operation is done.

    First it is necessary to erase the page (each page is 4096 bytes long or 0x1000). Erasing flash with HalFlashErase() will cause to change the entire page, so if I erase page 0x0000C000, locations from 0x0000C000 to 0x0000CFFF will be set to 0xFF. I don't know exactly if it is possible to write just a few bytes without erasing entire page. It is important to not write (nor erase) program code in flash while executing that code and of course erasing an entire page could damage your code.

    My solution (ble_cc26xx_2_01_01_44627 and RTOS 2.14.3.28) was to use page 0x000C000 for writing and reading. This page is the last page of my application, just before stack. This way i can erase the entire page and write needed values but this solution obviously requires one free page. Probably I will implement some robustness mechanism as suggested by Robert Chen.

    I understand from others posts that osal_svn is used to write less than one page (actually up to 256 bytes per write operation and up to 4096 bytes {yeah! one page} if OSAL_SNV = 2) but it is restricted to FLASH_LAST_PAGE address that goes after stack image.