my gcc8 built toolchain w/ ATmega DFP 2.0.12 not working for 4809

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

I'm working with the 4809 nano curiosity.  I had a routine to print a string constant.  It failed.  I traced it to the string constant not existing in sram.

Looking at the same C source compiled for mega328p and mega4809 leads to some significant differences.  I'm using objdump -D to peer into the binary.

 

 Notice below that the 328p elf has the string in the .data section and the 4809 elf has the string in the .rodata section, and that the do_copy_data code is inserted in the 328p object but not in the 4809 one.  I believe gcc is the tool that inserts the copy of text to data.  Any hints on why the 4809 is not being done?

 

The C code:

#define F_CPU 20000000UL

#include <avr/io.h>

char *s;

int main(void) {
  s = "abc";
  while (1);
}

Here is a relevant segment of the main.elf run through "avr-objdump -D main.elf for the 328p

Disassembly of section .data:

00800100 <__data_start>:
  800100:	61 62       	ori	r22, 0x21	; 33
  800102:	63 00       	.word	0x0063	; ????

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 34 00 	jmp	0x68	; 0x68 <__ctors_end>
   4:	0c 94 51 00 	jmp	0xa2	; 0xa2 <__bad_interrupt>
....
  64:	0c 94 51 00 	jmp	0xa2	; 0xa2 <__bad_interrupt>

00000068 <__ctors_end>:
  68:	11 24       	eor	r1, r1
  6a:	1f be       	out	0x3f, r1	; 63
  6c:	cf ef       	ldi	r28, 0xFF	; 255
  6e:	d8 e0       	ldi	r29, 0x08	; 8
  70:	de bf       	out	0x3e, r29	; 62
  72:	cd bf       	out	0x3d, r28	; 61

00000074 <__do_copy_data>:
  74:	11 e0       	ldi	r17, 0x01	; 1
  76:	a0 e0       	ldi	r26, 0x00	; 0
  78:	b1 e0       	ldi	r27, 0x01	; 1
  7a:	e8 eb       	ldi	r30, 0xB8	; 184
  7c:	f0 e0       	ldi	r31, 0x00	; 0
  7e:	02 c0       	rjmp	.+4      	; 0x84 <__do_copy_data+0x10>
  80:	05 90       	lpm	r0, Z+
  82:	0d 92       	st	X+, r0
  84:	a4 30       	cpi	r26, 0x04	; 4
  86:	b1 07       	cpc	r27, r17
  88:	d9 f7       	brne	.-10     	; 0x80 <__do_copy_data+0xc>

0000008a <__do_clear_bss>:
  8a:	21 e0       	ldi	r18, 0x01	; 1
  8c:	a4 e0       	ldi	r26, 0x04	; 4
  8e:	b1 e0       	ldi	r27, 0x01	; 1
  90:	01 c0       	rjmp	.+2      	; 0x94 <.do_clear_bss_start>

00000092 <.do_clear_bss_loop>:
  92:	1d 92       	st	X+, r1

00000094 <.do_clear_bss_start>:
  94:	a6 30       	cpi	r26, 0x06	; 6
  96:	b2 07       	cpc	r27, r18
  98:	e1 f7       	brne	.-8      	; 0x92 <.do_clear_bss_loop>
  9a:	0e 94 53 00 	call	0xa6	; 0xa6 <main>
  9e:	0c 94 5a 00 	jmp	0xb4	; 0xb4 <_exit>

000000a2 <__bad_interrupt>:
  a2:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

000000a6 <main>:
  a6:	80 e0       	ldi	r24, 0x00	; 0
  a8:	91 e0       	ldi	r25, 0x01	; 1
  aa:	90 93 05 01 	sts	0x0105, r25	; 0x800105 <__data_end+0x1>
  ae:	80 93 04 01 	sts	0x0104, r24	; 0x800104 <__data_end>
  b2:	ff cf       	rjmp	.-2      	; 0xb2 <main+0xc>

000000b4 <_exit>:
  b4:	f8 94       	cli

000000b6 <__stop_program>:
  b6:	ff cf       	rjmp	.-2      	; 0xb6 <__stop_program>

Here is the same for the 4809.

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 50 00 	jmp	0xa0	; 0xa0 <__ctors_end>
   4:	0c 94 62 00 	jmp	0xc4	; 0xc4 <__bad_interrupt>
