problem with codes size(MCF5213)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

problem with codes size(MCF5213)

Jump to solution
3,504 Views
doom
Contributor I
     I built a stationary project with CW6.4. It is said that it can download 128k codes for free.But  I can only write about 3,000 lines in my c source.If  I write more,it overflows.
Can anyone tell me how many lines can I write with in the 128k limitition or how can I reduce the size of my output file,because  I  need about  10,000 lines in my  project . It  rather bothers me...

Thanks.
Labels (1)
0 Kudos
1 Solution
793 Views
RichTestardi
Senior Contributor II
Hi,
 
I'm pretty sure you can get the same resulting precision with integer operations, since the raw a/d data only has 13 bits of significance, and each order of filter adds only about a bit of accuracy.
 
You can make a trivial integer square root function using successive approximation -- even at its slowest, it'll probably be quite a bit faster than floating point...  Something like (you can tune the details for your range of integers -- I assumed 0..32767):
 
Code:
#define SUCCESSIVE  10static intisqrt(int x){    int i;    int n;        if (! x) {        return 0;    }        n = 128;  // initial guess for sqrt(mean 0..32767)    for (i = 0; i < SUCCESSIVE; i++) {        if (n == x/n) {            break;        }        n = (n + x/n + 1)/2;    }    return n;}
 
Do you have the parameters for the digital filter (order, coefficients, and IIR/FIR)?  I used a simple low-pass filter on the a/d converter below in the past (hooked to the accelerometer) for input values 0..32767 -- notice how I multiply by ~10000 to efectively keep 4 decimal places in an integer:
 
Code:
// our low pass filter coefficientsstatic shortcoef[] = {      67,     449,     874,    1261,    1531,    1628,    1531,    1261,     874,     449,      67,};// our low pass filter order#define ORDER  (sizeof(coef)/sizeof(coef[0]))intlowpass(int x){    int i;    static int s;    static int xs[ORDER];    // low pass filter    xs[s] = x;    x = 0;    for (i = 0; i < ORDER; i++) {        x += coef[i]*xs[(s+i)%ORDER];    }    x /= 9992;  // sum of coef's    s = (s+1)%ORDER;    return x;}

 -- Rich

View solution in original post

0 Kudos
9 Replies
793 Views
RichTestardi
Senior Contributor II
Hi,
 
It really depends on your code, but for my project of 8000 lines of source (excluding comments and blanks), I compile to between 60-80 kbytes, depending on the compiler optimization level, using CW7.1 (CW7.0 was more bloated than CW6.4, but I believe CW7.1 is comparable).
 
The things you want to check for are:
 
1. compiler optimization levels, parameter passing mechanism, etc.
2. large constant data structures/strings
3. excessive library usage
4. is linker deadstripping disabled?
 
The best place to look for your code bloat is in your xMAP file -- you can see where every single byte of code comes from -- whether from libraries or from your routines.  Then you can shrink things appropriately.  The xMAP file should be in your "bin" directory.
 
I'd expect you could get 10,000 lines of reasonable source to fit into 128 kbytes.
 
-- Rich
 
0 Kudos
793 Views
doom
Contributor I
HI Rich
     Thanks for your reply.
      Ur.. well.
      1.I did not disable the linker deadstripping
      2.I changed compiler optimization levels fromm level 1 to level 4 and choosed the small size code

But it seems  not good .After that, the output file shrinked fome 30k to 28 k.Do you think it has something
to do with the license?Maybe I am using an improper license?
I will try again,and thanks all the same.


--doom

0 Kudos
793 Views
RichTestardi
Senior Contributor II
Hi,
 
I may have misunderstood...  I thought you had a 3000 source line project that was compiling to over 128k bytes, and you were getting a license error as a result...
 
If your code is compiling larger than you expect, it might help if you can post the corresponding xMAP file -- then I can probably tell you exactly why...  (You also might want to select "Always Keep Map" under ColdFire Linker options.)
 
