Shop OBEX P1 Docs P2 Docs Learn Events
C & SimpleIDE - Why does Code Size jump from 9k bytes to 32kbytes — Parallax Forums

C & SimpleIDE - Why does Code Size jump from 9k bytes to 32kbytes

twm47099twm47099 Posts: 867
edited 2014-08-01 08:48 in Propeller 1
I've written some simple software to interface to a BlueTooth joystick app on my Samsung tablet.
The program reads the joystick or button value from the app and prints the value on the SimpleIDE terminal.

The first version ran everything in "main". The code size reported by SimpleIDE was about 9k bytes.

The second version ran the bluetooth function in a separate cog and transferred x and y or a button code to main where it was printed on the SimpleIDE terminal. The code size changed to 32k bytes.

The third version commented out the call to the bluetooth function, the declaration of the function, and the cog_run. The code size is 30k.

Each version is listed below. SimpleIDE version is 0.9.45, and I am using the 2014.05.14 Learn Libraries. CMM model

This is the 9k bytes version
/*  C code used with Joystick BT Commander App by Kas - used with Samsung Tablet 7-29-14 BT Commander v5 Changed protocol -- code mods to read Joystick and buttons work -- need to do data TX to android
             coded button 6 as 'end' to terminate program
             Run with terminal
 */
 

  #include "simpletools.h"                      // Include simple tools
  #include "fdserial.h"
  
  fdserial *blut;
 

    char c1[9];
    int c0 = 2;
    int x; 
    int y;
    int z;
    
 int main()
 {
      // fdserial * fdserial_open(int rxpin, int txpin, int mode, int baudrate)
    blut = fdserial_open(9, 8, 0, 115200); 
    while(c0)                  // continue until button 4 is pressed 
      {
         int i = 1;
         z = 1;
         c1[1] = fdserial_rxChar(blut);    // read first byte from blut
         print("c10 = %d\n", c1[1]);
         if(c1[1] == 2)                    //   if STX read next 7 bytes    
         {                   
           z = 1;
           while(z)
           {
             i++;
             c1[i] = fdserial_rxChar(blut);  
             if((c1[i]==3) && (i==3 || i==8)) z=0;
            }                       //   end while z  android string i = 2 => button, i = 7 => x,y values
           if(i==8)
           {
             x = (c1[2] -48)*100 + (c1[3]-48)*10 + (c1[4]-48);
             y = (c1[5] -48)*100 + (c1[6]-48)*10 + (c1[7]-48);
             x = x-200;
             y = y-200; 
             print("x = %d\n", x);
             print("y = %d\n\n",y);
           }       //  end if i= 8
           if(i==3) print(" button = %d\n\n", c1[2]);
           if((i==3) && (c1[2]=='K' || c1[2]=='L'))
           {
             c0 = 0;
             print(" end \n\n");
           }
         }       // end if c1=2
     }     // end while c0
 }  // end main (temporary)
 