...
  9c:	0c 94 62 00 	jmp	0xc4	; 0xc4 <__bad_interrupt>

000000a0 <__ctors_end>:
  a0:	11 24       	eor	r1, r1
  a2:	1f be       	out	0x3f, r1	; 63
  a4:	cf ef       	ldi	r28, 0xFF	; 255
  a6:	cd bf       	out	0x3d, r28	; 61
  a8:	df e3       	ldi	r29, 0x3F	; 63
  aa:	de bf       	out	0x3e, r29	; 62

000000ac <__do_clear_bss>:
  ac:	28 e2       	ldi	r18, 0x28	; 40
  ae:	a0 e0       	ldi	r26, 0x00	; 0
  b0:	b8 e2       	ldi	r27, 0x28	; 40
  b2:	01 c0       	rjmp	.+2      	; 0xb6 <.do_clear_bss_start>

000000b4 <.do_clear_bss_loop>:
  b4:	1d 92       	st	X+, r1

000000b6 <.do_clear_bss_start>:
  b6:	a2 30       	cpi	r26, 0x02	; 2
  b8:	b2 07       	cpc	r27, r18
  ba:	e1 f7       	brne	.-8      	; 0xb4 <.do_clear_bss_loop>
  bc:	0e 94 64 00 	call	0xc8	; 0xc8 <main>
  c0:	0c 94 6b 00 	jmp	0xd6	; 0xd6 <_exit>

000000c4 <__bad_interrupt>:
  c4:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

000000c8 <main>:
  c8:	8a ed       	ldi	r24, 0xDA	; 218
  ca:	90 e4       	ldi	r25, 0x40	; 64
  cc:	80 93 00 28 	sts	0x2800, r24	; 0x802800 <__DATA_REGION_ORIGIN__>
  d0:	90 93 01 28 	sts	0x2801, r25	; 0x802801 <__DATA_REGION_ORIGIN__+0x1>
  d4:	ff cf       	rjmp	.-2      	; 0xd4 <main+0xc>

000000d6 <_exit>:
  d6:	f8 94       	cli

000000d8 <__stop_program>:
  d8:	ff cf       	rjmp	.-2      	; 0xd8 <__stop_program>

Disassembly of section .rodata:

000040da <.rodata>:
    40da:	61 62       	ori	r22, 0x21	; 33
    40dc:	63 00       	.word	0x0063	; ????

 

Here is relevant section of the ldscript for the 328p (i.e., avr5.xn):

  .data          :
  {
     PROVIDE (__data_start = .) ;
    *(.data)
     *(.data*)
    *(.gnu.linkonce.d*)
    *(.rodata)  /* We need to include .rodata here if gcc is used */
    *(.rodata*) /* with -fdata-sections.  */
    *(.gnu.linkonce.r*)
    . = ALIGN(2);
     _edata = . ;
     PROVIDE (__data_end = .) ;
  }  > data AT> text

Here is the relevant section of the ldscript for the 4809 (i.e., avrxmega3.xn):

  .data          :
  {
     PROVIDE (__data_start = .) ;
    *(.data)
     *(.data*)
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
     _edata = . ;
     PROVIDE (__data_end = .) ;
  }  > data AT> text
  .rodata  ADDR(.text) + SIZEOF (.text) + __RODATA_PM_OFFSET__    :
  {
    *(.rodata)
     *(.rodata*)
    *(.gnu.linkonce.r*)
  } AT> text

The 328p ldscript has no .rodata section listed.

This topic has a solution.
Last Edited: Fri. Nov 29, 2019 - 03:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any hints on why the 4809 is not being done?

It doesn't need to be done, because on the 4809, all of flash appears in the data/ram address space.

 

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

> I had a routine to print a string constant.

 

What does that routine look like?

 

avr0/1-

 

const char mystring[] = "123";

void print_str(const char* str){}

print_str(mystring);

 

Nothing special needs to be done. If its a const, it goes in .rodata, and it is given a virtual address according to the datasheet memory map. In the case of mega4809, flash virtual address starts at 0x4000, which is in the linker script as __RODATA_PM_OFFSET__. No more pgm_read_stuff, or flash decorations, etc.

 

Your char* s is a data var, and is being loaded with the address 0x40DA which is physical flash address 0x00DA (can also check it out in the hex file). Your mega328 version is all data (even if const), as you have to jump through some hoops to get it into flash, and another set of hoops to get it out.

 

