Tuesday, January 8, 2013

Can't find 0x210 words (0x210 withtotal) for psect "swtext1" in segment "CONST"

Have you ever seen something like this:

Error [1347] ; 0. can't find 0x210 words (0x210 withtotal) for psect "swtext1" in segment "CONST" (largest unused contiguous range 0x100)

Well, I crashed my head over the table the whole morning playing with buffers sizes, defines, deleting functions etc... The linker kept giving me the above error. Then I searched and fount this thread. One cool thing about this thread is that it contains a pretty cool step-by-step on how to trace to the root of the problem:



The linker is saying "I was asked to place a section called swtext1 somewhere in the memory ranges defined by the class(segment) CONST. The largest contiguous chunk of memory I can find in these ranges is 100h words long, but the section I have to position is 210h words long. Help!"
A psect cannot be split, so this is what causes the difficulty. Imagine that there are 10 car spaces in a parking garage. You arrive there in your really long truck that needs two contiguous spaces for you to be able to park it. Although there are 10 free spaces, and you only need two, you will not find space to park your truck unless you can find two that are one behind the other--which is probably unlikely.
With these errors, always first look in the map file. You will notice that the definition for the CONST class will look something like:
-ACONST=00h-0FFhx16
which says that this range consists of 16 blocks, each of 100h words. (Just confirming the amount of memory that is available.) So if your section is 210h words long, it will never fit, even if none of this memory was used by other code. So what goes into the swtext1 segment? Look in the assembly list file. Search for this name and you will see it used with a PSECT directive. Look at the code following and see what C code it corresponds to.
This psect is not commonly used, but it is related to switch statements in your C program. It is only used if you are using a direct switch, or the compiler has decided to use a direct switch encoding. You might see something like:
Code:



279 psect swtext1
280 0005 __pswtext1:
281 0005 S1832:
282 0005 3187 2FE4 ljmp l1808
283 0007 3187 2FE8 ljmp l1810
284 0009 3187 2FED ljmp l1812



so you now know that this psect holds the jumps to each case in the switch. (Look for the assembly that jumps to the label S1832, for example. You will see that comes from a switch statement.) If your psect has grown too large, then most likely you have too many cases in switch statement.
If the linker knew what was in the sections it was placing, it would tell you more information, but it is just a linker that puts boxes of code into memory. (c) Jeff O'Keefe Microchip Australian Design Center 

Another super cool thing is that it actually gives a solution:
Update: in case anyone hits the same issue.The Compiler may not always catch duplicate case statements. (c) Neil_K 
You know what? There were just two identical cases in my switch statement! Hail to the Internet, Google, and the guy who came back to the forum to post the solution (this almost never happens). 

No comments: