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.

[CC2541] How many data for user in flash

Hi,

It may be a simple problem but I cannot find the exact answer.

I need to store 3200 Bytes of data for my application. So I'm looking into flash's API and I found the non-volatile memory API (OSAL) but in the guide it says that user data can be stored from 0x80 to 0xFE. If I'm not mistaken, it means I have 126 WORD so 504 bytes to store.

Is there any solution to store more data ? I'm using SensorTag project from BLE Stack 1.4 and I don't use sensors, just one led and one button.

Thanks for your help,

regards,

  • That's the NV ID's range, not the address range. Osal snv has around 64KB 4KB of space by default. The flash address is abstracted away. You only need to keep track of ID's

  • Ok I understand, so can I use a single ID to store 3200 Bytes or there is a limitation ?


  • Arthur, 

    Because of the load-levelling algorithm employed by the SNV driver, the size of any item can never exceed the size of one flash page (2KB). There may be other restrictions as well like the range of the length attribute. 

    To store a solid block of 3.5 KB data, I would recommend you modify your linker file to reserve two whole flash pages for this purpose. Then you can use hal_flash_write(...) and hal_flash_read(...) to access it. 

    Peder

  • Ok thanks for these information, it will be simpler for me to use 2 IDs with SNV driver.


    I'm unable to link the project because osal_nv_item_init and osal_nv_write raised "undefined external". Do I have to link a specific .lib ? Or something to set in preprocessor ?


    Thanks

  • Peder is right. My earlier post about the SNV's size is wrong. The linker file you downloaded with the v1.4 stack reserves 4KB space by default. Its called BLENV_ADDRESS_SPACE

  • Ok I'm trying to understand each part in order to use correctly hal_flash now.

    I inspected the file ti_51ew_cc2540b.xcl because it was the file used by the linker in my project. And I found all information you gave me, but I cannot understand how I can use HalFlash API instead of OSAL API.

    For instance, I have this code:

    uint32 myvar = 0xABCDEF34;
    HalFlashWrite(0x7E800 / 4, &myvar, 4);
    
    uint32 readvar=0;
    HalFlashRead(0x7E800 / HAL_FLASH_PAGE_SIZE, 0x7E800 % HAL_FLASH_PAGE_SIZE, &readvar, 4);

    Does this code will write then read the same value ?

    Do I have to call HalFlashErase before writing in a page ?


    Thank for your help

  • I tried the code I sent before and it halts when it is executed.


    Do you know what do I have to do to use osal_nv API that seems to be much simpler ?


    Thanks

  • This code is beautifully commented in some areas. Don't shun that.

    /**************************************************************************************************

    * @fn HalFlashWrite
    *
    * @brief This function writes 'cnt' bytes to the internal flash.
    *
    * input parameters
    *
    * @param addr - Valid HAL flash write address: actual addr / 4 and quad-aligned.
    * @param buf - Valid buffer space at least as big as 'cnt' X 4.
    * @param cnt - Number of 4-byte blocks to write.
    *
    * output parameters
    *
    * None.
    *
    * @return None.
    **************************************************************************************************
    */

  • Ok but I have something different that means something different... :

    /**************************************************************************************************
     * @fn          HalFlashWrite
     *
     * @brief       This function reads 'cnt' bytes from the internal flash.
     *
     * input parameters
     *
     * @param       addr - Valid HAL flash write address: actual addr / 4 and quad-aligned.
     * @param       buf - Valid buffer space at least as big as the 'cnt' parameter.
     * @param       cnt - Valid number of bytes to write: a write cannot cross into the next 32KB bank.
     *
     * output parameters
     *
     * None.
     *
     * @return      None.
     **************************************************************************************************
     */

    Is my page computation correct ? 0x7E800 / HAL_FLASH_PAGE_SIZE

    Is my offset computation in the page correct ? 0x7E800 % HAL_FLASH_PAGE_SIZE

  • This question does not appear to have been answered. Arthur has pointed out that the documentation (in 'hal_flash.h') is different to what Peter referred to (the definitions of 'buf' and 'cnt' are different, and the @brief definition says the 'write' function is for reading!!

    Anyway, is there any reliable documentation for using these functions?

    -  it's clearly incorrect in 'hal_flash.h'

     - It isn't mentioned in the HAL Driver API.pdf.

    - the OSALAPI.pdf describes OSAL_NV... but this doesn't appear to be supported alongside the BLE stack;

    - the OSALAPI.pdf also describes OSAL_SNV... but as others have pointed out this is very limited (no obvious way to erase, for example)

    One basic question I have is why does the write function use an address parameter, whilst the read and erase use a page parameter? I assume there's a good reason but it's very confusing for users without a documented explanation.

  • The addressing code is hardware related. It is helpful to be familiar with the banking memory model of the 8051 architecture to completely understand

    To read, The uP checks out a bank. Each bank has a range of pages. Given the page number, it is simple to figure out what bank you want. Then you need to know the offset into that page. Then the MCU manually moves bytes to the destination one at a time. Hence why the count is in bytes

    To write, a 16 bit address is loaded into the FADDR registers. The function uses the DMA which moves 4 byte words at a time. That's why the counts is in words

    The flash functions are lightweight and only take exactly what is needed  as arguments  That's why they take different augments.

  • Thanks for detailed information Peter

    I did'nt find out why my code doesn't work... Do you see any mistakes ? Thanks ;)

    uint32 myvar = 0xABCDEF34;
    HalFlashWrite(0x7E800 / 4, &myvar, 4);
    uint32 readvar=0;
    HalFlashRead(0x7E800 / HAL_FLASH_PAGE_SIZE, 0x7E800 % HAL_FLASH_PAGE_SIZE, &readvar, 4);

  • The CC254x only has 256K of flash. You are attempting to write to the 518,144th byte (which doesn't exist).

  • Peter, this doesn't seem very helpful. The linker file defines the BLE NV address space at 0x7E800:

    // Internal flash used for NV address space.
    // ---------------------------
    //
    // Address range for HAL_FLASH_PAGE_SIZE == 2048
    -D_BLENV_ADDRESS_SPACE_START=0x7E800
    -D_BLENV_ADDRESS_SPACE_END=0x7F7FF

    ...so can you suggest a correction to Arthur's code? In fact, if the address is changed to 0x7F000, it works. But 0x7E800 is already used by the BLE stack so that's why that address doesn't work. Surely it's nothing to do with trying to write to a byte which doesn't exist.

    As I asked before, it would be really good to have a pointer to some useful documentation on how to use the flash in these devices alongside the BLE stack code..