Last Edited: Thu. Nov 28, 2019 - 05:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MattRW wrote:
I had a routine to print a string constant.  It failed.
Tell us more about "failed"!

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

Here is similar code update from what mraardvark posted in another thread.

 

The "putchar" demo, between "#if 0" and "#else" works fine: it prints out "hi" in my minicom session.

The,the "putline" fails: it prints out continuous garbage.  If I limit the loop in putline to two characters it prints two garbage characters.

This is what I traced down to what I thought was unintialized data.  Now that I look again with "objdump -D" instead of "objdump -d" I see there is a .rodata section with hex 68, 'h', and 69, 'i', at 0x415c, and the call to putline with the correct address 0x415c as argument.  

 

So I have again I am left clueless.

 

#define F_CPU 20000000
#include <avr/io.h>
#include <util/delay.h>

#define BAUDRATE 9600
#define BAUD_FROM_RATE(RATE) ((4UL * (F_CPU))/(RATE))

void uart_init(void)
{
  USART3.BAUD = BAUD_FROM_RATE(BAUDRATE);
  USART3.CTRLC = USART_SBMODE_2BIT_gc | USART_CHSIZE_8BIT_gc;
}

void uart_on(void)
{
  // Enable TX
  USART3.CTRLB = USART_TXEN_bm;
  // TX pin to output
  PORTB.DIRSET = (1 << 0);
}

void uart_off(void)
{
  // Disable TX
  USART3.CTRLB &= ~USART_TXEN_bm;
}

void uart_putchar(char c)
{
  // Wait for space
  while (!(USART3.STATUS & USART_DREIF_bm)) ;
  USART3.TXDATAL = c;
}

void uart_putline(char *p)
{
   while (*p != '\0') {
      uart_putchar(*p++);
   }
   uart_putchar('\r');
   uart_putchar('\n');
}

int main(void)
{
  // TX pin pullup enable
  PORTB.PIN0CTRL = PORT_PULLUPEN_bm;

  // Button pullup
  PORTF.PIN6CTRL = PORT_PULLUPEN_bm;

  // Setup 20MHz clock
  _PROTECTED_WRITE((CLKCTRL.MCLKCTRLB), (0 << CLKCTRL_PEN_bp));

  // UART init
  uart_init();

  while (1) {
    // Wait for button
    while (PORTF.IN & (1 << 6)) ;

    uart_on();
#if 0
    uart_putchar('h');
    uart_putchar('i');
    uart_putchar('\r');
    uart_putchar('\n');
#else
    uart_putline("hi");
#endif
    uart_off();
    _delay_ms(100);
  }
}

 

Here is disassembled code via "objdump -D" with debug sections removed and interrupt list trimmed:

 

Disassembly of section .text:

00000000 <__vectors>:
   0:	0c 94 50 00 	jmp	0xa0	; 0xa0 <__ctors_end>
   4:	0c 94 5a 00 	jmp	0xb4	; 0xb4 <__bad_interrupt>
...
  98:	0c 94 5a 00 	jmp	0xb4	; 0xb4 <__bad_interrupt>
  9c:	0c 94 5a 00 	jmp	0xb4	; 0xb4 <__bad_interrupt>

000000a0 <__ctors_end>:
  a0:	11 24       	eor	r1, r1
  a2:	1f be       	out	0x3f, r1	; 63
  a4:	cf ef       	ldi	r28, 0xFF	; 255
  a6:	cd bf       	out	0x3d, r28	; 61
  a8:	df e3       	ldi	r29, 0x3F	; 63
  aa:	de bf       	out	0x3e, r29	; 62
  ac:	0e 94 8a 00 	call	0x114	; 0x114 <main>
  b0:	0c 94 ac 00 	jmp	0x158	; 0x158 <_exit>

000000b4 <__bad_interrupt>:
  b4:	0c 94 00 00 	jmp	0	; 0x0 <__vectors>

000000b8 <uart_init>:
  b8:	e0 e6       	ldi	r30, 0x60	; 96
  ba:	f8 e0       	ldi	r31, 0x08	; 8
  bc:	8d e8       	ldi	r24, 0x8D	; 141
  be:	90 e2       	ldi	r25, 0x20	; 32
  c0:	80 87       	std	Z+8, r24	; 0x08
  c2:	91 87       	std	Z+9, r25	; 0x09
  c4:	8b e0       	ldi	r24, 0x0B	; 11
  c6:	87 83       	std	Z+7, r24	; 0x07
  c8:	08 95       	ret