This is the multicore 32k bytes version
/*  C code used with Joystick BT Commander App by Kas - used with Samsung Tablet 

 7-29-14 BT Commander V5 Changed protocol -- mods to read Joystick and buttons work -- need to do data TX to android
             coded button 6 as 'end' to terminate program
             Run with terminal
 */
 

  #include "simpletools.h"                      // Include simple tools
  #include "fdserial.h"
 

  fdserial *blut;
 

 char c1[9];
 int c0 = 1;
 int a;
 int x; 
 int y;
 int okread;
 int okwrite;
 int x1;
 int y1;
 int z;
 

 void getbtjoy();
 

 int main()
 {
   int x2;
   int y2;
   okread = 0;
   cog_run(&getbtjoy, 20);
   while(c0)
   {
     if((a==8) && (okread ==1))
     {
       okwrite = 0;
       pause(50);
       x2 = x1;
       y2 = y1;
       print("x = %d\n", x2);
       print("y = %d\n\n",y2);
       pause (50);
       okwrite = 1;
     }
     if(a==3)  print(" button = %d\n\n", c1[2]);
   }    // end while c0
 print(" end \n\n");
 }     // end main
 

 

 void getbtjoy()
 {
      // fdserial * fdserial_open(int rxpin, int txpin, int mode, int baudrate)
    blut = fdserial_open(9, 8, 0, 115200); 
    while(c0)                  // continue until button 6 is pressed 
     {
       a=0;
       int i = 1;
       z = 1;  
       c1[1] = fdserial_rxChar(blut);    // read first byte from blut
       if(c1[1] == 2)                    //   if STX read next 7 bytes    
       {                   
         z = 1;
         while(z)
          {
             i++;
             // print("i = %d\n",i);
             c1[i] = fdserial_rxChar(blut);  
             // print("button = %d\n", c1[i]);
             if((c1[i]==3) && (i==3 || i==8)) z=0;
           }                       //   end while z  android string i = 2 => button, i = 7 => x,y values
         if(i==8)
         {
           okread = 0;
           a=8;
           x = (c1[2] -48)*100 + (c1[3]-48)*10 + (c1[4]-48);
           y = (c1[5] -48)*100 + (c1[6]-48)*10 + (c1[7]-48);
           x = x - 200;  // x range -100 to +100
           y = y - 200; 
           while(okwrite =0){ } 
           x1 = x;   
           y1= y;  
           pause(50);
           okread = 1;
         }       //  end if i= 8
 

         if(i==3) 
         {
           a=3;
           // print(" button = %d\n\n", c1[2]);
         }
         if((i==3) && (c1[2]=='K' || c1[2]=='L'))
         {
           c0 = 0;
           //print(" end \n\n");
         }
       }       // end if c1=2
     }     // end while c0
  }  // end getbtjoy
  


This is the version with the multicore stuff commented out, 30k bytes
/*  C code used with Joystick BT Commander App by Kas - used with Samsung Tablet 

 7-29-14 BT Commander V5 Changed protocol -- mods to read Joystick and buttons work -- need to do data TX to android
             coded button 6 as 'end' to terminate program
             Run with terminal
 */
 

  #include "simpletools.h"                      // Include simple tools
  #include "fdserial.h"
 

  fdserial *blut;
 

 char c1[9];
 int c0 = 1;
 int a;
 int x; 
 int y;
 int okread;
 int okwrite;
 int x1;
 int y1;
 int z;
 

 // void getbtjoy();
 

 int main()
 {
   int x2;
   int y2;
   okread = 0;
 //  cog_run(&getbtjoy, 20);
   while(c0)
   {
     if((a==8) && (okread ==1))
     {
       okwrite = 0;
       pause(50);
       x2 = x1;
       y2 = y1;
       print("x = %d\n", x2);
       print("y = %d\n\n",y2);
       pause (50);
       okwrite = 1;
     }
     if(a==3)  print(" button = %d\n\n", c1[2]);
   }    // end while c0
 print(" end \n\n");
 }     // end main
 

 /*
 void getbtjoy()
 {
      // fdserial * fdserial_open(int rxpin, int txpin, int mode, int baudrate)
    blut = fdserial_open(9, 8, 0, 115200); 
    while(c0)                  // continue until button 6 is pressed 
     {
       a=0;
       int i = 1;
       z = 1;  
       c1[1] = fdserial_rxChar(blut);    // read first byte from blut
       if(c1[1] == 2)                    //   if STX read next 7 bytes    
       {                   
         z = 1;
         while(z)
          {
             i++;
             // print("i = %d\n",i);
             c1[i] = fdserial_rxChar(blut);  
             // print("button = %d\n", c1[i]);
             if((c1[i]==3) && (i==3 || i==8)) z=0;
           }                       //   end while z  android string i = 2 => button, i = 7 => x,y values
         if(i==8)
         {
           okread = 0;
           a=8;
           x = (c1[2] -48)*100 + (c1[3]-48)*10 + (c1[4]-48);
           y = (c1[5] -48)*100 + (c1[6]-48)*10 + (c1[7]-48);
           x = x - 200;  // x range -100 to +100
           y = y - 200; 
           while(okwrite =0){ } 
           x1 = x;   
           y1= y;  
           pause(50);
           okread = 1;
         }       //  end if i= 8
 

         if(i==3) 
         {
           a=3;
           // print(" button = %d\n\n", c1[2]);
         }
         if((i==3) && (c1[2]=='K' || c1[2]=='L'))
         {
           c0 = 0;
           //print(" end \n\n");
         }
       }       // end if c1=2
     }     // end while c0
  }  // end getbtjoy
 

 */

Any ideas?
Thanks
Tom

