Solution for Error - section '.udata_main.o' can not fit the section

The Microchip MPLAB C18 linker may give the message Error - section '.udata_main.o' can not fit the section. Section '.udata_main.o' length=0x00000XXX, perhaps with a different section name. There are several related, but different, causes for this error.

If the error refers to a '.code' or '.romdata' section, such as '.code_sralloc.o', this means you're out of code space. There is no software workaround for this. Ensure you have all of the compiler's optimizations enabled; if that doesn't help, you need a bigger PIC or a better compiler.

If you have a single object that is 257 bytes or larger, it will trigger this error. The fix for this error is here. Do not apply this fix unless you have single objects that are 257 bytes or larger.

If you're using one of the older USB PICs (18F2455, 18F2553, 18F4550, 18F2550, 18F4455, or 18F4553), your problem might be caused by the poorly-written linker script used by these PICs. These linker scripts have 1KB of RAM marked as PROTECTED, making it unavailable to your application. This is unnecessary with recent versions of the USB stack, because the stack places USB objects at absolute locations. The solution is to copy the linker script into your project and remove the PROTECTED keyword from the usb4, usb5, usb6, and usb7 memory regions.

If none of the above apply, the solution to the error is described below. If you have objects larger than 256 bytes, and you make the changes described in the above link for large objects, and you still get this error, come back here for the remainder of the fix -- in some cases, both fixes are required.

If you've applied all of the relevant fixes, and you still get the error, it means you're out of RAM. There is no user-friendly out of RAM message from the C18 linker.


When compiling a source file, say main.c, C18 places all of that file's uninitialized data into a single udata section, and all of its initialized data into a single idata section. Uninitialized data includes definitions such as
int a, b;
Initialized data includes definitions of data which is initialized at program startup, such as
char C18[] = "No one will ever need more than 256 bytes";
This applies only to objects in RAM with static storage duration; that is, objects defined at file scope, or using the static storage class specifier at block scope. Automatic variables defined inside functions are placed on the stack, not in idata/udata sections. Objects with the rom qualifier are placed in romdata sections, not in idata/udata sections; however, certain declarations may put part of an object in idata rather than romdata.

At link time, the linker attempts to place each section into a memory region. A memory region is defined by a line in the linker file, such as

DATABANK   NAME=gpr1       START=0x100          END=0x1FF
In the default linker files, each memory region is, at most, 256 bytes (one bank) in size. Since a section must fit within a memory region, any section which is larger than 256 bytes will trigger a can not fit the section error from the linker.

C18 doesn't know anything about memory regions or anything else in the linker file, so it will place an unlimited amount of data into an idata/udata section. So even if each of your objects is smaller than 256 bytes, and your PIC has enough RAM for them, you can get linker errors. For example, these definitions in a single source file named main.c will cause a linker error:

unsigned char a[150];
unsigned char b[150];
This is because C18 will place both a and b into a section named .udata_main.o, and the linker can't place a 300-byte section into any of the 256-byte memory regions available. Note that the section name is based on the object file name, so if you were to move b into a file named foo.c, the linker error would be gone. This is because there are now two sections, .udata_main.o and .udata_foo.o, and each of those sections is 150 bytes. The linker can place each 150 byte section into a different memory region.

Fixing the Error

The fix is simply to instruct C18 to use more than one idata/udata section in a source file. This is done with the #pragma idata and #pragma udata directives. To correct the linker error from the two definitions above:
#pragma udata udata1
unsigned char a[150];

#pragma udata udata2
unsigned char b[150];

#pragma udata
int c, d;
When the compiler encounters a #pragma udata directive, it switches the default udata section name from .udata_filename.o to the specified section name. In the example above, the section name is switched to udata1, and a is placed in the udata1 section. Likewise, b is placed in the udata2 section. The #pragma udata without a section name instructs C18 to return to the default .udata_filename.o section for subsequent udata definitions, so c and d will be placed in the default section of .udata_main.o. Each of the sections will now fit into a memory region, and the link will be successful.

The section name specified with the #pragma can be any valid C identifier. The section name does not correlate to the memory region names in the linker file. For example, if you use

#pragma udata gpr1
this will not place subsequent objects into bank 1, even if you have a memory region named gpr1 in the linker file.

Other Notes

#pragma idata/udata simply switch the default section name for the specified type of data. Their proximity to a declaration is not relevant. For example,
#pragma idata idata1
unsigned char a[150];
does not have any effect on the placement of a. a is not initialized data, so it will not be placed into an idata section. This pragma will only affect any subsequent idata definitions.

As many idata/udata sections as needed can be created.

The closing #pragma idata/udata without a section name is not required. It's a good idea, though, to prevent subsequent definitions from filling up one of the newly-created sections and triggering another linker error.

Arrays of pointers to rom will be placed in an idata section unless properly qualified. For example, in this definition:

rom char *array[] =
   "string 1",
   "string 2"
the two strings are placed in ROM, but array is placed in an idata section in RAM. This is because the rom qualifier applies to what is on the left side of the *; i.e., what is being pointed to; the array itself is not rom qualified. Consequently, an array like this can trigger an idata linker error even though it appears to be in ROM. To put the array itself in ROM:
rom char * rom array[] =
   "string 1",
   "string 2"

Copyright © 2009 John Temples (pic at xargs dot com)