Linker errors on accessing global variables (ATtiny404)

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

Hi,

I'm doing a project using the new ATtiny404. I'm using a PICkit4 (long-time PIC user here) and MPLABX v5.10 with the AVR-GCC toolchain v5.4.0 for my development - I'm on a mac, so Atmel Studio is a no-go. I'm new to AVRs, and have spent a LOT of time on the forums/datasheets the past few days, but I'm still pretty shaky on some of the concepts, especially to do with gcc, linkers etc. - apologies in advance.

I'm using Timer A (TCA0) periodic overflow interrupt to change the output on PORTA. The byte to be written to the PORT will be stored in 2 char variables, d1 and d2. On each interrupt, one of these bytes is to be written to PORTA (alternating between the 2, for which a third variable is used, which keeps track of which of these bytes is currently in use, called dActive).

The timer interrupt is working correctly as expected. 

The problem - since d1, d2 and dActive need to be accessed by the ISR as well as from other functions, I'm trying to declare them globally as volatile uint8_ts. The variables get declared without a problem, however, any statement accessing them (either in main() or in the ISR) causes linker errors. 

#include <stdio.h>
#include <stdlib.h>
#define F_CPU 3333333
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "portio.h"

#define delay_ms(x) _delay_ms(x)
#define digitSel B,1
#define digitVal PORTA_OUT

volatile uint8_t dActive=0;
volatile uint8_t d1=0x19, d2=0xe6;
/*
 *
 */
FUSES = {
    .OSCCFG = FREQSEL_20MHZ_gc,
    .SYSCFG0 = CRCSRC_NOCRC_gc | RSTPINCFG_UPDI_gc,
    .SYSCFG1 = SUT_64MS_gc,
    .APPEND = 0x00, // Application data section disabled
    .BOOTEND = 0x00 // Boot section disabled
};

void init()
{
    TCA0.SINGLE.INTCTRL |= (1 << TCA_SINGLE_OVF_bp); /* Overflow Interrupt: enabled */
	TCA0.SINGLE.PER = 0xff; /* Period: 0xff */
	TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV64_gc   /* System Clock / 64 */
	                    | 1 << TCA_SINGLE_ENABLE_bp;
    sei();

}

ISR(TCA0_OVF_vect)
{
    if(dActive==1)   //lines starting here are the ones causing the issue.
        digitVal=d2;
    else
        digitVal=d1;
    if(++dActive==2)
        dActive=0;    //issue causing block ends here.
    output_toggle(digitSel);
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm;
}

int main() {
    init();
    PORTA.DIR=0xFE;
    Set_Output(digitSel);
    digitVal=0xe6;

    while(1)
    {
        _delay_ms(1000);

    }

    return (EXIT_SUCCESS);
}

The errors are: 

