![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
sorasit46
Joined: 07 May 2007 Posts: 69
|
Why 1 command uses alot of Rom? |
Posted: Sun Dec 12, 2010 12:37 am |
|
|
What's wrong with this code ?
Code: | #include <16F819.h>
#FUSES INTRC_IO
#FUSES WDT
#FUSES NOPUT
#FUSES NOMCLR
#FUSES NOBROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG
#FUSES NOPROTECT
#use delay(clock=4000000)
#byte OSCCON = 0x8F
#include <math.h>
#include <stdlib.h>
int16 A,Cnt,Ori;
float B,C,D;
void main (void)
{
while (true)
{A=(abs(cos((B*C*D*Cnt+Ori)+1)*1000))/1; }
} |
By PCWHD Compiler V 4.057.
report
memory usage:Rom=80% RAM=22%-46%
How can I do?
Regards |
|
![](templates/subSilver/images/spacer.gif) |
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Sun Dec 12, 2010 12:55 am |
|
|
include files use a lot of ROM, its not un-common |
|
![](templates/subSilver/images/spacer.gif) |
sorasit46
Joined: 07 May 2007 Posts: 69
|
|
Posted: Sun Dec 12, 2010 1:17 am |
|
|
How can I do?
Before use this command. My program used 83% of Rom.
When add this command, Compiler report "Out of ROM,A segment or the program is too large".
Any suggestions about how to make this command working ?
I'm closing end of project. |
|
![](templates/subSilver/images/spacer.gif) |
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
Re: RE: |
Posted: Sun Dec 12, 2010 2:12 am |
|
|
arunb wrote: | include files use a lot of ROM, its not un-common |
That's a very broad and not terribly accurate generalisation. It's not include files that use a lot of ROM, but whatever code they bring with them.
In this specific case, it's almost certainly the floating point support code. Floating point is notorious for using lots of code and the only solution is not to use floating point!
Instead, use integer arithmetic. Precalculated lookup tables and fixed-point math (eg. where the integer 12345 is really 1.2345) are the usual solution. _________________ Andrew |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19366
|
|
Posted: Sun Dec 12, 2010 3:22 am |
|
|
Spot on AddrewG.
Begin with 'one command'. This isn't. The code as posted, has first, three floating point multiplications (because B,C,D, are floating point, the multiplication will be done using FP). Then two integers are converted to FP, and two floating point additions performed (in C, if you perform arithmetic on two numbers of different 'types', the lower type is converted to the higher, and the arithmetic performed using the higher type - so here, as the multiplications have been done with FP, and this result is FP, two FP additions are now done). Then another FP multiplication. Then a Cos is performed on this. Then the ABS function, and then finally a (pointless) division by one (I'd expect the compiler will hopefully have optimised this out - divide anything by 1, and you get the number you started with.....).
So the _statement_, involves four FP multiplications, two FP additions, four FP type conversions, a Cos, and the Abs (and possibly a useless division, depending if the compiler is smart enough to remove it or not....). Not one 'command' in anybodies language. The Cos alone, will be about 10000 machine instruction times. The multiplications about 900, the division (if used), about 1500. The actual 'code size', will be a significant fraction of these counts...
The size of the code involved, will change with the processor. On the PIC16 family, even a simple int16 multiplication, has to be done 'bit by bit'. Typically just under 250 instructions. The same command on a PIC18, drops to just over 30 instructions, with the processor having a hardware 8bit multiply present.
FP maths, is bulky, and slow.
It is quite possible, to write a one line statement, using a few FP operations, that will use _all_ the memory of almost any PIC..
Now, 'arunb', slightly oversimplified. Generally, include files, use little space, _until_ their functions are actually used.
For instance, if you build a simple test project, then include math.h, and recompile, the code size does not change. However now 'use' one of the functions (say just a single Cos), the code size jumps up by 1994 instructions. A multiply uses 294 instructions, a division 394 instructions etc. etc..
Now the size does not keep growing, quite as badly as this. _Once_ the Cos function is used, another cos, uses the same function. _However_ just the act of transferring the required numbers into the temporary registers and back again, will typically take several dozen instructions, so the first Cos, might use 1994 instructions, and subsequent ones perhaps 50 instructions each. Not quite so bad....
An enormous amount depends on what you actually need to do. If you 'must' use FP maths, then you need to be aware of just how large (and slow) the code will become. However for most things, using scaled integers is often possible, and Andrewg, has given some good ideas for this approach.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sun Dec 12, 2010 7:13 am |
|
|
As another example of using integers instead of floating point, I once did a project using CCS to measure the hulls of large ships. I ended up doing the measurements in 24 bit integer millimeters. I could have used 32 bit integer microns. I often measure temperature in integer milli-degrees. Conversion to whole meters or degrees can be handled by the print string formatting at the very end. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
sorasit46
Joined: 07 May 2007 Posts: 69
|
|
Posted: Sun Dec 12, 2010 7:34 am |
|
|
I'm trial change from float to int .
Code: | #include <16F819.h>
#FUSES INTRC_IO
#FUSES WDT
#FUSES NOPUT
#FUSES NOMCLR
#FUSES NOBROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG
#FUSES NOPROTECT
#use delay(clock=4000000)
#byte OSCCON = 0x8F
#include <math.h>
int A,B;
void main (void)
{
while (true)
{A=cos(B);}
} |
compiler report " memory usage :ROM = 60% Ram = 5%-28%"
It still use a lot of ROM.
I have 40% only for write another code. |
|
![](templates/subSilver/images/spacer.gif) |
dbotkin
Joined: 08 Sep 2003 Posts: 197 Location: Omaha NE USA
|
|
Posted: Sun Dec 12, 2010 8:28 am |
|
|
Maybe a different chip would be a better choice. If you don't need the ADC, a 16F648A has twice the memory in a pin-compatible package. If you do need ADC, the 16F88 would be good, or the 16F1828/16F1829 look good (though not the same pinout). A PIC18F1320 or 18F1330 would be a good choice if you have, or are willing to buy, the compiler for it.
If you're stuck with that chip, you may need to look at other ways to make your code more efficient. I have been able to eliminate complex and ROM-consuming mathematical calculations with tables or simpler math. As with many things, there's usually an easy and inefficient way, and then there's a harder but more efficient way.
Last edited by dbotkin on Sun Dec 12, 2010 8:50 am; edited 1 time in total |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19366
|
|
Posted: Sun Dec 12, 2010 8:40 am |
|
|
sorasit46 wrote: | I'm trial change from float to int .
Code: | #include <16F819.h>
#FUSES INTRC_IO
#FUSES WDT
#FUSES NOPUT
#FUSES NOMCLR
#FUSES NOBROWNOUT
#FUSES NOLVP
#FUSES NOCPD
#FUSES NOWRT
#FUSES NODEBUG
#FUSES NOPROTECT
#use delay(clock=4000000)
#byte OSCCON = 0x8F
#include <math.h>
int A,B;
void main (void)
{
while (true)
{A=cos(B);}
} |
compiler report " memory usage :ROM = 60% Ram = 5%-28%"
It still use a lot of ROM.
I have 40% only for write another code. |
You are still using float. The cos function, returns fractions, and _has_ to be written in float. To switch to using integers, _you_ have to generate your own 'scaled integer' maths libraries. Also, read the penultimate paragraph of what I posted, and understand, that you could probably write several hundred lines of code in the amount of ROM left...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
sorasit46
Joined: 07 May 2007 Posts: 69
|
|
Posted: Sun Dec 12, 2010 9:39 am |
|
|
Dbotkin suggest 16F648A .It's good choice. Thank you.
Ttelmah suggest switch to useing integer by generate 'scale integer' ?
How to do? and How I can transferring the required numbers into the temporary registers and back again ? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19366
|
|
Posted: Sun Dec 12, 2010 9:57 am |
|
|
Do a search on the forum.
The key is to understand that if (for example), you decided to use int32, and treat each unit, as if it was 'thousandths', you could represent numbers up to 4294967.296, with three decimal place accuracy. The compiler has the ability to printout such numbers for you (look at %w). For things like sin/cos, the quickest/code compact route, is a lookup table, combined with linear interpolation. remember since sin/cos, can not exceed '1', the scaled values can be stored in an int16. A 256 element table, then takes just 512bytes of ROM. There is a balancing 'act' between the number of elements in the table, and the interpolation needed, depending on what accuracy you actually need.
Remember also a table for one 'quadrant', can solve the entire circle, and that the same table can be used for sin and cos, by just adjusting by one quadrant.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Sun Dec 12, 2010 1:47 pm |
|
|
A line of code only seems to take up so much space. It is often simple like
x=0 in which case the notation x=0 takes up as much space or more than the machine instruction needed to implement it. Then there is something like cos(a) 6 chars which notate for a highly complex function. Now the machine code is sizable. One way to address this is to have the values computed elsewhere and load the results in a table. Another is a hybrid with a table of coefficients that yield rapid convergence when iterated. MPEG4 uses discrete cosine transfers often this is done with the CORDIC other times with a DSP chip. The PIC is not suited to massive calculations so it pays to trade some ROM for less math. The CORDIC uses base 2 angular rotation and was used decades ago with the earliest MCU's used in the space program. Most find float and the PIC to not be the best fit. |
|
![](templates/subSilver/images/spacer.gif) |
sorasit46
Joined: 07 May 2007 Posts: 69
|
|
Posted: Sun Dec 12, 2010 5:21 pm |
|
|
oh! I see.
Heart of this solution is " tables ".
thank you |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|