Also, can you tell us what the exact error is you are receiving?  It might help to post your Linker Command File (.lcf) as well, depending on when you are getting the error.
 
Thanks!
 
-- Rich
 
0 Kudos
793 Views
doom
Contributor I
HI
    Blame it on me  that I did not explain clearly.
    Well,
  1.(optimization off )  three days ago ,in order to test the maximal lines in a project ,I copied the codes as follows up to 3000 lines and then  it  was compiling to over 128k bytes.   
   
       if(ADCNT>=4)
               {

               ADresult0[4]=(ADresult0[0]+ADresult0[1]+ADresult0[2]+ADresult0[3])/4;
               FRE1=(unsigned int)(ADresult0[4]*100*238.7/167.4346);
               DISPBF[0]=((unsigned int)FRE1)/10000;
               DISPBF[1]=(((unsigned int)FRE1)%10000)/1000;
               DISPBF[2]=((unsigned int)FRE1%1000)/100;
               DISPBF[3]=((unsigned int)FRE1%100)/10;
               DISPBF[4]=((unsigned int)FRE1%10);
         
               ADresult1[4]=(ADresult1[0]+ADresult1[1]+ADresult1[2]+ADresult1[3])/4;
               FRE1=(unsigned int)(ADresult1[4]*100*238.7/167.4346);
              DISPBF[6]=((unsigned int)FRE1)/10000;
              DISPBF[7]=(((unsigned int)FRE1)%10000)/1000;
              DISPBF[8]=((unsigned int)FRE1%1000)/100;
              DISPBF[9]=((unsigned int)FRE1%100)/10;
              DISPBF[10]=((unsigned int)FRE1%10);   
           
              ADresult2[4]=(ADresult2[0]+ADresult2[1]+ADresult2[2]+ADresult2[3])/4;
              FRE1=(unsigned int)(ADresult2[4]*100*238.7/167.4346);
              DISPBF[12]=((unsigned int)FRE1)/10000;
              DISPBF[13]=(((unsigned int)FRE1)%10000)/1000;
              DISPBF[14]=((unsigned int)FRE1%1000)/100;
              DISPBF[15]=((unsigned int)FRE1%100)/10;
              DISPBF[16]=((unsigned int)FRE1%10);   
           
             ADCNT=0;
            }

Then I test  with copying this code"i=2+3*5-4".like this:
          main()
        {
             double i;
             i=sqrt(9.0);
             i=i=2+3*5-4;
             i=i=2+3*5-4;
             i=i=2+3*5-4;
             .
             .  
             .
        }
I can write about 6000 lines

2 .(optimization  level 4)After take your advice.I choose the optimiziton level 4 and then I can repeat "i=2+3*5-4" 16,000 times in the main function.
 
 But even when I choose optimization level 4 ,if I copy the codes  :                                                                                    ADresult0[4]=(ADresult0[0]+ADresult0[1]+ADresult0[2]+ADresult0[3])/4;
                  FRE1=(unsigned int)(ADresult0[4]*100*238.7/167.4346);
                 DISPBF[0]=((unsigned int)FRE1)/10000;
                 DISPBF[1]=(((unsigned int)FRE1)%10000)/1000;
                 DISPBF[2]=((unsigned int)FRE1%1000)/100;
                 DISPBF[3]=((unsigned int)FRE1%100)/10;
                 DISPBF[4]=((unsigned int)FRE1%10);
I can still write 3000 lines at most.

So I agree it really depends on  the codes.


3.The attachments are my Installed Plugins file , lcf file and xMAPfile . I use none libraries except  support_common.h
stdio.h
and sqrt in math.h
I will appreciate it,if you guide me to remove the unused libraries.
0 Kudos
793 Views
RichTestardi
Senior Contributor II
Ah, that makes more sense...
 