000000ca <uart_on>:
  ca:	80 e4       	ldi	r24, 0x40	; 64
  cc:	80 93 66 08 	sts	0x0866, r24	; 0x800866 <__TEXT_REGION_LENGTH__+0x7f4866>
  d0:	81 e0       	ldi	r24, 0x01	; 1
  d2:	80 93 21 04 	sts	0x0421, r24	; 0x800421 <__TEXT_REGION_LENGTH__+0x7f4421>
  d6:	08 95       	ret

000000d8 <uart_off>:
  d8:	e0 e6       	ldi	r30, 0x60	; 96
  da:	f8 e0       	ldi	r31, 0x08	; 8
  dc:	86 81       	ldd	r24, Z+6	; 0x06
  de:	8f 7b       	andi	r24, 0xBF	; 191
  e0:	86 83       	std	Z+6, r24	; 0x06
  e2:	08 95       	ret

000000e4 <uart_putchar>:
  e4:	90 91 64 08 	lds	r25, 0x0864	; 0x800864 <__TEXT_REGION_LENGTH__+0x7f4864>
  e8:	95 ff       	sbrs	r25, 5
  ea:	fc cf       	rjmp	.-8      	; 0xe4 <uart_putchar>
  ec:	80 93 62 08 	sts	0x0862, r24	; 0x800862 <__TEXT_REGION_LENGTH__+0x7f4862>
  f0:	08 95       	ret

000000f2 <uart_putline>:
  f2:	cf 93       	push	r28
  f4:	df 93       	push	r29
  f6:	ec 01       	movw	r28, r24
  f8:	89 91       	ld	r24, Y+
  fa:	81 11       	cpse	r24, r1
  fc:	08 c0       	rjmp	.+16     	; 0x10e <__EEPROM_REGION_LENGTH__+0xe>
  fe:	8d e0       	ldi	r24, 0x0D	; 13
 100:	0e 94 72 00 	call	0xe4	; 0xe4 <uart_putchar>
 104:	8a e0       	ldi	r24, 0x0A	; 10
 106:	df 91       	pop	r29
 108:	cf 91       	pop	r28
 10a:	0c 94 72 00 	jmp	0xe4	; 0xe4 <uart_putchar>
 10e:	0e 94 72 00 	call	0xe4	; 0xe4 <uart_putchar>
 112:	f2 cf       	rjmp	.-28     	; 0xf8 <uart_putline+0x6>

00000114 <main>:
 114:	88 e0       	ldi	r24, 0x08	; 8
 116:	80 93 30 04 	sts	0x0430, r24	; 0x800430 <__TEXT_REGION_LENGTH__+0x7f4430>
 11a:	80 93 b6 04 	sts	0x04B6, r24	; 0x8004b6 <__TEXT_REGION_LENGTH__+0x7f44b6>
 11e:	88 ed       	ldi	r24, 0xD8	; 216
 120:	90 e0       	ldi	r25, 0x00	; 0
 122:	84 bf       	out	0x34, r24	; 52
 124:	90 93 61 00 	sts	0x0061, r25	; 0x800061 <__TEXT_REGION_LENGTH__+0x7f4061>
 128:	0e 94 5c 00 	call	0xb8	; 0xb8 <uart_init>
 12c:	80 91 a8 04 	lds	r24, 0x04A8	; 0x8004a8 <__TEXT_REGION_LENGTH__+0x7f44a8>
 130:	86 fd       	sbrc	r24, 6
 132:	fc cf       	rjmp	.-8      	; 0x12c <main+0x18>
 134:	0e 94 65 00 	call	0xca	; 0xca <uart_on>
 138:	8c e5       	ldi	r24, 0x5C	; 92
 13a:	91 e4       	ldi	r25, 0x41	; 65
 13c:	0e 94 79 00 	call	0xf2	; 0xf2 <uart_putline>
 140:	0e 94 6c 00 	call	0xd8	; 0xd8 <uart_off>
 144:	2f e7       	ldi	r18, 0x7F	; 127
 146:	8a e1       	ldi	r24, 0x1A	; 26
 148:	96 e0       	ldi	r25, 0x06	; 6
 14a:	21 50       	subi	r18, 0x01	; 1
 14c:	80 40       	sbci	r24, 0x00	; 0
 14e:	90 40       	sbci	r25, 0x00	; 0
 150:	e1 f7       	brne	.-8      	; 0x14a <main+0x36>
 152:	00 c0       	rjmp	.+0      	; 0x154 <main+0x40>
 154:	00 00       	nop
 156:	ea cf       	rjmp	.-44     	; 0x12c <main+0x18>

