Q: Atmel Studio: Compiler error when adding external SRAM I have board wired up to use ATMega1281's Eternal Memory Interface with a BSI, BS62LV4006STIP55, 512Kx8 SDRAM connected. I am trying to do something similar to this (ATMega128), except my memory is larger and uses ATMega1281:
https://scienceprog.com/adding-external-memory-to-atmega128/
The blog instructs to add a line to the linker option:
-Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x8030ff

I've adapted this to my board with ATMega1281's slightly larger internal SRAM. In the beginning I am happy only to get the external SRAM to work using 8192 bytes. External SRAM should start at 0x2200 and end at 0x41FF:
-Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x8041ff


The linker part of the makefile (I opted to copy the auto-generated make file and modify it) now looks like this:
$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP) $(LINKER_SCRIPT_DEP)
    @echo Building target: $@
    @echo Invoking: AVR/GNU Linker : 5.4.0
    $(QUOTE)C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="XMEM_Mega1281.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega1281 -B "C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega1281" -Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x8041ff
    @echo Finished building target: $@
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "XMEM_Mega1281.elf" "XMEM_Mega1281.hex"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "XMEM_Mega1281.elf" "XMEM_Mega1281.eep" || exit 0
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "XMEM_Mega1281.elf" > "XMEM_Mega1281.lss"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "XMEM_Mega1281.elf" "XMEM_Mega1281.srec"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "XMEM_Mega1281.elf"

When compiling using the added linker options I get:
Severity    Code    Description Project File    Line
Error       address 0x802214 of XMEM_Mega1281.elf section `.data' is not within region `data'   XMEM_Mega1281       1
Error       address 0x80221e of XMEM_Mega1281.elf section `.bss' is not within region `data'    XMEM_Mega1281       1
Error       address 0x802214 of XMEM_Mega1281.elf section `.data' is not within region `data'   XMEM_Mega1281       1
Error       address 0x80221e of XMEM_Mega1281.elf section `.bss' is not within region `data'    XMEM_Mega1281       1

Can anyone tell me how to go about to achieve what I want to do, i. e. getting the compiler to take the external SRAM into use? At this point it doesn't matter how much it uses, only that it uses some. I must admit that I have practically no experience modifying memory maps etc.
To my understanding, avr-libs doesn't have a linker. Here's my makefile:
################################################################################
# Automatically-generated file. Do not edit!
################################################################################

SHELL := cmd.exe
RM := rm -rf

USER_OBJS :=

LIBS := 
PROJ := 

O_SRCS := 
C_SRCS := 
S_SRCS := 
S_UPPER_SRCS := 
OBJ_SRCS := 
ASM_SRCS := 
PREPROCESSING_SRCS := 
OBJS := 
OBJS_AS_ARGS := 
C_DEPS := 
C_DEPS_AS_ARGS := 
EXECUTABLES := 
OUTPUT_FILE_PATH :=
OUTPUT_FILE_PATH_AS_ARGS :=
AVR_APP_PATH :=$$$AVR_APP_PATH$$$
QUOTE := "
ADDITIONAL_DEPENDENCIES:=
OUTPUT_FILE_DEP:=
LIB_DEP:=
LINKER_SCRIPT_DEP:=

# Every subdirectory with source files must be described here
SUBDIRS := 


# Add inputs and outputs from these tool invocations to the build variables 
C_SRCS +=  \
../led.c \
../XMEM_Mega1281.c \
../uart.c


PREPROCESSING_SRCS += 


ASM_SRCS += 


OBJS +=  \
led.o \
XMEM_Mega1281.o \
uart.o

OBJS_AS_ARGS +=  \
led.o \
XMEM_Mega1281.o \
uart.o

C_DEPS +=  \
led.d \
XMEM_Mega1281.d \
uart.d

C_DEPS_AS_ARGS +=  \
led.d \
XMEM_Mega1281.d \
uart.d

OUTPUT_FILE_PATH +=XMEM_Mega1281.elf

OUTPUT_FILE_PATH_AS_ARGS +=XMEM_Mega1281.elf

ADDITIONAL_DEPENDENCIES:=

OUTPUT_FILE_DEP:= ./makedep.mk

LIB_DEP+= 

