Writing uint64_t on a specific memory address.

Hello all,

i need to save uint64_t in to a specific memory address.

in main. c
__attribute__((section(".flash_id_number"))) const uint64_t my_id_number = 0x1500080507032592;
i have create my .ld file named: my_memory.ld
SECTIONS
{
   .flash_id_number 0x40000 :
   {
      *(.flash_id_number)
      KEEP(*(.flash_id_number*))
   } > FLASH
}
i have edited CMakeList.txt as follow:
#
# Copyright (c) 2021 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#
cmake_minimum_required(VERSION 3.20.0)

set(LINKER_SCRIPT "C:/Users/Enrico/PTT_Dual_2_0/my_memory.ld")

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
but when i build the project i can not see in zephyr.hex the number that i writte.
I made another attempt and modified the linker.cmd file as follows:
....
ztest :
{
 _ztest_expected_result_entry_list_start = .; KEEP(*(SORT_BY_NAME(._ztest_expected_result_entry.static.*))); _ztest_expected_result_entry_list_end = .;
 _ztest_suite_node_list_start = .; KEEP(*(SORT_BY_NAME(._ztest_suite_node.static.*))); _ztest_suite_node_list_end = .;
 _ztest_unit_test_list_start = .; KEEP(*(SORT_BY_NAME(._ztest_unit_test.static.*))); _ztest_unit_test_list_end = .;
 _ztest_test_rule_list_start = .; KEEP(*(SORT_BY_NAME(._ztest_test_rule.static.*))); _ztest_test_rule_list_end = .;
} > FLASH

.flash_id_number 0x40000 :
{
   *(.flash_id_number)
   KEEP(*(.flash_id_number*))
} > FLASH
....

It works, and I can see the values written at the correct memory address, but when I recompile the main.c it deletes the changes in the linker.cmd file, and I no longer have the values at the correct memory address.

I'm using nrf52840 and ncs 2.6.1

Can you help me in some way?

Parents
  • Hello all,

    i have edited main.c like follow:

    void write_memory_id_number_(void){
        const struct device *flash_id;
        struct flash_area *fa;
        uint64_t my_id_number = 0x1500080507032592;
        uint64_t data_read;
        int rc;
        
        /*DON'T REMOVE THE COMMENTS HERE BELOW... IT WILL NOT WORK*/
        /*flash_id = device_get_binding("flash_id_number");
        if (!flash_id) {
            printk("Error\n");
            return;
        }*/
    
        rc = flash_area_open(FLASH_AREA_ID(flash_id_number), &fa);
        if (rc != 0) {
            printk("Error flash_id_number: %d\n", rc);
            return;
        }
    
        rc = flash_area_erase(fa, 0, fa->fa_size);
        if (rc != 0) {
            printk("Error flash_id_number: %d\n", rc);
            flash_area_close(fa);
            return;
        }
    
        rc = flash_area_write(fa, 0, &my_id_number, sizeof(my_id_number));
        if (rc != 0) {
            printk("Errore flash_id_number: %d\n", rc);
        } 
    
        rc = flash_area_read(fa, 0, &data_read, sizeof(data_read));
        if (rc != 0) {
            printk("Error: %d\n", rc);
        } else if (data_read == my_id_number) {
            printk("OK \n");
        } else {
            printk("Error:  0x%x no equals to 0x%x\n", data_read, my_id_number);
        }
    
        flash_area_close(fa);
    }

    edited .overlay file like follow:

        partitions {
            compatible = "fixed-partitions";
            #address-cells = < 0x1 >;
            #size-cells = < 0x1 >;
            boot_partition: partition@0 {
                label = "mcuboot";
                reg = < 0x0 0xc000 >;
            };
            slot0_partition: partition@c000 {
                label = "image-0";
                reg = < 0xc000 0x75000 >;
            };
    
            flash_id_number: partition@81000 {
                label = "flash_id_number";
                reg = < 0x81000 0x1000 >;
            };
            slot1_partition: partition@82000 {
                label = "image-1";
                reg = < 0x82000 0x76000 >;
            };
            storage_partition: partition@f8000 {
                label = "storage";
                reg = < 0xf8000 0x8000 >;
            };
        };

    I can save data in flash file. But if i change memory address doesn't on hex file. 
    It is correct what i do?
    Where I'm wrong?

  • Hi,

     

    Using a linker script to place a variable at a absolute address is possible, but you have to be aware that the linker does not handle fragmentation well. For example, if you place a var inside a region, such as "FLASH", the linker will not split up the region and handle any gaps in address space.

    The recommendation if you need to both read and write to a region is to place the region at the end of your flash layout, and address it.

     

    Do you need to be able to erase and re-write the "my_id_number"? If not, I would then recommend to look at the UICR.OTP[] area for storing a specific ID.

     

    Kind regards,

    Håkon

  • No, I do not need to be able to erase and re-write "my_id_number".
    I just need to set it one time, keep it in a specific memory address and read it every time at power on.

    It can happens that this number could be change in the future. UICR.OTP[] is not good for us.

    Can you provide me a sample?

    Thanks

  • Hi,

     

    It is unclear to me if this variable/number can change or not, based on your description. 

    If you cannot use UICR, then I would recommend the settings subsys, or set aside a specific page/section for your user-specified data at the end of flash.

     

    Kind regards,

    Håkon

Reply Children
Related