00000158 <_exit>:
 158:	f8 94       	cli

0000015a <__stop_program>:
 15a:	ff cf       	rjmp	.-2      	; 0x15a <__stop_program>

Disassembly of section .rodata:

0000415c <_end-0x7fe6a4>:
    415c:	68 69       	ori	r22, 0x98	; 152
	...

 

Last Edited: Thu. Nov 28, 2019 - 03:17 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

void putline(const char* p) gives the same (failed) response

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

Doesn't anyone around here own an ICE? It would reveal in seconds what is going on as you could step through the putline() and see what it's actually dereferencing off the pointer.

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

>void putline(const char* p) gives the same (failed) response

 

The 'const' really does nothing here, except prevent you from modifying the *p. In c++, you will get a warning when using a const to a non-const argument. In any case its the same address and has no bearing on the result.

 

Here is a little sample for a tiny817 xplained board, which I was using for another thread uart problem. I'm still not sure what is going on, but I sometimes have problems if I putc in a continuous loop, where garbage is the output (although seems to be a single piece of garbage). On the mega4809 where I had the same problem, I discovered I had forgot to set the tx pin high/idle when setting it to output. In that case, that seemed to solve the problem on the mega4809. I imagine in a tight loop, the pc side never gets a chance to sort out where the start bit is, or something like that.

 

The below code, if I only use the u0_putc in a loop, it will work. Or it will not. I'm confused, as I cannot get a handle on when/why it works. If the printf is involved, then it always seems to work. Maybe its just a matter of the pc side not being able to sort out the bits (in a continuous loop), and is made worse when the tx pin is initially low when set to an output.

 

I would set the tx pin high, then set it to output. The pullup does no good as when the output is enabled, the port will output the default low (and since is an output, is either outputting low or high, pullup doing nothing).

 

You can play around with tiny delays/nops/whatever in between the dre status check and putting data in txdatal, and other things. I don't think code is your problem.

 

//attiny817 xplained mini
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 3333333ul
#include <util/delay.h>

 

FILE u0_FILE;
static const char myString[] = "My String\r\n";

 

int u0_putc(char c, FILE* f){
    while( 0 == (USART0.STATUS & USART_DREIF_bm) );
    USART0.TXDATAL = c;
    return 0;
}
void u0_puts(const char* str){
    for( ; *str; u0_putc(*str++, 0) );
}
//usart0 tx only
void u0_initTX(const uint32_t bps){
    u0_FILE.put = u0_putc;
    u0_FILE.flags = __SWR;
    stdout = &u0_FILE;

    PORTB.OUTSET = PIN2_bm; //PB2 tx high
    PORTB.DIRSET = PIN2_bm; //PB2 tx output
    USART0.BAUD = F_CPU*4/bps;
    USART0.CTRLB = USART_TXEN_bm; //tx on
}
int main(void) {
    u0_initTX(9600);

    for( ; ;_delay_ms(1000) ){
        for( uint8_t i = '0'; i <= '9'; i++ ) u0_putc(i, 0);
        char buf[] = "ATtiny817 Xplained Mini\r\n";
        printf(buf);
        printf("a normal string\r\n");
        char buf2[] = "buf again: %s";
        printf(buf2, buf);
        printf(myString);
        u0_puts("OK, wait 1 second...\r\n");
    }
}

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

I added DIRSET before the OUTSET for tx pin.  Also sprinkled in _delay_ms(1) after putchar in the loop and in putchar between reading uart status and writing to TXDATA.  No luck.

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

>Also sprinkled in _delay_ms(1)

 

That is not enough for 9600 baud. Try 2ms.

 

I can reproduce a problem with using this line-

for( uint8_t i = '0'; ; i = i < '9' ? i+1 : '0'  ) u0_putc(i, 0);

and this does not help-