"/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/avr-gcc"   -mmcu=attiny404  -I "/Applications/microchip/mplabx/v5.10/packs/Atmel/ATtiny_DFP/1.3.238/include"  -B "/Applications/microchip/mplabx/v5.10/packs/Atmel/ATtiny_DFP/1.3.238/gcc/dev/attiny404"  -x c -c -D__ATtiny404__  -funsigned-char -funsigned-bitfields -O1 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -Wall -MD -MP -MF "build/default/production/main.o.d" -MT "build/default/production/main.o.d" -MT build/default/production/main.o  -o build/default/production/main.o main.c  -DXPRJ_default=default
"/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/avr-gcc"  -mmcu=attiny404  -B "/Applications/microchip/mplabx/v5.10/packs/Atmel/ATtiny_DFP/1.3.238/gcc/dev/attiny404"  -D__ATtiny404__  -Wl,-Map="dist/default/production/app1.X.production.map"    -o dist/default/production/app1.X.production.elf build/default/production/main.o      -DXPRJ_default=default    -Wl,--defsym=__MPLAB_BUILD=1 -Wl,--gc-sections -Wl,--start-group  -Wl,-lm -Wl,--end-group
/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld: address 0x803f02 of dist/default/production/app1.X.production.elf section `.data' is not within region `data'
/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld: address 0x803f03 of dist/default/production/app1.X.production.elf section `.bss' is not within region `data'
/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld: address 0x803f02 of dist/default/production/app1.X.production.elf section `.data' is not within region `data'
/Users/samay/Downloads/avr8-gnu-toolchain-darwin_x86_64/bin/../lib/gcc/avr/5.4.0/../../../../avr/bin/ld: address 0x803f03 of dist/default/production/app1.X.production.elf section `.bss' is not within region `data'
collect2: error: ld returned 1 exit status
make[2]: *** [dist/default/production/app1.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

The Makefile is the one generated by MPLAB, and the program compiles fine if the lines marked in the ISR function are removed.

 

What is it that i'm doing wrong here? Any help would be much appreciated.

Thanks!

-Sam

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

Welcome to AVRFreaks!  Please update your profile with a location, you may have other freaks near by that can lend a hand.

 

samay wrote:
#define F_CPU 3333333

 

From the datasheet: are capable of running at up to 20 MHz

 

Not that that is the source of your problem.

I don't see any glaring errors, but MPLAB is new to the AVR and attiny404 is also a new part, so there is plenty of room for bugs.

 

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

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

The obcopy invoked from the makefile is wrong. It does not have the right -j's or -R's

For the time being ditch the fuse stuff and do that manually

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

Thanks. I removed the FUSES part, but the linker errors remain the same.

Could you elaborate on what I need to do with the -j's and -R's?

-Sam

Last Edited: Thu. Dec 27, 2018 - 09:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah apologies, on my phone I misread it as 0x83???? but it's really 0x803??? so it's really just saying "too much RAM usage". I'm guessing you might have a load of const data that should be in __flash

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

I have no const data at all - all of my code except the port IO macros are put up on my first post. Removing any lines to do with the global variables allows the program to compile fine.

Some further experiment results - the program compiles if I use the xc8 compiler instead of GCC. I would like to get to the bottom of this, however (and I would not like to use xc8). The map files also seem to  differ a little.

With XC8, the map file contains: 

Memory Configuration

Name             Origin             Length             Attributes
text             0x0000000000000000 0x0000000000001000 xr
data             0x0000000000803f00 0x0000000000000100 rw !x
eeprom           0x0000000000810000 0x0000000000000080 rw !x
fuse             0x0000000000820000 0x0000000000000009 rw !x
lock             0x0000000000830000 0x0000000000000400 rw !x
signature        0x0000000000840000 0x0000000000000400 rw !x
user_signatures  0x0000000000850000 0x0000000000000400 rw !x
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

Address of section .data set to 0x803f00
                0x0000000000008000                __RODATA_PM_OFFSET__ = 0x8000

With GCC, the map file has this: 


Memory Configuration

Name             Origin             Length             Attributes
text             0x0000000000000000 0x0000000000001000 xr
data             0x0000000000802000 0x0000000000000100 rw !x
eeprom           0x0000000000810000 0x0000000000000080 rw !x
fuse             0x0000000000820000 0x0000000000000009 rw !x
lock             0x0000000000830000 0x0000000000000400 rw !x
signature        0x0000000000840000 0x0000000000000400 rw !x
user_signatures  0x0000000000850000 0x0000000000000400 rw !x
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

Address of section .data set to 0x803f00
                0x0000000000008000                __RODATA_PM_OFFSET__ = 0x8000

Which does mention a wrong data section origin (as per the datasheet SRAM starts at 0x3f00). However, I'm not sure if this makes any difference.

Any ideas? 

Thanks.

-Sam

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

I know this isn't your question, but you could simplify your

program by initializing PORTA to d2 and then toggling every

bit of PORTA in the interrupt.  Since d1 is just ~d2.

 

--Mike

 

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

Mike,

yes, that is something like what i'll do eventually (d1 and d2 will come from a lookup table). I'm just trying to get the damn thing to compile with the simplest code for now.

-Sam

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

I checked the Microchip site and the 404 only has 256 bytes of RAM. Admittedly I didn't download the datasheet to find out if there's some kind of offset to the mapping but the 0x803F02 and 0x803F03 errors in #1, once the 0x800000 Harvard offset is removed still suggest 3F02 in the RAM region which is almost 4K so sounds very wrong for a 256 byte chip. What does the map file show as being at (80)3F02?

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

The RAM starting address is at 3F00 as per the datasheet, so 0x803f00 seems to be correct. If I compile the program with the global variables declared but not accessed anywhere, the variables d2, d1 and dActive seem to be at 0x803f01-03.


.data           0x0000000000803f00        0x2 load address 0x0000000000000100
                0x0000000000803f00                PROVIDE (__data_start, .)
 *(.data)
 *(.data*)
 .data.d2       0x0000000000803f00        0x1 build/default/production/main.o
                0x0000000000803f00                d2
 .data.d1       0x0000000000803f01        0x1 build/default/production/main.o
                0x0000000000803f01                d1
 *(.gnu.linkonce.d*)
                0x0000000000803f02                . = ALIGN (0x2)
                0x0000000000803f02                _edata = .
                0x0000000000803f02                PROVIDE (__data_end, .)

.bss            0x0000000000803f02        0x1
                0x0000000000803f02                PROVIDE (__bss_start, .)
 *(.bss)
 *(.bss*)
 .bss.dActive   0x0000000000803f02        0x1 build/default/production/main.o
                0x0000000000803f02                dActive
 *(COMMON)
                0x0000000000803f03                PROVIDE (__bss_end, .)
                0x0000000000000100                __data_load_start = LOADADDR (.data)
                0x0000000000000102                __data_load_end = (__data_load_start + SIZEOF (.data))

Thanks.

-Sam

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

Update: Heard back from microchip support on this. It seems to be an issue with the .o and .a DFP files supplied with their GCC in the mplabx attiny_DFP's /gcc/dev/attiny404/avrxmega3/short-calls folder, which they are investigating. For the time being, copying over those 2 files from the corresponding device's short-calls folder in the xc8 installation to the GCC one seems to work and the program compiles. 

 

-Sam

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

Thanks Sam for posting your solution. I just hit the same issue, and you really helped me out. 

 

Edit: I spoke too soon. I seem to have the exact same issue with a ATtiny404, but copying the files crtattiny404.o and libattiny404.a does not seem to make any difference. 

Last Edited: Tue. Mar 12, 2019 - 12:01 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think you are correct that the 0x802000 value for the data region is the problem. The data section is put at 0x803f00, but not the region. 

 

I added `-Wl,--verbose` to the ld command line arguments, and found that it was using this linker script in the gcc toolchain distribution from microchip: `avr8-gnu-toolchain-darwin_x86_64/avr/bin/../lib/ldscripts/avrxmega3.xn`

 

Sure enough, it is setting the wrong RAM region. Copying that linker script and changing the address appears to work-around the issue. 

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

Hi guys.

 

Today, 05.fev.2020 we start a project with Attiny1604 and got the same issue mentioned by Samay (thanks, you help me so much...). PS: Using Atmel Studio 7 with Native Toolchain.

 

Got the following error when I declare a global variable: address 0x803c01 of Project.elf section `.bss' is not within region `data'

 

The error occurs because the memory map file of my DFP pack was wrong. So, after some hours of meditation and this post, I solve using an older version of the DFP.

 

Just report, if someone has the same problem change DFP version: Project > Properties > Packs > Change Version

 

With packs 1.4 or newer the memory mapping is wrong. Currently, I using DFP version 1.3.169 and works fine.

 

A detail, DFP 1.4.131 was released 28.jan.2020, just one week ago. Probably I am the first freak to use this package and suffer from this issue.

 

I will report Microchip soon.

 

Regards

 

Diego Padilha

Electrical Engineer
Brazil

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

D_Padilha wrote:
I will report Microchip soon.

 

They know: https://www.avrfreaks.net/commen...

 

That whole thread contains very important info on this issue.

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

I think not...

 

The last post is from 06.dec.2019, the pack with the issue was released on 28.jan.2020... Or the trainee used the wrong commit surprise

 

 

Attachment(s): 

Diego Padilha

Electrical Engineer
Brazil

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

Looks like they messed up, then. I have ATtiny_DFP 1.4.283 and it seems to be working fine.

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

ATtiny_DFP 1.4.283 doesn´t work with me. I using ATtiny1604.

Attachment(s): 

Diego Padilha

Electrical Engineer
Brazil

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

Yeah, my toolchain is 3.6.2.1778 because I recently installed AS7 in my new laptop.

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

D_Padilha wrote:
ATtiny_DFP 1.4.283 doesn´t work with me. I using ATtiny1604.
As implied - it's not just the pack that needs to be right - it's the whole toolchain. So if latest pack does not work for you then the chances are your toolchain is out of date.

 

(this is the penalty for using "new silicon" - the tools are still "bedding in")

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

kabasan wrote:

It may be the same cause as this thread.

https://www.avrfreaks.net/forum/cannot-compile-atmega808-global-variables

 

 

Yeah, probably... I will post my solution there.

Diego Padilha

Electrical Engineer
Brazil

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

Another workaround for this is force feeding the linker with the address of SRAM. For the tiny1604 this is 0x3C00, so you can add this to the linker options:

-Tdata=0x803C00

 

edit: actually this doesn't work, I was too hasty. But 0x802000 may work because the SRAM is aliased. Not recommended as it's undocumented behaviour.

Last Edited: Wed. Feb 5, 2020 - 03:27 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Indeed, -Tdata=0x803c00 still gives the linker error.

If you do -Tdata=0x802000 then it will compile but you've now convinced gcc the ram is at 0x2000 so the code won't actually work. 

I found a quick fix by editing the "data" line of .../lib/ldscripts/avrxmega3.xn near the start:

MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
  data   (rw!x) : ORIGIN = 0x803f00, LENGTH = __DATA_REGION_LENGTH__
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = __EEPROM_REGION_LENGTH__
  fuse      (rw!x) : ORIGIN = 0x820000, LENGTH = __FUSE_REGION_LENGTH__
  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = __LOCK_REGION_LENGTH__
  signature (rw!x) : ORIGIN = 0x840000, LENGTH = __SIGNATURE_REGION_LENGTH__
  user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = __USER_SIGNATURE_REGION_LENGTH__
}

