[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-gcc-list] Re: Strange compile behaviour

From: David Brown
Subject: [avr-gcc-list] Re: Strange compile behaviour
Date: Tue, 02 Feb 2010 13:08:14 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv: Gecko/20100111 Lightning/1.0b1 Thunderbird/3.0.1

When you have the compile loop enabled, the code will wait until app_TXIncomming is zero before moving on. The reason the generated code is smaller with the loop enabled is that the optimiser knows that app_TXIncomming must be zero from then on, thus it can figure out the address of configMsg->BufferFull at compile time and save some code.

Other than that, my guess would be that you are running the code with app_TXIncomming with some non-zero, invalid value. When the loop is there, the body of the code won't be run until app_TXIncomming is zero. Without the loop, it will be run and something goes wrong (in WISP_Put_Flags, I expect).



On 02/02/2010 11:35, Han Hoekstra wrote:
Hello all,

I hope someone can help me with a strange problem I have.

What I see is that there is a problem with my stack, I check if the 2
bytes at __bss_end and __bss_end + 1 have a specific value, which I put
in them, so I can detect stack overflows in my application. I have a
piece of code that will generate a stack problem depending on if I
enable or disable a while loop in that piece of code.

The code is :

*while* (app_TXIncomming != 0) {

} /* while */

configMsg = &app_RS232_TX_Buffers [app_TXIncomming];

*if* (!configMsg->BufferFull) {

/* There is free space, so create the message */

/* We will send NoConfig_ind messages to the base CPU and the

* base Extender, because we don't know what is in the

* _basestation_ */

app_GenAddress.NetworkID = NETWORK_ID_BROADCAST;

app_GenAddress.DeviceID = DEVICE_ID_BROADCAST;

*switch* (stepStateNoConfig) {


app_GenAddress.DeviceType = DEVTYPE_WS_BASE_CPU;

stepStateNoConfig = /app_NOCONFIGSTEP_EXTENDER/;



app_GenAddress.DeviceType = DEVTYPE_WS_EXTENDER;

stepStateNoConfig = /app_NOCONFIGSTEP_BASECPU/;


} /* switch */

//WISP_Put_Flags (configMsg, 0);

WISP_Put_Flags (configMsg, 0);

This code is part of a larger function.

A little explanation of the code:

configMsg pointer to the same type as the array app_RS232_TX_Buffers

app_TXIncomming the index of the next buffer that I can use to create a
message that must be transmitted via the RS-232 port.

app_GenAddress a structure that can contain an address as we use it

What I see no is that when the while loop at the beginning is compiled
into the code, everything is running OK, but when I comment it out, so
it is not in de code, the stack check fails, indicating that __bss_end
and __bss_end + 1 no longer have the specific test values.

Below is the part of the .lst file for both cases.

With commented out while loop:


585 lds r24,app_TXIncomming

586 mul r24,r16

587 012a 84E0 movw r30,r0

588 012c 0E94 0000 clr r1

589 0130 00C0 subi r30,lo8(-(app_RS232_TX_Buffers))

590 sbci r31,hi8(-(app_RS232_TX_Buffers))

592 .LM51:

593 0132 8091 0000 ldd r24,Z+1

594 0136 809F tst r24

595 0138 F001 brne .L20

597 013c E050 .LM52:

598 013e F040 sts app_GenAddress,__zero_reg__

600 .LM53:

601 0140 8181 sts (app_GenAddress+2)+1,__zero_reg__

602 0142 8823 sts app_GenAddress+2,__zero_reg__

604 .LM54:

605 tst r17

606 0146 1092 0000 brne .L45

608 .LM55:

609 014a 1092 0000 sts app_GenAddress+1,r15

610 014e 1092 0000 ldi r17,lo8(1)

611 .L21:

613 0152 1123 .LM56:

614 0154 01F4 movw r24,r30

615 ldi r22,lo8(0)

616 call WISP_Put_Flags

With while loop in place:


583 0126 0E94 0000 .LM50:

584 012a 00C0 lds r24,app_RS232_TX_Buffers+1

585 tst r24

586 012c 8091 0000 brne .L21

588 .LM51:

589 sts app_GenAddress,__zero_reg__

591 0132 01F4 .LM52:

592 sts (app_GenAddress+2)+1,__zero_reg__

593 sts app_GenAddress+2,__zero_reg__

595 0138 8823 .LM53:

596 013a 01F4 tst r17

597 brne .L47

599 013c 1092 0000 .LM54:

600 sts app_GenAddress+1,r16

601 ldi r17,lo8(1)

602 0140 1092 0000 .L22:

604 .LM55:

605 ldi r24,lo8(app_RS232_TX_Buffers)

606 0148 1123 ldi r25,hi8(app_RS232_TX_Buffers)

607 014a 01F4 ldi r22,lo8(0)

608 call WISP_Put_Flags

When I leave the while loop in the code, the code is smaller than
without the while loop, which seems strange, because the while loop has
no effect on the actual code.

I am using the latest WinAVR with AVR-GCC 4.3.3 at the moment, but I
started with the previous version AVR-GCC 4.3.2, which did the exact
same thing.

Optimisation is set to size, I am using an ATMega168. Optimisations that
I use are :

-mcall-prologues, -ffunction-sections, -fdata-sections,
-fno-free-loop-optimize, -fno-inline, -fno-tree-scev-cprop, -fpack-struct

This seems to give me the smallest code, which is what I need, because I
am almost at the limit of code space.

The most simple solution would be to just keep the while loop in the
code, but since it does nothing, it is a strange piece of code to keep
in my application and what other parts of the code would have similar
problems and would also require something like this ?!

Does anyone know what is going wrong here ?




Han Hoekstra

Software Engineer

Wireless Value B.V.
Waanderweg 30a
7812 HZ Emmen
Tel: +31-591-633200
Fax: +31-591-631197
Web: www.wirelessvalue.nl <http://www.wirelessvalue.nl>

__________ Information from ESET NOD32 Antivirus, version of virus
signature database 4827 (20100202) __________

The message was checked by ESET NOD32 Antivirus.


AVR-GCC-list mailing list

reply via email to

[Prev in Thread] Current Thread [Next in Thread]