CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Error 71 ... Out of ROM, A segment or the program is too lar
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 02, 2016 12:12 pm     Reply with quote

Ok, now it's my turn:
PIC16F887 (8K words program memory)

*** Error 71 "vlv2.c" Line 100(1,2): Out of ROM, A segment or the program is too large ReadTempSensor
Seg 00800-00FFF, 022C left, need 0070D
Seg 01000-017FF, 043F left, need 0070D
Seg 01800-01EFF, 0700 left, need 0070D
Seg 00000-00003, 0000 left, need 0070D Reserved
Seg 00004-00050, 0000 left, need 0070D Reserved
Seg 00051-007FF, 0003 left, need 0070D

I already split many of the functions and added #SEPARATE. It seems I'm almost there (0x70D needed, 0x700 left) but it's elusive - I split a little more and everything changes again...
Since I have plenty of non-consecutive memory left my question is this:
Does the linker do a good work in fitting the code blocks into available memory blocks, or do I need to help it with #ORG ? I can't see the function sizes until it compiles Sad
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Aug 02, 2016 12:38 pm     Reply with quote

Quote:
I can't see the function sizes until it compiles

You could remove some functions until it compiles. Then print out the
sizes of the remaining functions. That would get you part of it.
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Tue Aug 02, 2016 12:56 pm     Reply with quote

The compiler does a very good job of fitting stuff in. Remove something so it compiles, then identify what function it is that is this large in one piece.
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 02, 2016 2:10 pm     Reply with quote

when I started I thought it was easy. It gets worse and worse.
I #separate all of the large functions and even split functions into sub functions.

Also look what I get now (after commenting out a call to a function in order to compile) - it needs TWO different block sizes...? What am I missing?
Quote:
*** Error 71 "vlv2.c" Line 100(1,2): Out of ROM, A segment or the program is too large ReadTempSensor
Seg 00051-007FF, 0055 left, need 006E5
Seg 00800-00FFF, 0261 left, need 006E5
Seg 01000-017FF, 043F left, need 006E5
Seg 01800-01EFF, 0700 left, need 00739
Seg 00000-00003, 0000 left, need 00739 Reserved
Seg 00004-00050, 0000 left, need 00739 Reserved
Seg 00051-007FF, 0055 left, need 00739
Seg 00800-00FFF, 0261 left, need 00739
Seg 01000-017FF, 043F left, need 00739


If I #separate a sub function of ReadTempSensor I get this:

Quote:
*** Error 71 "vlv2.c" Line 100(1,2): Out of ROM, A segment or the program is too large readDS1820
Seg 01000-017FF, 043F left, need 00A3F
Seg 01800-01EFF, 0700 left, need 00A3F
Seg 00000-00003, 0000 left, need 00A3F Reserved
Seg 00004-00050, 0000 left, need 00A3F Reserved
Seg 00051-007FF, 0035 left, need 00A3F
Seg 00800-00FFF, 0261 left, need 00A3F

So #separate INCREASES the required block size?!
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 02, 2016 2:29 pm     Reply with quote