From your xMAP file, you can see main() is taking 100k bytes, and the rest looks to be floating point and printf support libraries.
 
  00000C10 00018ECC .text   main (main.c)
If you right-click on your source file and click "Disassemble", you can see how many bytes each line is compiling to (by searching for the source line in the disassembly listing).
 
Can you tell me how these variables (ADresult0, FRE1, and DISPBF) are declared -- are they floating point or integer or unsigned integer?
 
               ADresult0[4]=(ADresult0[0]+ADresult0[1]+ADresult0[2]+ADresult0[3])/4;
               FRE1=(unsigned int)(ADresult0[4]*100*238.7/167.4346);
               DISPBF[0]=((unsigned int)FRE1)/10000;
               DISPBF[1]=(((unsigned int)FRE1)%10000)/1000;
               DISPBF[2]=((unsigned int)FRE1%1000)/100;
               DISPBF[3]=((unsigned int)FRE1%100)/10;
               DISPBF[4]=((unsigned int)FRE1%10);
 
It looks like you're doing a lot of floating point ops to get integer results...
 
I'm *guessing* ADresult0 might be a result from the a/d converter, and you're trying to do some kind of a digital filter?  If so, the a/d results are 15 bit values (actually, 13 bit, I think, but multiplied by 4), so you might be able to use a 32 bit integer and replace the big line with an approximation:
 
               FRE1=(unsigned int)(ADresult0[4]*14256/10000*100);
 
But if you can tell me the types of the variables, we'll know for sure what kind of optimization might be possible, hopefully avoiding floating point.  Also, is your compiler set to size integers as 32 bit values?
 
-- Rich
 
 
0 Kudos
793 Views
doom
Contributor I
THANKS

I did use lots of floating point  to get precise datas.
variables (ADresult0, FRE1, and DISPBF) are declared as follows:
double result=0,ADresult0[5],ADresult1[5]={0},ADresult2[5]={0},ADresult3[5]={0},ADresult4[5]={0},ADresult5[5]={0};
int AD0[128],AD1[128],AD2[128],AD3[128],AD4[128],AD5[128];

unsigned char j=0,ADCNT=0,ADFLG=0,_100MS=0,i=0,cnt1;

unsigned int FRE1=0;
unsigned char DISPBF[18]={0,1,2,3,4,0x27,5,6,7,8,9,0x27,0x0a,0x0b,0x0c,0x0d,0x0e,0x00};
char cnt=0;


ADx[128] are result from the a/d converter.
I use double sqrt();in math.h and "ADresult0[x]=sqrt(result/128);"and use "ADresult0[4]=(ADresult0[0]+ADresult0[1]+ADresult0[2]+ADresult0[3])/4;"to do a digital filter.


I do not care about RAM.What I care about most is Flash.By Disassembling I found that:

    DISPBF[4]=((unsigned int)FRE1%10);
