This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Segger Embedded Studio - FDS - warning .stack and hardfault

Hello everyone,

I am trying to use Segger Embedded Studio for a simple explerimental project. I started from the sample FDS example from github and build something on it. Now I create some file/records and try to remove them.

I followed the instructions from the post on the UNPLACED sections from there : devzone.nordicsemi.com/.../

It does run but I still have an issue.

I have a warning while SES generates the linker file:

cannot place section .stack at end of segment because section .fs_data_run does not have a fixed size

I did not payed attention until my code tried to delete a record from the NVM and went systematically into Hardfault.

So I simply tried to add a size to the .fs_data_run section declaration in the xml file:

<MemorySegment name="$(FLASH_NAME:FLASH)">
     <ProgramSection alignment="4" load="Yes" runin=".fs_data_run" name=".fs_data" />
</MemorySegment>
<MemorySegment name="$(RAM_NAME:RAM);SRAM">
     (...)
     <ProgramSection alignment="4"  size="3072" load="No" name=".fs_data_run" address_symbol="__start_fs_data"  end_symbol="__stop_fs_data" />
</MemorySegment>

This made the warning disappear, however it did not took away the hardfault I encounter. According to what SES show while running step by step code, this hardfault happens exactly in the fds.c functionrecord_find_and_delete, at the moment the page is marked as ready for garbage collection even though the m_pages variable looks OK and is accessible to watch:

if (record_find_by_desc(&desc, &page))
{
  (...)
    // Flag the record as dirty.
    ret = record_header_flag_dirty((uint32_t*)desc.p_record);

    // This page can now be garbage collected.
    m_pages[page].can_gc = true;  // **<<<<----------- HARDFAULT**
}
else
{...

I cannot really say why this is happening. However I feel like it is really connected because if I build the exact same project using gcc it is working fine and I don't encounter any hardfault.

Did anyone encounter the same issue? Hopefully resolved it?

Thank you for your help!

[EDIT] Some of my parameters, if that could help: in sdk_config.h

#define FDS_ENABLED 1
#define FDS_OP_QUEUE_SIZE 4
#define FDS_CHUNK_QUEUE_SIZE 8
#define FDS_MAX_USERS 8
#define FDS_VIRTUAL_PAGES 3
#define FDS_VIRTUAL_PAGE_SIZE 1024

#define FSTORAGE_ENABLED 1
#define FS_QUEUE_SIZE 4
#define FS_OP_MAX_RETRIES 3
#define FS_MAX_WRITE_SIZE_WORDS 1024

And as macros in SES:

FLASH_START=0x1F000
SRAM_START=0x20002128
FLASH_SIZE=0x61000
SRAM_SIZE=0xded8
  • FormerMember
    0 FormerMember

    As mentioned in @RK 's answer, you do also need to define the linker symbols __start_fs_data and __stop_fs_data. In flash_placement.xml it will look like the following:

    <MemorySegment name="$(FLASH_NAME:FLASH)">
    ...
    <ProgramSection alignment="4" load="Yes" name=".fs_data" address_symbol="__start_fs_data"  end_symbol="__stop_fs_data" />
    <ProgramSection alignment="4" load="Yes" runin=".fs_data_run" name=".fs_data" />
    ...
    </MemorySegment>
    
    <MemorySegment name="$(RAM_NAME:RAM);SRAM">
    ...
    <ProgramSection alignment="4" load="No" name=".fs_data_run" address_symbol="__start_fs_data"  end_symbol="__stop_fs_data" />
    ...
    </MemorySegment>
    

    Did you add the below in thumb_crt0.s (also from @RK 's answer)?

      ldr r2, =__tdata_end__
    bl memory_copy
    # ADD HERE ... 
    ldr r0, =__fs_data_load_start__
    ldr r1, =__fs_data_start__
    ldr r2, =__fs_data_end__
    bl memory_copy
    # TO HERE ...
    
  • Well, my thumb_crt0.s was ok. I missed the definition of the symbols in the FLASH segment. I added it and removed my size from the RAM section to be aligned with what you are mentioning. And in fact this is even worse, the warning is back and it looks like the init of fds cannot go through. In my code I directly call fds_init() function. During this execution, a call to pages_init() occurs just after the fs_init(). In this pages_init() function there is a tentative of retrieving the address of the start page which fails:

    uint32_t        const * const p_page_addr = fs_config.p_start_addr + (i * FDS_PAGE_SIZE);
    

    p_page_addr = 0xffffffff after this call, and thus all this ends in a hardfault on the line that follows

    fds_page_type_t const         page_type   = page_identify(p_page_addr);
    
Related