LINKER_SCRIPT_DEP+= 


# AVR32/GNU C Compiler
./led.o: .././led.c
    @echo Building file: $<
    @echo Invoking: AVR/GNU C Compiler : 5.4.0
    $(QUOTE)C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE)  -x c -funsigned-char -funsigned-bitfields -DDEBUG  -I"C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include"  -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega1281 -B "C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega1281" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"   -o "$@" "$<" 
    @echo Finished building: $<
    

./XMEM_Mega1281.o: .././XMEM_Mega1281.c
    @echo Building file: $<
    @echo Invoking: AVR/GNU C Compiler : 5.4.0
    $(QUOTE)C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE)  -x c -funsigned-char -funsigned-bitfields -DDEBUG  -I"C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include"  -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega1281 -B "C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega1281" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"   -o "$@" "$<" 
    @echo Finished building: $<
    

./uart.o: .././uart.c
    @echo Building file: $<
    @echo Invoking: AVR/GNU C Compiler : 5.4.0
    $(QUOTE)C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE)  -x c -funsigned-char -funsigned-bitfields -DDEBUG  -I"C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\include"  -Og -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega1281 -B "C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega1281" -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -MT"$(@:%.o=%.o)"   -o "$@" "$<" 
    @echo Finished building: $<
    




# AVR32/GNU Preprocessing Assembler



# AVR32/GNU Assembler




ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif

# Add inputs and outputs from these tool invocations to the build variables 

# All Target
all: $(OUTPUT_FILE_PATH) $(ADDITIONAL_DEPENDENCIES)

$(OUTPUT_FILE_PATH): $(OBJS) $(USER_OBJS) $(OUTPUT_FILE_DEP) $(LIB_DEP) $(LINKER_SCRIPT_DEP)
    @echo Building target: $@
    @echo Invoking: AVR/GNU Linker : 5.4.0
    $(QUOTE)C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-gcc.exe$(QUOTE) -o$(OUTPUT_FILE_PATH_AS_ARGS) $(OBJS_AS_ARGS) $(USER_OBJS) $(LIBS) -Wl,-Map="XMEM_Mega1281.map" -Wl,--start-group -Wl,-lm  -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega1281 -B "C:\Program Files (x86)\Atmel Studio\7.0\Packs\atmel\ATmega_DFP\1.7.374\gcc\dev\atmega1281" -Wl,--section-start,.data=0x802200,--defsym=__heap_end=0x8041ff
    @echo Finished building target: $@
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "XMEM_Mega1281.elf" "XMEM_Mega1281.hex"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "XMEM_Mega1281.elf" "XMEM_Mega1281.eep" || exit 0
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "XMEM_Mega1281.elf" > "XMEM_Mega1281.lss"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "XMEM_Mega1281.elf" "XMEM_Mega1281.srec"
    "C:\Program Files (x86)\Atmel Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-size.exe" "XMEM_Mega1281.elf"
    
    





# Other Targets
clean:
    -$(RM) $(OBJS_AS_ARGS) $(EXECUTABLES)  
    -$(RM) $(C_DEPS_AS_ARGS)   
    rm -rf "XMEM_Mega1281.elf" "XMEM_Mega1281.a" "XMEM_Mega1281.hex" "XMEM_Mega1281.lss" "XMEM_Mega1281.eep" "XMEM_Mega1281.map" "XMEM_Mega1281.srec" "XMEM_Mega1281.usersignatures"

Linker script and memory map
Address of section .data set to 0x800200
LOAD C:/Program Files (x86)/Atmel Studio/7.0/Packs/atmel/ATmega_DFP/1.7.374/gcc/dev/atmega1281/avr51/crtatmega1281.o
LOAD led.o
LOAD XMEM_Mega1281.o
LOAD uart.o
START GROUP
LOAD c:/program files (x86)/atmel studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr51\libm.a
END GROUP
Address of section .data set to 0x802200
                0x008041ff                __heap_end = 0x8041ff
