GIE disables itself - AS6

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I have a problem with my program. Global Interrupts disables itself.
I am using Atmel Studio 6 SP1 with latest tool-chain (Version: 3.4.1.798 - GCC 4.6.2) and default project settings. Target CPU is ATmega16.
I've managed to isolate the problem in this simple test case:
Interrupts are disabled by BufferAdd function, the question is why? :-(
Thanks for your help.

#include 
#include 

typedef struct
{
	uint8_t address;
	uint8_t data[5];

} Message;

typedef struct
{
	Message mess[4];
	uint8_t Head;
	uint8_t Tail;
} TransmitBufer ;

TransmitBufer buff;


void BufferAdd(Message msg)
{
	buff.Head++;
	buff.mess[buff.Head] = msg;
}

int main(void)
{
	sei(); //Interrupts are enabled
	
	Message msg;
	BufferAdd(msg); //GIE disables itself here!
	
	while(1)
	{
		asm volatile ("nop"); 
	}
}
Last Edited: Mon. Nov 12, 2012 - 12:42 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How can you tell?
What does the asm tell you?

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

be aware that there is a bug in as6 where single stepping over sei() causes a problem.

if you are having this problem try setting a breakpoint at BufferAdd(msg) rather than stepping to it.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I just built and simulated that for mega16 in AS6 1938 + 3.4.1 and did two "Step-over"s and I was still set when it reached the asm() in the while(). So exactly what are you doing to see this effect?

(as already noted AS6 has issue with the simulated execution of SEI).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
How can you tell?
What does the asm tell you?

Well, I am not an asm expert, but here is lss file (default debug build):
I thing, that there should not be cli instruction in BufferAdd function.

test1.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000112  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00800060  00000112  000001a6  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          0000001a  00800060  00800060  000001a6  2**0
                  ALLOC
  3 .stab         000006cc  00000000  00000000  000001a8  2**2
                  CONTENTS, READONLY, DEBUGGING
  4 .stabstr      00000085  00000000  00000000  00000874  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_aranges 00000060  00000000  00000000  00000900  2**3
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_info   00000297  00000000  00000000  00000960  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_abbrev 0000003c  00000000  00000000  00000bf7  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_line   000001a7  00000000  00000000  00000c33  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 2a 00 	jmp	0x54	; 0x54 <__ctors_end>
   4:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
   8:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
   c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  10:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  14:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  18:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  1c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  20:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  24:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  28:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  2c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  30:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  34:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  38:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  3c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  40:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  44:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  48:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  4c:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>
  50:	0c 94 47 00 	jmp	0x8e	; 0x8e <__bad_interrupt>

00000054 <__ctors_end>:
  54:	11 24       	eor	r1, r1
  56:	1f be       	out	0x3f, r1	; 63
  58:	cf e5       	ldi	r28, 0x5F	; 95
  5a:	d4 e0       	ldi	r29, 0x04	; 4
  5c:	de bf       	out	0x3e, r29	; 62
  5e:	cd bf       	out	0x3d, r28	; 61

00000060 <__do_copy_data>:
  60:	10 e0       	ldi	r17, 0x00	; 0
  62:	a0 e6       	ldi	r26, 0x60	; 96
  64:	b0 e0       	ldi	r27, 0x00	; 0
  66:	e2 e1       	ldi	r30, 0x12	; 18
  68:	f1 e0       	ldi	r31, 0x01	; 1
  6a:	02 c0       	rjmp	.+4      	; 0x70 <__do_copy_data+0x10>
  6c:	05 90       	lpm	r0, Z+
  6e:	0d 92       	st	X+, r0
  70:	a0 36       	cpi	r26, 0x60	; 96
  72:	b1 07       	cpc	r27, r17
  74:	d9 f7       	brne	.-10     	; 0x6c <__do_copy_data+0xc>

00000076 <__do_clear_bss>:
  76:	10 e0       	ldi	r17, 0x00	; 0
  78:	a0 e6       	ldi	r26, 0x60	; 96
  7a:	b0 e0       	ldi	r27, 0x00	; 0
  7c:	01 c0       	rjmp	.+2      	; 0x80 <.do_clear_bss_start>

0000007e <.do_clear_bss_loop>:
  7e:	1d 92       	st	X+, r1

00000080 <.do_clear_bss_start>:
  80:	aa 37       	cpi	r26, 0x7A	; 122
  82:	b1 07       	cpc	r27, r17
  84:	e1 f7       	brne	.-8      	; 0x7e <.do_clear_bss_loop>
  86:	0e 94 75 00 	call	0xea	; 0xea 
8a: 0c 94 87 00 jmp 0x10e ; 0x10e <_exit> 0000008e <__bad_interrupt>: 8e: 0c 94 00 00 jmp 0 ; 0x0 <__vectors> 00000092 : 92: cf 93 push r28 94: df 93 push r29 96: 00 d0 rcall .+0 ; 0x98 98: 00 d0 rcall .+0 ; 0x9a 9a: 00 d0 rcall .+0 ; 0x9c 9c: cd b7 in r28, 0x3d ; 61 9e: de b7 in r29, 0x3e ; 62 a0: 49 83 std Y+1, r20 ; 0x01 a2: 5a 83 std Y+2, r21 ; 0x02 a4: 6b 83 std Y+3, r22 ; 0x03 a6: 7c 83 std Y+4, r23 ; 0x04 a8: 8d 83 std Y+5, r24 ; 0x05 aa: 9e 83 std Y+6, r25 ; 0x06 ac: 80 91 78 00 lds r24, 0x0078 b0: 8f 5f subi r24, 0xFF ; 255 b2: 80 93 78 00 sts 0x0078, r24 b6: 90 e0 ldi r25, 0x00 ; 0 b8: fc 01 movw r30, r24 ba: ee 0f add r30, r30 bc: ff 1f adc r31, r31 be: e8 0f add r30, r24 c0: f9 1f adc r31, r25 c2: ee 0f add r30, r30 c4: ff 1f adc r31, r31 c6: e0 5a subi r30, 0xA0 ; 160 c8: ff 4f sbci r31, 0xFF ; 255 ca: de 01 movw r26, r28 cc: 11 96 adiw r26, 0x01 ; 1 ce: 86 e0 ldi r24, 0x06 ; 6 d0: 0d 90 ld r0, X+ d2: 01 92 st Z+, r0 d4: 81 50 subi r24, 0x01 ; 1 d6: e1 f7 brne .-8 ; 0xd0 d8: 26 96 adiw r28, 0x06 ; 6 da: 0f b6 in r0, 0x3f ; 63 dc: f8 94 cli de: de bf out 0x3e, r29 ; 62 e0: 0f be out 0x3f, r0 ; 63 e2: cd bf out 0x3d, r28 ; 61 e4: df 91 pop r29 e6: cf 91 pop r28 e8: 08 95 ret 000000ea
: ea: cf 93 push r28 ec: df 93 push r29 ee: 00 d0 rcall .+0 ; 0xf0 f0: 00 d0 rcall .+0 ; 0xf2 f2: 00 d0 rcall .+0 ; 0xf4 f4: cd b7 in r28, 0x3d ; 61 f6: de b7 in r29, 0x3e ; 62 f8: 78 94 sei fa: 49 81 ldd r20, Y+1 ; 0x01 fc: 5a 81 ldd r21, Y+2 ; 0x02 fe: 6b 81 ldd r22, Y+3 ; 0x03 100: 7c 81 ldd r23, Y+4 ; 0x04 102: 8d 81 ldd r24, Y+5 ; 0x05 104: 9e 81 ldd r25, Y+6 ; 0x06 106: 0e 94 49 00 call 0x92 ; 0x92 10a: 00 00 nop 10c: fe cf rjmp .-4 ; 0x10a 0000010e <_exit>: 10e: f8 94 cli 00000110 <__stop_program>: 110: ff cf rjmp .-2 ; 0x110 <__stop_program>

gregd99 wrote:
be aware that there is a bug in as6 where single stepping over sei() causes a problem.

if you are having this problem try setting a breakpoint at BufferAdd(msg) rather than stepping to it.


Where can I find more about this bug? Is it only in simulator? My problem is in real hardware also (ATmega16 with JTAGICE3)

clawson wrote:
I just built and simulated that for mega16 in AS6 1938 + 3.4.1 and did two "Step-over"s and I was still set when it reached the asm() in the while(). So exactly what are you doing to see this effect?

Hmm, two "Step-over"s works fine, but more will disable GIE.
Another way to reproduce:
1, Put breakpoint at line. "BufferAdd(msg); //GIE disables itself here!"
2, Start debuging, programs breaks at break point - GIE is enabled
3, step into - GIE disabled... :-( (In simulator it takes 2 step into)
3b, "step over" works fine, but after second "step over" GIE is also disabled

It happened in simulator and over JTAG with JTAGICE3

Last Edited: Mon. Nov 12, 2012 - 10:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

there should not be cli instruction in BufferAdd function

yes there should - it's protection while the (double register) stack pointer is being changed. Suppose the code had only changed one half of SPL/SPH and an interrupt occurred - it could be fatal! If you see the source generated for your code:

	adiw r28,6	 ; ,
	in __tmp_reg__,__SREG__
	cli
	out __SP_H__,r29	 ; 
	out __SREG__,__tmp_reg__
	out __SP_L__,r28	 ; 
	pop r29	 ; 
	pop r28	 ; 
	ret

you can see exactly what the compiler is up to. It's adjusting the stack back up by 6 bytes so it adds 6 to R29:R28 which now hold the new stack value. It then reads SREG to __tmp_reg__ (that is R0) and disables interrupts. It then starts to store the newly adjusted (by 6 bytes) stack value. It stores one half to SPH. It may seem odd that it then does an OUT to put SREG back the way it was but this is relying on a feature of the AVR that the change will not come into effect until one opcode later. So it then stores SPL with the new value and it's at the end of that opcode that the change to SREG comes into effectso I is now back the way it was when originally copied into __temp_reg__. Finally it recovers R29:R28 (also known as "Y") which is the stack frame pointer and it returns.

All this is completely normal and exactly what you would expect.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

there should not be cli instruction in BufferAdd function

yes there should - it's protection while the (double register) stack pointer is being changed.

Ohh, you are right. I can see it now. 0x3f is SREG address, so GIE state is restored after cli.
Well that means that this is not GCC bug, but AS6 bug. Stepping just does not work. Workaround is moving through code just using breakpoints.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

but AS6 bug. Stepping just does not work. Workaround is moving through code just using breakpoints.

Indeed - that's what Greg told you above - it's a well know fault in AS6's simulator - it cannot step over an SEI.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

but AS6 bug. Stepping just does not work. Workaround is moving through code just using breakpoints.

Indeed - that's what Greg told you above - it's a well know fault in AS6's simulator - it cannot step over an SEI.

not only in simulator, but even with JTAGICE3. And not only at sei instruction, but in whole program

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The SEI bug in the sim/tools should be corrected in the latest patch release of Atmel Studio - update from the extension manager.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser wrote:
The SEI bug in the sim/tools should be corrected in the latest patch release of Atmel Studio - update from the extension manager.

- Dean :twisted:


I already have latest version (at least I thing). I installed AS6, then SP1 and then updated avrgcc with extension manager.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I tried it with a mega324PA. It worked fine with a Dragon and it worked fine with the Simulator.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I copied project to different PC and it works! This is really strange because all installed packages versions in both PC match. :evil: (in help -> about atmel studio)
So I am trying to reinstall AS now.
Update: I applied SP1 and problem is still same (can't update to leatest toolchain through extension manager because Atmel update pages are down :evil: )

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had some unexplained behaviours when I installed on win7 without runas admin. even though my account had admin privilege this seemed to make a difference. just a suggestion.

regards
Greg

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gregd99 wrote:
I had some unexplained behaviours when I installed on win7 without runas admin. even though my account had admin privilege this seemed to make a difference. just a suggestion.

Thanks, but this is probably not my case, because I have just one default account on both PCs. Both are Win7.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have any ideas how to correct this problem ?
I spent nearly whole of the weekend, because my code sometimes reaches interrupt-service-routines and sometimes not.
E.g. I stepped through the code sending data via SPI and never got a SPI-ready-IRQ.
Yesterday i found out that the Global-Interrupt flag is de-activated sometimes without intention. This happens with real-hardware (at90CAN128, AVR Dragon AS6.1938)

I program like a man:
COPY CON: > firmware.hex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Yesterday i found out that the Global-Interrupt flag is de-activated sometimes without intention. This happens with real-hardware (at90CAN128, AVR Dragon AS6.1938)

But does it really happen in the hardware or is it a fault in the debugger. If you forget the debugger and instead send SREG as hex digits over the UART or an LCD from time to time is the bit really reset? I don't think it will be.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As I wrote before:

Single-Stepping into my subroutine disables the I-Flag. For me it seems that teh I-Flag then stays disabled.
Inmy case this affects CAN: Inside the subroutine a CAN-Message is sent, but the according ISR is then never reached.

The same happened to SPI-complete ISR.

I program like a man:
COPY CON: > firmware.hex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am sorry, I don't have UART at this layout.

I program like a man:
COPY CON: > firmware.hex

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes but it's already been established that the debugger cannot handle single stepping over opcodes that change I so avoid doing that. Use breakpoints and "run to" instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Yes but it's already been established that the debugger cannot handle single stepping over opcodes that change I so avoid doing that. Use breakpoints and "run to" instead.

Well, I have one PC where everything is working fine (as far as I can tell) and one where it does not. Only difference is that working PC uses 32b version of windows 7. (installed in virtual box) So maybe it is just problem of 64b windows? Does anyone else experiencing this problem at 32b windows?

Update: I discovered there is an option in: Tool -> Options -> Debugger -> "Mask interrupts while stepping"
Try to change this to false.