How to save uint32_t variable to a specific address in flash memory in nrf connect sdk?

Hello. How to save uint32_t variable to a specific address in flash memory in nrf connect sdk? in other projects this was solved by allocating a custom flash memory section in the linker script, and also using __attribute__((section("name"))). But in zephyr the linker script is generated during assembly. If it's not difficult, give an example of how to implement this, thanks in advance

Parents
  • Hello,

    In the NRF Connect SDK, you can save a uint32_t variable to a specific address in flash memory by using the Flash Storage API provided by the Zephyr RTOS. Here's an example of how you can implement this:

    1. Define the custom flash section and symbol in your application's prj.conf file:


    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_CUSTOM_FLASH_SECTION=y
    CONFIG_CUSTOM_FLASH_SYMBOL="__custom_flash"

    2. Create a custom linker script for your application. Create a file named custom.ld in your project directory and add the following contents:


    SECTIONS {
    .custom_flash_section :
    {
    KEEP(*(.__custom_flash))
    } > flash
    }

    3. Update your CMakeLists.txt file to include the custom linker script. Add the following line:

    undertale yellow

    set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_SOURCE_DIR}/custom.ld)

    4. In your source code, declare and define your uint32_t variable and place it in the custom flash section using the __attribute__((section("name"))) attribute:

    c
    
    #include <zephyr.h>
    #include <device.h>
    #include <drivers/flash.h>
    
    __attribute__((section(".custom_flash_section")))
    uint32_t my_variable = 42;


    5. To save the variable to flash memory, use the Flash Storage API provided by Zephyr. Here's an example of how you can do this:

    c
    
    #include <zephyr.h>
    #include <device.h>
    #include <drivers/flash.h>
    
    void save_variable_to_flash(void)
    {
    const struct device *flash_dev;
    int err;
    
    flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
    if (!flash_dev) {
    printk("Flash device not found\n");
    return;
    }
    
    uint32_t flash_address = (uint32_t)&my_variable;
    
    err = flash_write_protection_set(flash_dev, false);
    if (err) {
    printk("Failed to disable flash write protection\n");
    return;
    }
    
    err = flash_write(flash_dev, flash_address, &my_variable, sizeof(my_variable));
    if (err) {
    printk("Failed to write variable to flash\n");
    return;
    }
    
    err = flash_write_protection_set(flash_dev, true);
    if (err) {
    printk("Failed to enable flash write protection\n");
    return;
    }
    
    printk("Variable saved to flash\n");
    }


    Make sure to adjust DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL to match the label of the flash controller in your device tree.

  • Hello, thanks for the answer, I'll definitely try it. I need to save a variable as a constant when compiling. Will this method work with a const specification?

Reply Children
No Data
Related