Producing code without interrupt table testing

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

I've used the -nostartfiles option before and found that gcc oddly includes some startup code, but leaves some startup code out.  In fact, doing a comparison between a mostly empty application and then the output by adding the -nostartfiles option shows that you still get code to copy data from flash to sram and also clear sram for globals.  The problem is that it does setup the stack or R1 and it doesn't call main and then do the cli/loop if main returns.

 

I found that by doing this:

 

//avr/gnu linker, miscellanous, other linker flags:  -Wl,--section-start=.text=0x3800 -nostartfiles
__attribute__((naked,section(".vectors"))) void start(void)
{
  asm("eor r1,r1");
  SREG=0;
  SP=RAMEND;
  asm("jmp __ctors_end");
}

int main();

__attribute__((naked,section(".init9"))) void start2(void)
{
  main();
  cli();
  for(;;);
}

I can get it to output code very much near what it normally would except no interrupt table.  The vectors "start" does the r1 clear/sreg/stack.  Then the copy/clear code is generated.  Then the "start2" calls main.  These sections seem to put this code where it is needed.

 

I tried it with bss to clear and bss to copy and it will either include or exclude those sections and work either way.

 

This saves you from having to write your own copy/clear code when the compiler is emitting code for them.  With both clear and copy it is 54 bytes.

 

Disassembly of section .text:

00003800 <start>:
#include "cdelay.h"

//avr/gnu linker, miscellanous, other linker flags:  -Wl,--section-start=.text=0x3800 -nostartfiles
__attribute__((naked,section(".vectors"))) void start(void)
{
  asm("eor r1,r1");
    3800:	11 24       	eor	r1, r1
  SREG=0;
    3802:	1f be       	out	0x3f, r1	; 63
  SP=RAMEND;
    3804:	8f ef       	ldi	r24, 0xFF	; 255
    3806:	9a e0       	ldi	r25, 0x0A	; 10
    3808:	9e bf       	out	0x3e, r25	; 62
    380a:	8d bf       	out	0x3d, r24	; 61

0000380c <__ctors_end>:
    380c:	11 e0       	ldi	r17, 0x01	; 1
    380e:	a0 e0       	ldi	r26, 0x00	; 0
    3810:	b1 e0       	ldi	r27, 0x01	; 1
    3812:	e6 e3       	ldi	r30, 0x36	; 54
    3814:	f8 e3       	ldi	r31, 0x38	; 56
    3816:	02 c0       	rjmp	.+4      	; 0x381c <__ctors_end+0x10>
    3818:	05 90       	lpm	r0, Z+
    381a:	0d 92       	st	X+, r0
    381c:	a0 30       	cpi	r26, 0x00	; 0
    381e:	b1 07       	cpc	r27, r17
    3820:	d9 f7       	brne	.-10     	; 0x3818 <__ctors_end+0xc>

00003822 <__do_clear_bss>:
    3822:	21 e0       	ldi	r18, 0x01	; 1
    3824:	a0 e0       	ldi	r26, 0x00	; 0
    3826:	b1 e0       	ldi	r27, 0x01	; 1
    3828:	01 c0       	rjmp	.+2      	; 0x382c <.do_clear_bss_start>

0000382a <.do_clear_bss_loop>:
    382a:	1d 92       	st	X+, r1

0000382c <.do_clear_bss_start>:
    382c:	a0 30       	cpi	r26, 0x00	; 0
    382e:	b2 07       	cpc	r27, r18
    3830:	e1 f7       	brne	.-8      	; 0x382a <.do_clear_bss_loop>

00003832 <start2>:
int main();

__attribute__((naked,section(".init9"))) void start2(void)
{
	main();
  cli();
    3832:	f8 94       	cli
  for(;;);
    3834:	ff cf       	rjmp	.-2      	; 0x3834 <start2+0x2>

 

Last Edited: Thu. Nov 2, 2017 - 09:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In the thread that Andy linked to note my comment in #8:

 

http://www.avrfreaks.net/comment...

 

That is:

 

By implementing these as hard linked functions they over-ride the weak linked library copies.

 

Though you should actually find that as long as there are no globals then you don't get the routines anyway. If you do have globals then surely you want them set up?

 

PS my equivalent of the CRT is:

 

...

 

And no, I don't know why the switch from spaces.atmel.com to spaces.microchip.com appears to have screwed the vertical spacing in code such as the above :-(

Last Edited: Wed. Nov 1, 2017 - 10:26 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I believe the symbols just need to be defined.

Defining them with linker options should be sufficient.

In assembly, two .global's and two .set's should do the trick.

 

The real issue, of course, is why one wants to.

 

International Theophysical Year seems to have been forgotten..
Anyone remember the song Jukebox Band?