Why is the "can’t find space error" message issued even though there is plenty of space left in a device’s memory?

One of the main tasks the linker performs is positioning the blocks (or psects) of code and data that is generated from the program into the memory available for the target device.

There are a number of memory-related error messages and all roughly mean the same thing; that the produced code or data cannot fit into the available memory on the device. These errors are produced by the linker application.

For Example:

can’t find 0x* words for psect "*" in segment "*" (largest unused contiguous range 0x%lX)
can’t find 0x* words (0x* withtotal) for psect "*" in segment "*"
can’t find 0x* words for psect "*" in segment "*"

These errors indicate that the linker was unable to find an area of free memory large enough to accommodate one of the psects. The error message indicates the psect (named in the error) cannot be positioned in the segment (named in the error).

Please refer to the “Compiler-Generated Psects” section in the manual that lists each compiler-generated psect and what it contains. Typically, psects are related to program code. Names such as bss or data refer to data space.

Causes of these errors

First, the size of the program or the program’s data has exceeded the total amount of space on the selected device. In other words, some part of your device’s memory has completely filled. If this is the case, then the size of the specified psect must be reduced; i.e. the code must be reduced so that it can fit in the code segment.

The second cause of this message is when the total amount of memory needed by the psect being positioned is sufficient, but the available memory is fragmented in such a way that the largest contiguous block is too small to accommodate into the psect. The linker is unable to split the psects in this situation. That is, the linker cannot place part of a psect at one location and part somewhere else. The linker needs a contiguous block of memory large enough for every psect generated in the program. If this is the cause of the error, then if possible, the psect specified in the error must be split into smaller psects.

Interpreting the error messages

Can’t find 0x34 words (0x34 with total) for psect text in segment CODE (error) look in the map file for the ranges of unused memory.

UNUSED ADDRESS RANGES // Under Map file generated by the Compiler, after code build
CODE 00000244-0000025F

In the CODE segment, available memory is 0x1C (0x25F-0x244+1) in one block, and 0x30 available in another block (102F-1000).
Neither of these is large enough to accommodate the psect text which is 0x34 bytes long.
Notice, however, that the total amount of memory available is larger than 0x34 bytes, but the available memory is fragmented and the 34 bytes of code cannot be placed in this fragmented memory.

Example 1:
Error [1347] ; 0. can't find 0x2D words (0x2d withtotal) for psect "text2256" in segment "CODE" (largest unused contiguous range 0x1F)

Error [1347] ; 0. can't find 0x29 words (0x29 withtotal) for psect "stringtext" in segment "STRCODE" (largest unused contiguous range 0x1F)

UNUSED ADDRESS RANGES (From the map file)
Name Unused Largest block Delta
CODE 00800-00808 9 2
STRCODE 00800-00808 9 2

The "can't find space" error occurs in the psect CODE and STRCODE because they fall short of 0x2D and 0x29 words respectively (as pointed out in the error message above).

The unused space as seen from the map file in the CODE Segment is 0x9 bytes and the STRCODE Segment is 0x9 bytes, which isn't enough to allocate the 0x2D and 0x29 words.

Solutions to avert this error in the code are:

  1. Use all the compiler’s optimizations.
  2. Restructuring the program. Split a function into two or more smaller functions that may call each other. These functions may be placed in new modules.
  3. Program may need to be rewritten so that it needs fewer variables. Reduce the number of auto variables.

Example 2:
Error [1347] ; 0. can't find 0x2 words (0x2 withtotal) for psect "wdtbss" »>in class "BANK0" (largest unused contiguous range 0x0)

The error indicates that the linker has run out of space in RAM Bank 0. From the memory map, Bank0 is 96% full and all the other banks are relatively free. It is recommended to move some of the variables into other banks.
The solution is that some variables need to be moved into banks one, two, or three.
You do this by prefixing the variable declarations with a qualifier like "bank1".

For example:

In the device, there are x banks of yy bytes. Move some variables to another bank, by the following method:

Naturally, you should group variables often accessed together in the same bank. You can't use the bank qualifiers with auto variables, functions, or parameters, but it can be used with static variables.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.