(This was for the attiny404. You need to change the 803f00 to whatever is appropriate.)

I must admit to being a bit confused as to why this works since I though -Txxx was supposed to override this.

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

psa2 wrote:
you've now convinced gcc the ram is at 0x2000 so the code won't actually work.

 

So it seems, but did you actually try it, though, or just dismissing out of hand? Because some tinyAVR-1 have their SRAM memory aliased at various addresses, not just the one stated in the datasheet. Maybe the tiny404 doesn't.

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

I must admit I just looked at the assembler output of gcc. I didn't program it into the tiny404 in case it blew the house up.

Anyway, there's a better solution from MattRW on this thread.

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

I know, it's the best solution. I just wanted to share my discovery of the aliased SRAM :) don't worry, the tiny404 wouldn't have exploded, probably it would just work normally.

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

D_Padilha wrote:

Hi guys.

..

Just report, if someone has the same problem change DFP version: Project > Properties > Packs > Change Version

 

With packs 1.4 or newer the memory mapping is wrong. Currently, I using DFP version 1.3.169 and works fine.

 

A detail, DFP 1.4.131 was released 28.jan.2020, just one week ago. Probably I am the first freak to use this package and suffer from this issue.

 

I will report Microchip soon.

 

Regards

 

 

In my case, changing device from Attiny416 to Attiny816 automatically changed the pack version from 1.3.172 to 1.4.301 and this created the .bss problem.

