Removing interrupt vector table.

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

In an effort to remove the interrupt table  I added the following to the linker config in studio

-nostartfiles -nodefaultlibs 

and the following code from a very old thread.

void __jumpMain     (void) __attribute__ ((naked)) __attribute__ ((section (".init9")));

void __jumpMain(void)
{    
    asm volatile ( ".set __stack, %0" :: "i" (RAMEND) );
    asm volatile ( "clr __zero_reg__" );        // r1 set to 0
    asm volatile ( "rjmp main");                   // jump to main()
}

void main(void){

 

 This worked to remove the table, but now when any function is called, it returns back to jumpMain()

What is the ".init9" above?

What is the line with ",set __Stack"?

 

 

Without the above, the vector table is present and main is treated like a function, with lots of pushes at its beginning.

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

I guess first you need to tell which model of AVR you are using.

 

Then, to keep our interest, tell us why removing the vector table is important.

 

"studio" is a broad term.  Studio version; and assuming GCC compiler/library version.

 

Perhaps the results of the build are pertinent.

 

Yes, AFAIK GCC calls main.  But see the '2313 complete app below--I don't see no stankin' pushes...

 

//---Includes
#include <avr/io.h>                    // Include AVR device-specific IO definitions
#include <avr/interrupt.h>

unsigned char flag;
unsigned char my_flag;


__attribute__ ((noinline)) unsigned char Fetch_flag()   {
	return flag;
}
int main(void) 
{
for (unsigned char i = 0; i < 10; i++)	
	{
	my_flag = Fetch_flag();
	}

	PORTB = my_flag;
	while(1);
	return 0;
}

ISR(TIMER0_OVF_vect) {
	flag++;
}


GccApplication1.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000084  00000000  00000000  00000074  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .bss          00000002  00800060  00800060  000000f8  2**0
                  ALLOC
  2 .comment      00000030  00000000  00000000  000000f8  2**0
                  CONTENTS, READONLY
  3 .debug_aranges 00000030  00000000  00000000  00000128  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_info   000000ff  00000000  00000000  00000158  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_abbrev 000000b9  00000000  00000000  00000257  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_line   00000105  00000000  00000000  00000310  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_frame  00000054  00000000  00000000  00000418  2**2
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_str    00000147  00000000  00000000  0000046c  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_loc    0000007d  00000000  00000000  000005b3  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_ranges 00000020  00000000  00000000  00000630  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 <__vectors>:
   0:	14 c0       	rjmp	.+40     	; 0x2a <__ctors_end>
   2:	21 c0       	rjmp	.+66     	; 0x46 <__bad_interrupt>
   4:	20 c0       	rjmp	.+64     	; 0x46 <__bad_interrupt>
   6:	1f c0       	rjmp	.+62     	; 0x46 <__bad_interrupt>
   8:	1e c0       	rjmp	.+60     	; 0x46 <__bad_interrupt>
   a:	1d c0       	rjmp	.+58     	; 0x46 <__bad_interrupt>
   c:	28 c0       	rjmp	.+80     	; 0x5e <__vector_6>
   e:	1b c0       	rjmp	.+54     	; 0x46 <__bad_interrupt>
  10:	1a c0       	rjmp	.+52     	; 0x46 <__bad_interrupt>
  12:	19 c0       	rjmp	.+50     	; 0x46 <__bad_interrupt>
  14:	18 c0       	rjmp	.+48     	; 0x46 <__bad_interrupt>
  16:	17 c0       	rjmp	.+46     	; 0x46 <__bad_interrupt>
  18:	16 c0       	rjmp	.+44     	; 0x46 <__bad_interrupt>
  1a:	15 c0       	rjmp	.+42     	; 0x46 <__bad_interrupt>
  1c:	14 c0       	rjmp	.+40     	; 0x46 <__bad_interrupt>
  1e:	13 c0       	rjmp	.+38     	; 0x46 <__bad_interrupt>
  20:	12 c0       	rjmp	.+36     	; 0x46 <__bad_interrupt>
  22:	11 c0       	rjmp	.+34     	; 0x46 <__bad_interrupt>
  24:	10 c0       	rjmp	.+32     	; 0x46 <__bad_interrupt>
  26:	0f c0       	rjmp	.+30     	; 0x46 <__bad_interrupt>
  28:	0e c0       	rjmp	.+28     	; 0x46 <__bad_interrupt>

0000002a <__ctors_end>:
  2a:	11 24       	eor	r1, r1
  2c:	1f be       	out	0x3f, r1	; 63
  2e:	cf ed       	ldi	r28, 0xDF	; 223
  30:	cd bf       	out	0x3d, r28	; 61

00000032 <__do_clear_bss>:
  32:	20 e0       	ldi	r18, 0x00	; 0
  34:	a0 e6       	ldi	r26, 0x60	; 96
  36:	b0 e0       	ldi	r27, 0x00	; 0
  38:	01 c0       	rjmp	.+2      	; 0x3c <.do_clear_bss_start>

0000003a <.do_clear_bss_loop>:
  3a:	1d 92       	st	X+, r1

0000003c <.do_clear_bss_start>:
  3c:	a2 36       	cpi	r26, 0x62	; 98
  3e:	b2 07       	cpc	r27, r18
  40:	e1 f7       	brne	.-8      	; 0x3a <.do_clear_bss_loop>
  42:	05 d0       	rcall	.+10     	; 0x4e <main>
  44:	1d c0       	rjmp	.+58     	; 0x80 <_exit>

00000046 <__bad_interrupt>:
  46:	dc cf       	rjmp	.-72     	; 0x0 <__vectors>

00000048 <Fetch_flag>:
unsigned char my_flag;


__attribute__ ((noinline)) unsigned char Fetch_flag()   {
	return flag;
}
  48:	80 91 60 00 	lds	r24, 0x0060
  4c:	08 95       	ret

0000004e <main>:
int main(void) 
{
  4e:	ca e0       	ldi	r28, 0x0A	; 10
for (unsigned char i = 0; i < 10; i++)	
	{
	my_flag = Fetch_flag();
  50:	fb df       	rcall	.-10     	; 0x48 <Fetch_flag>
  52:	80 93 61 00 	sts	0x0061, r24
  56:	c1 50       	subi	r28, 0x01	; 1
__attribute__ ((noinline)) unsigned char Fetch_flag()   {
	return flag;
}
int main(void) 
{
for (unsigned char i = 0; i < 10; i++)	
  58:	d9 f7       	brne	.-10     	; 0x50 <main+0x2>
	{
	my_flag = Fetch_flag();
	}

	PORTB = my_flag;
  5a:	88 bb       	out	0x18, r24	; 24
  5c:	ff cf       	rjmp	.-2      	; 0x5c <main+0xe>

0000005e <__vector_6>:
	while(1);
	return 0;
}

ISR(TIMER0_OVF_vect) {
  5e:	1f 92       	push	r1
  60:	0f 92       	push	r0
  62:	0f b6       	in	r0, 0x3f	; 63
  64:	0f 92       	push	r0
  66:	11 24       	eor	r1, r1
  68:	8f 93       	push	r24
	flag++;
  6a:	80 91 60 00 	lds	r24, 0x0060
  6e:	8f 5f       	subi	r24, 0xFF	; 255
  70:	80 93 60 00 	sts	0x0060, r24
}
  74:	8f 91       	pop	r24
  76:	0f 90       	pop	r0
  78:	0f be       	out	0x3f, r0	; 63
  7a:	0f 90       	pop	r0
  7c:	1f 90       	pop	r1
  7e:	18 95       	reti

00000080 <_exit>:
  80:	f8 94       	cli

00000082 <__stop_program>:
  82:	ff cf       	rjmp	.-2      	; 0x82 <__stop_program>

So perhaps post a complete small test program that we can work with.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

 

We needed a custom bootloader.  None of the common ones could be used easily;fboot,blips,etc.

Did not really want to write in assembly, so we started with the AVR109 source

After tuning it, we got it down to 580 bytes.   But that's when we noticed the stack issue.

The micro is a ATMEGA64

We still use Studio 4.18.......have had no reason to change.

WinAVR-20100110

 

I guess fundamentally, we just want to know what magic dust to use to remove the vector table.

Last Edited: Mon. Apr 13, 2015 - 09:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You have to set the stack pointer yourself when you use -hostartfiles.

 

See what I do at line 126 onwards in this...

 

https://spaces.atmel.com/gf/proj...

Last Edited: Mon. Apr 13, 2015 - 09:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Clawson,

 

Per your example, I added:

 

SREG = 0;
SP = RAMEND;

 

That fixed the problem

 

Then I returned to the code snippet above and found that I could comment out two of the lines and noticed no difference

void __jumpMain     (void) __attribute__ ((naked)) __attribute__ ((section (".init9")));

void __jumpMain(void)
{    
//    asm volatile ( ".set __stack, %0" :: "i" (RAMEND) );
//    asm volatile ( "clr __zero_reg__" );        // r1 set to 0
    asm volatile ( "rjmp main");                   // jump to main()
}

void main(void){

What does the ".init9"  mean?

Last Edited: Mon. Apr 13, 2015 - 09:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We still use Studio 4.18.......have had no reason to change.

WinAVR-20100110

Well, I guess you have found a reason now.  You are despairing over some pushes.  With a 5-year-old version.  Mom:  "What did you THINK was going to happen?!?"

 

What does the ".init9"  mean?

What does da book say?

http://nongnu.org/avr-libc/user-...

 

[Your version might very well be in the GCC era of re-entrant main() which would explain your symptoms.]

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Apr 13, 2015 - 10:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I thought I was out of the woods, but it appears that no registers are being pushed to the stack when functions are called.  Hence these registers which hold variables are getting clobbered and when the function returns, things go crazy

What have I done to suppress push/pop or what haven't I done to enable this?

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

//    asm volatile ( "clr __zero_reg__" );        // r1 set to 0

 This may appear to be unnecessary, but you really do want to include it.  The registers seem to be initialized to zero on powerup, but they are NOT on reset, and you can get weird behavior.  (This was the cause of an actual bug over in Arduino-land.)

 

Why don't you disassemble your program (with avr-objdump -S) to see what the start code actually looks like?

 

it appears that no registers are being pushed to the stack when functions are called. 

Registers are not normally pushed on the stack "when functions are called."  They are pushed when a function is entered, but only if necessary.

 

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

Westfw,

 

You were exactly right.  I uncommented those lines and now the world makes sense again.

The fact that there are no pushes/pops is apparently the compiler doing a good job of optimizing.

Last Edited: Wed. Apr 15, 2015 - 12:48 PM