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");
}
}