After wasting 4 hours and finding this thread, I reverted to 1.3.172 and I can compile now (AS7 V7.0.122)

 

Thank you very much guys.

 

 

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

https://www.avrfreaks.net/commen...

 

If you simply correct the problem, you can be done with it and move on to using the latest 'packs'.

 

 

Here is what happens, forgive my overuse of crayons.

 

 

unmodified linker script- avrxmega3.xn
...
__TEXT_REGION_LENGTH__ = DEFINED(__TEXT_REGION_LENGTH__) ? __TEXT_REGION_LENGTH__ : 1024K;
__DATA_REGION_LENGTH__ = DEFINED(__DATA_REGION_LENGTH__) ? __DATA_REGION_LENGTH__ : 0xffa0;
...
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = __TEXT_REGION_LENGTH__
  data   (rw!x) : ORIGIN = 0x802000, LENGTH = __DATA_REGION_LENGTH__
  ...
}
...

 

DFP packs starting at some point add these symbols into crtattinyNNN.o (or crtatmegaNNN.o)-
00000000  w      *ABS*    00000000 __TEXT_REGION_ORIGIN__
00803f00  w      *ABS*    00000000 __DATA_REGION_ORIGIN__
...
00001000  w      *ABS*    00000000 __TEXT_REGION_LENGTH__
00000100  w      *ABS*    00000000 __DATA_REGION_LENGTH__
...

 