for( uint8_t i = '0'; ; i = i < '9' ? i+1 : '0',  _delay_ms(1) ) u0_putc(i, 0);

but this does-

for( uint8_t i = '0'; ; i = i < '9' ? i+1 : '0',     _delay_ms(2) ) u0_putc(i, 0);

 

I hooked up my dslogic so see what is happening- the chars coming out are correct, but the decoder can easily be tricked (sometimes ok, mostly not). Since this is a continuous stream of bits it just depends on when the other end thinks it sees a start bit, I guess.

 

So I think when testing with these continuous streams of chars/bits, I suppose its just confusing the other end (either the usb-cdc device or the pc). The strange results are probably just a matter of luck as to what is used as the start bit on the other end of tx.

 

Continuous streams of chars are not a normal thing, but maybe there is a method to get in sync somehow. the other end can start its rx at any time when the tx stream is already started, so maybe the only solution is to insert some occasional delays to make sure start bit sync is ok.

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

I tried _delay_ms(2) and _delay_ms(4) -- didn't work.

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

PB2 tx?

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

ezharkov wrote:

PB2 tx?

 

PB0 according to the curiosity nano datasheet (= CDC RX).

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

Never mind. I saw "PORTB.DIRSET = PIN2_bm". I thought it was your code. But now I see that it is curtvm's and for a tiny.

 

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

>I added DIRSET before the OUTSET for tx pin.

 

The outset goes before the dirset, although we are talking a low of one clock period and any rx should not be detecting this as a start bit, but may as well set it before changing to an output.

 

I also tried my previous tiny817 example code on a mega4809 (usart1, alt pin pc4). That worked ok in the continuous for loop putc, but then started to see garbage when I commented out the setting of the tx pin high (before setting it to output). The 4809 is not using the edbg usb-cdc in my case, so that is something different added to the equation. In either case, the rest of the code works ok and the only problems I see are when a continuous stream of bytes go out and there is no opportunity for the other end to determine what is a start bit.

 

I tested your code in #5 as-is, except the change to use usart1 on alt pin pc4. It works- both the putline and the putchar. But then, I'm not using the builtin usb-cdc either. Since you wait for a switch press before setting the usart pins, you do need the pullup, or simply set the pins first and skip the pullup.

 

 

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

I mistyped: the OUTSET preceeds the DIRSET.   Thanks for checking further.  I am soon to start hosting big dinner her.  I will play with it later.  

Maybe the baud rate.  And I need to go read the data sheet.  There are rules in there about changing i/o ports, IIRC.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could this be related to the linker script issues discussed in other threads?

 

For instance:

 

Disassembly of section .rodata:

000040da <.rodata>:
    40da:	61 62       	ori	r22, 0x21	; 33
    40dc:	63 00       	.word	0x0063	; ????

 