I tried commenting out each major function, write down the ROM usage % in order to know the size of the function (since I can't compile when all functions are used).
It seems that when I 'fix' something with #separate the compiler moves on to the next challenge which could be a bigger block, hence the growing block size.
And at the end of the day when I sum up the percentages of usage, the whole program would take 113% which explains a few things... No use but migrating...
Good night people and thanks for the tips. Confused
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Wed Aug 03, 2016 12:57 am     Reply with quote

The other thing is to look at 'why' the code is so large?. Something silly like using fp maths when it is not needed, can easily use up all the memory space in chips that are perfectly capable of handling the job required....
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Wed Aug 03, 2016 1:20 pm     Reply with quote

after I finished sulking about writing unnecessarily large code I remove FP conversion from Celcius to F and the code fit. No need for migration!

One big surprise is that a #SEPARATE statement caused the code NOT TO FIT. Removing it enabled the compilation. Could be that a function *doesn't* have to fit inside a page. Back in the days when I wrote in Assembly I could continue a function beyond a page limit (PC doesn't roll over) as long as I didn't GOTO without handling the pages. What do you think??

With #SEPARATE before handleCcommand :
Quote:
*** Error 71 "vlv2.c" Line 105(1,2): Out of ROM, A segment or the program is too large handleCcommand
Seg 01800-01EFF, 02B3 left, need 00A69
Seg 00000-00003, 0000 left, need 00A69 Reserved
Seg 00004-00050, 0000 left, need 00A69 Reserved
Seg 00051-007FF, 00EA left, need 00A69
Seg 00800-00FFF, 002A left, need 00A69
Seg 01000-017FF, 00EF left, need 00A69


Without #SEPARATE:
Quote:
Memory usage: ROM=86% RAM=61% - 82%
0 Errors, 12 Warnings.
Build Successful.
temtronic



Joined: 01 Jul 2010
Posts: 9632
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 04, 2016 5:16 am     Reply with quote

re: C to F conversion

f=(C*2)-(.1C)+32

say C is 20
20 * 2 = 40 //this is a simple rotate left
40 - 4 is 36 //just take 10s digit
36+32 = 68//simple add

I do this in my head all the time as Canada is 'supposed' to be metric but I'm old and like *F !

Don't know about cold(-) temps.. when it's that cold I stay inside !


You could probably go through most functions and 'tweak' them to gain some more code space,but time IS money...you don't live forever, AND there HAS to be a pin compatible PIC with more in it for just a few pennies more.

Jay
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Thu Aug 04, 2016 5:38 am     Reply with quote

I needed 0.1F accuracy so my code was:
Quote:
signed int16 q;
// Celcius to Fahrenheit conversion:
// q holds temperature in deg.C
q*=18; // *1.8 , *10 for decimal point
q+=320; // +32 (*10)

The result is displayed with printf(q,%3.1w) which adds a decimal point to an integer.

Since I used DS18B20 temp. sensor and added 0.5 deg.C accuracy, I used:
Quote:
signed int16 q;
signed int j;

swap(touchBuffer[0]);
swap(touchBuffer[1]);

j=(touchBuffer[1]&0xF0)|(touchBuffer[0]&0x0F); // signed int
q=j; // signed int16
q*=18; // *1.8 , *10 for decimal point
if(bit_test(touchBuffer[0],7)) q+=9; // 0.5 deg.C *18
q+=320; // +32 (*10)

This still needs to be tested for negative Fahrenheit temperatures - I don't know how printf(...%w) treats negative numbers.
But we are already way off topic Cool
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Thu Aug 04, 2016 7:15 am     Reply with quote

%w and %Lw work with signed numbers.

It's worth understanding that the reason to avoid #separate, is that if used for functions that are called only once, it uses extra space. Splitting the code means extra calls and returns, and moving the data to temporary storage for the call. The reason to use it, is to allow the code block to be subdivided.

This is why it can become such a complex balancing act... :(
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Mon Aug 08, 2016 7:57 am     Reply with quote

I used printf("%1.1Lw",signed16) but on negative numbers a bug causes trailing zeros - it produces 000000000.1 for -1 (compiler version 5.048).
This could be solved by changing to printf("%2.1Lw",signed16) which correctly outputs -0.1 and works well from -32768 to 32767.
%w rules!! Cool Thanks Ttelmah.
Ttelmah



Joined: 11 Mar 2010
Posts: 20061

View user's profile Send private message

PostPosted: Mon Aug 08, 2016 12:48 pm     Reply with quote

The reason for this, is that you are overflowing the width.

In C, the field width includes the decimal point. %1.1, specifies to print in a field that is not wide enough to take any value....
While the field will automatically expand, if the number is bigger than will fit, it has to be able to get the decimal part in.
TimothyCarter



Joined: 08 Aug 2016
Posts: 22

View user's profile Send private message

Re-organize the functions
PostPosted: Mon Aug 08, 2016 2:10 pm     Reply with quote

Your best bet is probably just to simply re-arrange the order of the functions (as has already been mentioned). This has worked for me a few times.

Of course, even better - if time permits - is to shrink the functions down as much as possible.
_________________
“Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter.”
- Eric S. Raymond
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group