START GROUP
LOAD c:/program files (x86)/atmel studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/avr51\libgcc.a
LOAD c:/program files (x86)/atmel studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr51\libm.a
LOAD c:/program files (x86)/atmel studio/7.0/toolchain/avr8/avr8-gnu-toolchain/bin/../lib/gcc/avr/5.4.0/../../../../avr/lib/avr51\libc.a
LOAD C:/Program Files (x86)/Atmel Studio/7.0/Packs/atmel/ATmega_DFP/1.7.374/gcc/dev/atmega1281/avr51\libatmega1281.a
END GROUP
                0x00000000                __TEXT_REGION_ORIGIN__ = DEFINED (__TEXT_REGION_ORIGIN__)?__TEXT_REGION_ORIGIN__:0x0
                [0x00800200]                __DATA_REGION_ORIGIN__ = DEFINED (__DATA_REGION_ORIGIN__)?__DATA_REGION_ORIGIN__:0x800100
                [0x00020000]                __TEXT_REGION_LENGTH__ = DEFINED (__TEXT_REGION_LENGTH__)?__TEXT_REGION_LENGTH__:0x20000
                [0x00002000]                __DATA_REGION_LENGTH__ = DEFINED (__DATA_REGION_LENGTH__)?__DATA_REGION_LENGTH__:0xff00
                [0x00001000]                __EEPROM_REGION_LENGTH__ = DEFINED (__EEPROM_REGION_LENGTH__)?__EEPROM_REGION_LENGTH__:0x10000
                [0x00000003]                __FUSE_REGION_LENGTH__ = DEFINED (__FUSE_REGION_LENGTH__)?__FUSE_REGION_LENGTH__:0x400
                0x00000400                __LOCK_REGION_LENGTH__ = DEFINED (__LOCK_REGION_LENGTH__)?__LOCK_REGION_LENGTH__:0x400
                0x00000400                __SIGNATURE_REGION_LENGTH__ = DEFINED (__SIGNATURE_REGION_LENGTH__)?__SIGNATURE_REGION_LENGTH__:0x400
                0x00000400                __USER_SIGNATURE_REGION_LENGTH__ = DEFINED (__USER_SIGNATURE_REGION_LENGTH__)?__USER_SIGNATURE_REGION_LENGTH__:0x400

This caused similar compiler errors:
-Wl,-Tdata,0x802200

I tried following, defining only the heap to reside in external SRAM (adapted from the link above):
-Wl,--defsym=__heap_start=0x802200,--defsym=__heap_end=0x8041ff

SUCCESS! That took the compiler errors away. Since it is writing and reading back the memory contents, the external SRAM now appears to work:
   mem = malloc(BUFFER_SIZE);
   PRINTF("Allocating 256 bytes space in ext ram\n");
   PRINTF("%d Byte buffer (starting at 0x%04X) filled with incrementing numbers:\n",BUFFER_SIZE,mem);
   // Fill memory incrementing values
   for(index = 0; index < BUFFER_SIZE; index++)
   {
       mem[index] = data++;
   }
   // Display memory block
   for(index = 0; index < BUFFER_SIZE; index++)
   {
      PRINTF("%02X ",mem[index]);
      if((index&0x0F) == 0x0F)
      {
         PRINTF("\n");
      }
   }



A: The error message that you are seeing indicates that the linker is unable to allocate the specified amount of memory for the .data section of your program. This is likely happening because the --section-start option that you are using is specifying a memory address range that is not available on the ATMega1281 microcontroller.
To fix this issue, you will need to specify a valid memory address range for the .data section of your program. The ATMega1281 microcontroller has a total of 8192 bytes of internal SRAM, with the first 64 bytes reserved for the stack, so you will need to specify a memory address range that is within this range and does not overlap with the stack.
For example, you could try specifying a memory address range of 0x0100 to 0x3FFF for the .data section, which would give you 8128 bytes of SRAM for your program to use. The updated linker options would look like this:
-Wl,--section-start,.data=0x0100,--defsym=__heap_end=0x3FFF
You may also need to adjust the __heap_end symbol to ensure that it does not overlap with the stack or any other memory areas that your program is using. You can use the avr-size tool to check the memory usage of your program and determine the appropriate value for this symbol.
Overall, it is important to ensure that you are specifying a valid memory address range for the .data section of your program when using the --section-start option in the linker options. This will ensure that the linker is able to properly allocate the necessary memory for your program, and avoid the kind of error that you are seeing.
