 |
 |
| View previous topic :: View next topic |
| Author |
Message |
guy
Joined: 21 Oct 2005 Posts: 297
|
|
Posted: Tue Aug 02, 2016 12:12 pm |
|
|
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  |
|
 |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 02, 2016 12:38 pm |
|
|
| 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
|
|
Posted: Tue Aug 02, 2016 12:56 pm |
|
|
| 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
|
|
Posted: Tue Aug 02, 2016 2:10 pm |
|
|
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
|
|
Posted: Tue Aug 02, 2016 2:29 pm |
|
|
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.  |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20061
|
|
Posted: Wed Aug 03, 2016 12:57 am |
|
|
| 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
|
|
Posted: Wed Aug 03, 2016 1:20 pm |
|
|
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
|
|
Posted: Thu Aug 04, 2016 5:16 am |
|
|
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
|
|
Posted: Thu Aug 04, 2016 5:38 am |
|
|
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  |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20061
|
|
Posted: Thu Aug 04, 2016 7:15 am |
|
|
%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
|
|
Posted: Mon Aug 08, 2016 7:57 am |
|
|
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!! Thanks Ttelmah. |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 20061
|
|
Posted: Mon Aug 08, 2016 12:48 pm |
|
|
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
|
| Re-organize the functions |
Posted: Mon Aug 08, 2016 2:10 pm |
|
|
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 |
|
 |
|
|
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
|