;  529:           
;
0x00002700  0x223900000000           move.l   _FRE1,d1
0x00002706  0x4C431000               remul.l  d3,d0:d1
0x0000270A  0x13C000000000           move.b   d0,_DISPBF+4
0x00002710  0x41F900000000           lea      _ADresult1+8,a0
0x00002716  0x2010                   move.l   (a0),d0
0x00002718  0x2F6800040010           move.l   4(a0),16(a7)
0x0000271E  0x41F900000000           lea      _ADresult1,a0
0x00002724  0x2F40000C               move.l   d0,12(a7)
0x00002728  0x2010                   move.l   (a0),d0
0x0000272A  0x22280004               move.l   4(a0),d1
0x0000272E  0x41EEDF28               lea      -8408(a6),a0
0x00002732  0x2F410008               move.l   d1,8(a7)
0x00002736  0x2F400004               move.l   d0,4(a7)
0x0000273A  0x2E88                   move.l   a0,(a7)
0x0000273C  0x4EB900000000           jsr      __d_add
0x00002742  0x2010                   move.l   (a0),d0
0x00002744  0x2F6800040010           move.l   4(a0),16(a7)
0x0000274A  0x41F900000000           lea      _ADresult1+16,a0
0x00002750  0x2F40000C               move.l   d0,12(a7)
0x00002754  0x2010                   move.l   (a0),d0
0x00002756  0x22280004               move.l   4(a0),d1
0x0000275A  0x41EEDF20               lea      -8416(a6),a0
0x0000275E  0x2F410008               move.l   d1,8(a7)
0x00002762  0x2F400004               move.l   d0,4(a7)
0x00002766  0x2E88                   move.l   a0,(a7)
0x00002768  0x4EB900000000           jsr      __d_add
0x0000276E  0x2010                   move.l   (a0),d0
0x00002770  0x2F6800040010           move.l   4(a0),16(a7)
0x00002776  0x41F900000000           lea      _ADresult1+24,a0
0x0000277C  0x2F40000C               move.l   d0,12(a7)
0x00002780  0x2010                   move.l   (a0),d0
0x00002782  0x22280004               move.l   4(a0),d1
0x00002786  0x41EEDF10               lea      -8432(a6),a0
0x0000278A  0x2F410008               move.l   d1,8(a7)
0x0000278E  0x2F400004               move.l   d0,4(a7)
0x00002792  0x2E88                   move.l   a0,(a7)
0x00002794  0x4EB900000000           jsr      __d_add
0x0000279A  0x203C40100000           move.l   #1074790400,d0        ; '@...'

As you see, this code is so inefficient.Maybe I should do some changes besides optimizing variables.



--DOOM
0 Kudos
794 Views
RichTestardi
Senior Contributor II
Hi,
 
I'm pretty sure you can get the same resulting precision with integer operations, since the raw a/d data only has 13 bits of significance, and each order of filter adds only about a bit of accuracy.
 
You can make a trivial integer square root function using successive approximation -- even at its slowest, it'll probably be quite a bit faster than floating point...  Something like (you can tune the details for your range of integers -- I assumed 0..32767):
 
Code:
#define SUCCESSIVE  10static intisqrt(int x){    int i;    int n;        if (! x) {        return 0;    }        n = 128;  // initial guess for sqrt(mean 0..32767)    for (i = 0; i < SUCCESSIVE; i++) {        if (n == x/n) {            break;        }        n = (n + x/n + 1)/2;    }    return n;}
 
Do you have the parameters for the digital filter (order, coefficients, and IIR/FIR)?  I used a simple low-pass filter on the a/d converter below in the past (hooked to the accelerometer) for input values 0..32767 -- notice how I multiply by ~10000 to efectively keep 4 decimal places in an integer:
 
Code:
// our low pass filter coefficientsstatic shortcoef[] = {      67,     449,     874,    1261,    1531,    1628,    1531,    1261,     874,     449,      67,};// our low pass filter order#define ORDER  (sizeof(coef)/sizeof(coef[0]))intlowpass(int x){    int i;    static int s;    static int xs[ORDER];    // low pass filter    xs[s] = x;    x = 0;    for (i = 0; i < ORDER; i++) {        x += coef[i]*xs[(s+i)%ORDER];    }    x /= 9992;  // sum of coef's    s = (s+1)%ORDER;    return x;}

 -- Rich
0 Kudos
793 Views
Everton
Contributor I

Hi, Rich T

 

I want to know if this algorithm can be used to filter high-pass and band-pass? Replacing only the coefficient of the filter.

 

Thanks advance

 

Everton Danilo

0 Kudos
793 Views
RichTestardi
Senior Contributor II

There are lots of sites on the web for computing the coefficients and getting guidance in digital filter design...

 

You might try something like: http://www.dsptutor.freeuk.com/FIRFilterDesign/FIRFilterDesign.html

 

Or just search for "fir digital filter design" or "iir digital filter design".

 

Good luck.

 

-- Rich

 

0 Kudos