specs file moves .data section to start of ram (not data region)

 

results:

 

OLD pack in use (above symbols missing), with original linker script, for attiny404-

 

linker symbols (default values)-
__TEXT_REGION_LENGTH__ = 1024K
__DATA_REGION_LENGTH__ = 0xffa0

 

specs file provided option-> -Tdata 0x803F00

data region = 0x802000 - 0x811fbf
.data section = 0x803F00

 

.data section will never get to end of data region, 
no errors but also no warnings when using too much data

 

NEW pack in use (w/above symbols), with original linker script, for attiny404-

 

linker symbols overridden-
__TEXT_REGION_LENGTH__ = 0x1000
__DATA_REGION_LENGTH__ = 0x100

 

specs file provided option-> -Tdata 0x803F00

 

data region = 0x802000 - 0x802100
.data section = 0x803F00

 

the .data section is no longer in the data region, so you get an error if any data is used

 

NEW pack in use (w/above symbols), with MODIFED linker script, for attiny404-

 

script change (avrxmega3.xn)-
data   (rw!x) : ORIGIN = __DATA_REGION_ORIGIN__, LENGTH = __DATA_REGION_LENGTH__

 

linker symbols overridden-
__TEXT_REGION_LENGTH__ = 0x1000
__DATA_REGION_LENGTH__ = 0x100

new symbol required (from somewhere external, in this case crt.o)
__DATA_REGION_ORIGIN__ = 0x803F00

 

specs file provided option-> -Tdata 0x803F00 (no longer necessary)

data region = 0x803F00 - 0x803FFF
.data section = 0x803F00

 

the .data section is now in the data region, and you will also get an error if data exceeds size of data region

 

 

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

Hi there!

I used this forum for some time now without singup, always very useful, but never needed to write something...until now.

I faced the same problem with MPLAP X IDE v.5.35 and AVG-GCC toolchain v.5.4.0

Considering i'm not very pro with programming and that this project was the first with MPLAB IDE, i spent hours to figure out why this was happening...and this post saved me other hours of uselss work.

So, i signup only for say thanks to you all freaks :)

 

---
Ettore