Comments

  • twm47099twm47099 Posts: 867
    edited 2014-07-31 22:27
    A little trouble shooting --
    I took the 3rd version and deleted all of the getbtjoy related code and declarations. Still 30k.
    Then I deleted all of main and just had int main() { }, still 30 k.

    Then I started commenting out each of the includes and declarations - still 30 k until I commented the declaration: int y1; Then the code size dropped to 2 k.

    I deleted that statement and retyped it - back to 30 k.

    Then I replaced int y1; with int yy; code size = 2k.

    I went back to the 2nd code in the above post (multicore, 32 k) and replaced all occurrences of y1 with yy. Code size 9 k. ?!?!?

    What is magic about y1? Is it a reserved word?

    Totally confused (but the code works)
    Tom
  • jazzedjazzed Posts: 11,803
    edited 2014-07-31 22:31
    Not sure why but a ton of math library routines were included in the binary (something to track down).

    How did I know that?
    Open the Project Manager and right click on the .c file.
    Choose Show Map File ... in the first four items I log, sqrt, etc...

    Uncheck "Math Lib" in Project Manager -> Library ....

    Everything goes back to normal. BTW, if you don't need floating point use printi() for smaller code.
  • twm47099twm47099 Posts: 867
    edited 2014-07-31 23:25
    Steve,
    Thanks for the information. I tried it, and I see how it works. I've had a couple other programs that had very large code size, although the programs weren't that large. I'll have to check them.

    Thanks again,

    Tom
  • twm47099twm47099 Posts: 867
    edited 2014-07-31 23:34
    I took the multicore version above (with y1 changed to yy) and added code to calculate and print the values for the drive_speed command based on the position of the joystick. That program was 10k bytes. When I took Steve's advice to change all the print() statements to printi() statements, the code size dropped to 5.7k. That's a significant reduction in code size.

    Tom.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-08-01 06:26
    It seems that y1 is defined as a global in one of the libraries, which is causing it to be linked into your program. You can work around this by using a different name, such as yy, or you can declare y1 static.

    EDIT: I also found that declaring y1 as "int y1 = 0;" resolves the problem.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-08-01 07:59
    I compiled a small program with "int y1" declared and I got the warning "built-in function 'y1' declared as non-function". I googled "built-in function y1" and found the following:
    y0, y0f, y0l, y1, y1f, y1l, yn, ynf, ynl - Bessel functions of the second kind
    So y1 is a built-in function that requires the floating-point library. It's unfortunate that these short names are used for built-in functions. When using any of these names as variables the programmer should declare them as static. Or better yet, these names should be avoided.
  • jazzedjazzed Posts: 11,803
    edited 2014-08-01 08:04
    Oivey! :[

    Thanks for following up Dave.

    Dave Hein wrote: »
    I compiled a small program with "int y1" declared and I got the warning "built-in function 'y1' declared as non-function". I googled "built-in function y1" and found the following:

    So y1 is a built-in function that requires the floating-point library. It's unfortunate that these short names are used for built-in functions. When using any of these names as variables the programmer should declare them as static. Or better yet, these names should be avoided.
  • twm47099twm47099 Posts: 867
    edited 2014-08-01 08:48
    Dave,
    Thanks for the information. I went back and compiled one of the versions that gave code size 30k, and I found this line (below) in SimpleIDE when I clicked on the build icon at the bottom of the screen. (Since the progam built & loaded to the prop ok, these messages didn't open automatically.)

    d:/program files/simpleide/propeller-gcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/bin/ld.exe: Warning: alignment 2 of symbol `_y1' in d:/program files/simpleide/propeller-gcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/lib/cmm/short-doubles\libm.a(e_j1.o) is smaller than 4 in C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\ccgjhUiC.o

    There is a warning regarding '_y1', but in my program I was using 'y1'. I would expect that libraries would use names with a leading underscore, but I don't see how that would be confused with a name without one??

    As suggested declaring int y1=0 fixes the problem and also removes that warning.

    I like using SimpleIDE because I don't have to be bothered by what is happening when my program is built. But I also feel that I am missing a lot by not doing it the hard way. Is there a beginners text or link to using PropGCC that includes the messy stuff (not even sure what it is called - compile, link, and load?)

    Thanks again
    Tom
Sign In or Register to comment.