How to strip a tiny avr?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
We are looking to do a simple project with the tiny 15/25/45/85.
Tiny15 would be ideal.  However, to compile a simple dummy C program
with AVR studio/WinAVR created 2.8K, which would rule out the 15 and
25.  Are there ways to strip the run time library?


Re: How to strip a tiny avr?
Quoted text here. Click to load it

Switch to assembly?
Or use a better C compiler. What does the program do? I have used C on a
Tiny11 (Imagecraft).

Meindert



Re: How to strip a tiny avr?
Quoted text here. Click to load it

I expect you're using some large library function, either printf,
scanf, or some floating point stuff, or something of that nature.

How about actually posting the code you're trying to shrink rather than
trying to get us to read your mind?

-Mike


Re: How to strip a tiny avr?

Quoted text here. Click to load it
I second that.  Unless you're using a bone head tool chain with a bone
head library, you'll only pull in the library functions that you need,
so avoiding the really expensive ones (like printf) will avoid pulling
in huge amounts of stuff.  If your linker produces a map file you should
examine it to find what's getting pulled in from the library, then
consider what you can change so your application doesn't need it any more.

--

Tim Wescott
Wescott Design Services
We've slightly trimmed the long signature. Click to see the full one.
Re: How to strip a tiny avr?

Quoted text here. Click to load it

Nothing like that at all, no floating points.  Floating points would
pull in 3K at least.

Quoted text here. Click to load it

Just the follow 2 routines take up over 1K.  I guess tiny15 is
definitely out.  I think I will go with the tiny45.

int adc(int channel, int ref)
{
    int i, t, tt = 0;

    if(ref == AVCC)
        ADMUX = (1<<REFS0) | channel; // internal AVCC
    else
        ADMUX = (1<<REFS1) | channel; // internal 1.1

    ADCSRA = (1<<ADEN) | (1<<ADPS1) | (1<<ADPS0);    // set ADC prescaler
to , 1MHz / 8 = 125kHz

    //do a dummy readout first
    ADCSRA |= (1<<ADSC);        // do single conversion
    while(!(ADCSRA & 0x10));    // wait for conversion done, ADIF flag
active

    for(i=0;i<8;i++)            // do the ADC conversion 8 times for
better accuracy
    {
        ADCSRA |= (1<<ADSC);        // do single conversion
        while(!(ADCSRA & 0x10));    // wait for conversion done, ADIF
flag active

        t = ADCL;            // read out ADCL register
        t += (ADCH << 8);    // read out ADCH register

        tt += t;      // accumulate result (8 samples) for later
averaging
    }

    ADCSRA = 0;
    ADMUX = 0;

    tt >>= 4;     // average the samples

    return(tt);
}

char n[32];
char o[32];
char c[32];

remap(int code)
{
    int i,j;

    for(i=0; i<32; i++)
        o[i] = n[i];

    switch(code)
    {
        case 'y':
            n[0]=1; n[1]=2; n[2]=2; n[3]=1; n[4]=2; n[5]=2; n[6]=1; n[7]=2;
break;
        case 'p':
            n[0]=1; n[1]=3; n[2]=3; n[3]=3; n[4]=1; n[5]=3; n[6]=3; n[7]=3;
break;
        case 'g':
            n[0]=2; n[1]=3; n[2]=2; n[3]=3; n[4]=2; n[5]=3; n[6]=2; n[7]=3;
break;
        case 'r':
            n[0]=1; n[1]=2; n[2]=1; n[3]=3; n[4]=1; n[5]=2; n[6]=1; n[7]=3;
break;
        case 'b':
            n[0]=3; n[1]=1; n[2]=3; n[3]=3; n[4]=3; n[5]=2; n[6]=3; n[7]=3;
break;
    }

    for(i=0; i<8; i++)
    {
        n[i+8] = n[i];
        n[i+16] = n[i];
        n[i+24] = n[i];
    }

    for(i=0; i<3200; i++)
    {
        j = i/100;
        if(j < 32)
        {
            c[j] = n[j];
        }
    }
}


Re: How to strip a tiny avr?

Quoted text here. Click to load it

Why is there even a division in there ?

for( i = 0; i < 32; i++ )
    c[i] = n[i];

Saves more than 100 bytes.


Re: How to strip a tiny avr?

Quoted text here. Click to load it

It does not mean anything here, but I would need division in the real
program.  I am just sizing up the micros and my app.  I guess 1K and 2K
are not possible for me.  I am too lazy to code in assembly anyway.


Re: How to strip a tiny avr?


Quoted text here. Click to load it

