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

How do I read my .map file?

I am trying to free up some RAM on my nRF because I am getting Fatal error 0x4, NRF_ERROR_NO_MEM when I try to increase the size of a 2D array. 

I do not understand how to read my map file. This is the file that contains all my symbols, correct? I sorted all the symbols by size and this is what I get: 

Apparently all the ".debug_str" take up 11 MB total? That's a lot but if it's all in flash then I don't care. I want to free up RAM. How do I list only the RAM symbols? Do I just delete the entire ".text" section from the .map file?

I filtered out all the ".debug" symbols and I'm left with this: 

First of all, what is the difference between ".bss.ucHeap" and ."heap"? 

Secondly, I changed my makefile to make the heap size = 0 and my stack size bigger (from 2048 bytes to 3072), but my application STILL Fatal errors with 0x04 when I try to increase the size of a 2D array from [2][75] to [2][140]. I am only using 130 more bytes in the array. Why can't my stack handle it if I just increased its size from 2048 bytes to 3072? I am not using malloc() anywhere. 

New map file after stack/heap modification: 

  

  • You should consider using objdump. I found it useful to dump all the symbols from the ELF file, sort or grep them by type (data, code, whatever), and then by size. In my case, I quickly realised that the heap reserved by the linker script was huge and unnecessary, and that the heap reserved by FreeRTOS was also huge. I've switched to static allocation for pretty much all objects as this means that the linker will complain long before I have to deal with runtime error codes.

  • Apparently all the ".debug_str" take up 11 MB total? That's a lot but if it's all in flash

    The nRF52832 only has 512K of Flash - so they clearly can't be in Flash!

    These are debug symbols - not loaded into the device at all.

    Do I just delete the entire ".text" section from the .map file?

    No!

    The .text section is where the code goes!

    https://en.wikipedia.org/wiki/Code_segment

    Another useful tool for seeing what's using up memory is nm

    https://en.wikipedia.org/wiki/Nm_(Unix)

    See your toolchain documentation for details

    EDIT

    Try this: www.google.com/search

  • This was helpful. I didn't know ".bss.ucHeap" is the FreeRTOS heap. Mine was set to 8192. I lowered it to 4096 and FreeRTOS crashed. I lowered it to 8000 and FreeRTOS seemed to run, but then when I increased my array size from 140 to 280, I still got a runtime error NRF_ERR_NO_MEM even though I can see in the map file that my array is now 0x112 = 280 bytes as expected. So I'm not clear as to why disallocating 192 bytes and then reallocating 140 bytes causes a runtime error. 

  • I made a symbol table of everything in my map file from RAM start address 0x20002400 to (0x20002400 + 0xDC00). They add up to 21556 bytes, not the expected 56kbytes. And why is the RAM length only 56k bytes? Why isn't it 64k bytes since the chip has 64k RAM?

  • Hi,

    I did not follow your calculations and reasoning about why you would expect to fill all the RAM.

    Regarding the physical size, the application can typically not use all the RAM of the device. If you have a SoftDevice, then that will need some RAM as well. In your case the application RAM starts from 0x20002400, which I assume is because the SoftDevice use the RAM from 0x20000000 and upto 0x200023FF. I expect this matches your linker configuration.

    Regarding the original question: Note that there is no direct link between free space on the device and you getting NRF_ERROR_NO_MEM. If there is no more space in the heap, then you cannot allocate any more. That is regardless of if there is available space on the device or not, as long as that is not configured to be used for the heap.

Related