there's your "abc", just where we all think it should be.    But your problems could be explained because .rodata isn't being merged into the flash at link time, or because you need to explicitly handle .rodata in your objcopy when creating your .hex file.  (Check to see what's actually in the .hex file...)

 

Edit: Atmel Studio DOES put the string in the .hex file, but it uses objcopy like:

        avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "strcheck-rodata.elf" "strcheck-rodata.hex"

ie - it specifically omits sections that it doesn't want in the .hex file.  By comparison, I've seen stand-along makefiles that use "-j sectionName" to only INLCUDE specific sections.  If you have that, you probably won't get the readonly data copied into the .hex file.

 

Last Edited: Fri. Nov 29, 2019 - 03:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw,

 

I think you caught something there.   I need to update my objcopy rule.  I'm using:

 

/opt/local/bin/avr-objcopy -j .text -j .data -O ihex main.elf main.hex

I'm guessing it needs arguments for the rodata arguments.  I picked up that form a while ago from potentially outdated source.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
/opt/local/bin/avr-objcopy -j .text -j .data -O ihex main.elf main.hex

That is a problem.

 

MPLABX does not add any options other than -O ihex, so I doubt you would need anything special, unless your programming software has a cow seeing some of the other sections that are in specific memory regions like eeprom, fuses, etc.

 

 

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

It works with

/opt/local/bin/avr-objcopy -O ihex main.elf main.hex

According ot the documentation for "objcopy" the "-R" arguments are used to specify sections to remove.   I will do some experiments to see if other sections end up in the .hex file.

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

MattRW wrote:
It works with
Fine until you add any EEMEM (.eeprom), .fuse or .lock to the ELF that you are building. After that if you don't cherry pick with -j's (+) or -R's (-) then your .hex can end up with additional data you don't want.

 

Most folks choose -R to say "don't want these (.eeprom, .fuse, .lock) but give me everything else". That way when you add .mydatasection it automatically gets included. With -j's you'd have to remember to add "-j .mydatasection" if you later added such a section.

 

The danger of -R is that if some other default section is later added to the build (something like .user_row perhaps?) that if you forget to add the-R it will get assimilated into the .hex

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

Right.   So probably want a script that dumps out a list of sections along with the hex file.

MPLABx is an option, but I just hate navigating through multi-level menus to get work done.

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

MattRW wrote:
MPLABx is an option, but I just hate navigating through multi-level menus to get work done.
Working Outside of MPLAB® X IDE - Developer Help

 

"Dare to be naïve." - Buckminster Fuller

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

Just for grins I added eeprom and lock sections into the file.   These are shown via "avr-objdump" command:

e$ avr-objdump -h maindemo.elf

maindemo.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000000  00802800  0000017b  0000024f  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  1 .text         00000178  00000000  00000000  000000d4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .rodata       00000003  00004178  00000178  0000024c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .eeprom       00000002  00810000  00810000  0000024f  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  4 .lock         00000002  00830000  00830000  00000251  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  5 .stab         00000078  00000000  00000000  00000254  2**2
                  CONTENTS, READONLY, DEBUGGING
  6 .stabstr      00000058  00000000  00000000  000002cc  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .comment      00000011  00000000  00000000  00000324  2**0
                  CONTENTS, READONLY
  8 .note.gnu.avr.deviceinfo 00000040  00000000  00000000  00000338  2**2
                  CONTENTS, READONLY
  9 .debug_info   0000248a  00000000  00000000  00000378  2**0
                  CONTENTS, READONLY, DEBUGGING
 10 .debug_abbrev 00002296  00000000  00000000  00002802  2**0
                  CONTENTS, READONLY, DEBUGGING
 11 .debug_line   00000187  00000000  00000000  00004a98  2**0
                  CONTENTS, READONLY, DEBUGGING
 12 .debug_str    00000f85  00000000  00000000  00004c1f  2**0
                  CONTENTS, READONLY, DEBUGGING

And the hex file, with my added comments, follows.  The eeprom and lock sections appear at 0x0081000 and 0x008300, respectively.   If I use "avr-objcopy -O ihex -R .lock -R .eeprom ..." the lock and eeprom sections don't appear in the hex file.

$ cat maindemo.hex
:100000000C9450000C945A000C945A000C945A0012
:100010000C945A000C945A000C945A000C945A00F8
:100020000C945A000C945A000C945A000C945A00E8
:100030000C945A000C945A000C945A000C945A00D8
:100040000C945A000C945A000C945A000C945A00C8
:100050000C945A000C945A000C945A000C945A00B8
:100060000C945A000C945A000C945A000C945A00A8
:100070000C945A000C945A000C945A000C945A0098
:100080000C945A000C945A000C945A000C945A0088
:100090000C945A000C945A000C945A000C945A0078
:1000A00011241FBECFEFCDBFDFE3DEBF0E9498005B
:1000B0000C94BA000C940000E0E6F8E08DE890E2C1
:1000C000808791878BE08783089580E4809366081A
:1000D000E0E2F4E081E0858381830895E0E6F8E0E2
:1000E00086818F7B868308959091640895FFFCCF6D
:1000F000EFE1FEE43197F1F700C000008093620861
:100100000895CF93DF93EC018991811108C08DE0B0
:100110000E9474008AE0DF91CF910C9474000E94D9
:1001200074008FE19EE40197F1F700C00000ECCF6E
:1001300088E0809330048093B60488ED90E084BF1B
:10014000909361000E945C008091A80486FDFCCF22
:100150000E94650088E791E40E9481000E946E0081
:100160002FE78AE196E0215080409040E1F700C0FF
:080170000000EACFF894FFCF74
:03017800686900B3
:02000004008179        <= extended address (record type 04) at 0x0081____
:040000003412CDAB3E    <= added eeprom values
:02000004008377        <= extended address (record type 04) at 0x0083____
:04000000EFBEADDEC4    <= added lock values
:00000001FF