ok, fair enough. If this sample is a good indication, I would estimate
that with some decent optimizations, this kind of code can be
compressed by a factor of two, maybe even in C, and certainly in
assembly. Whether this is worth the effort depends on the number of
units you'll be making, and what the cost difference is between the 2K
and 4K part. For anything less than say 1,000 units, the tiny45 is
probably the best choice.


Re: How to strip a tiny avr?

Quoted text here. Click to load it
  -- code snipped --

It could all be going to the C startup code (which seems odd, but who
knows?).  You could make your own custom startup code that only does
what you need, but if you're spending $$ to avoid assembly perhaps going
to a bigger processor is the right answer anyway.

--

Tim Wescott
Wescott Design Services
We've slightly trimmed the long signature. Click to see the full one.
Re: How to strip a tiny avr?
Quoted text here. Click to load it

I think you need a better compiler. I just compiled this for a tiny25
(because I haven't upgraded my Imagecraft compiler yet) and it produces 880
bytes of code. But.....  you seriously need to rethink the remap() function.
All these array operations take huge amounts of code.

Meindert



Re: How to strip a tiny avr?

Quoted text here. Click to load it

FWIW I compiled this with GCC 3.4.6 and it generated 418 bytes of code.
This was measured by adding the code to an existing program and
re-compiling - the program grew by 418 bytes. All the generated code was
included. None was optimized out. The .bss segment grew by 90 bytes.

Pete Harrison



Re: How to strip a tiny avr?

Quoted text here. Click to load it

That's what I though.  WinAVR (based on older gcc?) is inefficent.   We
need to prototype the project under AVRstudio/WinAVR, but perhaps
recompile it natively under gcc for production.


Re: How to strip a tiny avr?
Quoted text here. Click to load it
That was with WinAVR. The version I have uses GCC 3.4.6

The optimisation level was O2 I think.

Pete

Re: How to strip a tiny avr?
Quoted text here. Click to load it

A compiler's optimizer is not omnipotent. A bit of sensible
optimization can dramatically improve things; try this as a
replacement for your cruddy remap. I didn't optimise the last
loop because you said you wanted it, though with "gcc -O6"
it makes no difference(!). The extra benefit is that the code
is *much more readable* also.

Clifford Heath.
------------------------ Cut Here ------------------------

char n[32];
char o[32];
char c[32];

static void copy(char* t, char const* f, int size)
{
        while (size-- > 0)
                *t++ = *f++;
}

remap(int code)
{
        static  char const      y_val[8] = { 1,2,2,1,2,2,1,2 };
        static  char const      p_val[8] = { 1,3,3,3,1,3,3,3 };
        static  char const      g_val[8] = { 2,3,2,3,2,3,2,3 };
        static  char const      r_val[8] = { 1,2,1,3,1,2,1,3 };
        static  char const      b_val[8] = { 3,1,3,3,3,2,3,3 };
        char const*     val;
        int     i,j;

        copy(o, n, 32);

        switch(code)
        {
        case 'y': val = y_val; break;
        case 'p': val = p_val; break;
        case 'g': val = g_val; break;
        case 'r': val = r_val; break;
        case 'b': val = b_val; break;
        }
        copy(n, val, 8);
        copy(n+8, val, 8);
        copy(n+16, n, 16);

        for (i=0; i<3200; i++)
        {
                j = i/100;
                if (j < 32)
                        c[j] = n[j];
        }
}

Re: How to strip a tiny avr?
Quoted text here. Click to load it

Did you disassemble the binary to see what's actually included ?
Sometimes an innocent looking library call can pull in a lot of extra
code. When using avr-gcc for Tiny45, compiling an empty C program, I
get 96 bytes of binary, mostly interrupt vector table, and bss/data
segment initialization.

Extra library stuff may be avoided by setting compiler/linker/library
options (depending on the environment), or sometimes by providing your
own dummy implementation of functions. Suppose you need library call
"A", but "A" needs library call "B" for rare cases that don't apply to
your project, you can define a dummy function "B" yourself, and avoid
pulling in the big library version.


Re: How to strip a tiny avr?



Quoted text here. Click to load it

I bet this is the size of the hex file, not the binary file :)))
Perhaps you also have the debug info, printf and the other bulky stuff
included.

Vladimir Vassilevsky

DSP and Mixed Signal Design Consultant

http://www.abvolt.com


Re: How to strip a tiny avr?

Quoted text here. Click to load it

have a look at:
mcu.hk

this may help.

Don...


--
Don McKenzie
E-Mail Contact Page:               http://www.dontronics.com/e-mail.html

We've slightly trimmed the long signature. Click to see the full one.
Re: How to strip a tiny avr?
Quoted text here. Click to load it

Whoops! Thats half of what ImageCraft does. Impressive!!
For remap(): imagecraft produces 0x206 words while IAR produces 0x110 words.

Ok Richard, what gives?

Meindert



Site Timeline