How to use progmem on 256kb

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

Hi

My first real post here, normally its enough just to browse the archive then the answers are there, but im facing a problem i haven't really found a nice solution on.
im having problems addressing the high program memory on an mega2560.
I read the nice guide from wek :http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=708225 , but in his example he used 1 dimensional arrays, and he concludes that its not possible to use " GET_FAR_ADDRESS " or " pgm_get_far_address "( in newer versions of pgmspace.h)

In his example:

uint16_t PROGMEM v[10] =
   {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
uint16_t a, i;
[...]
// a = pgm_read_word(&v[i]);
a = pgm_read_word_far(GET_FAR_ADDRESS(v[0]) + i * sizeof(v[0])); 

But that is not possible since a multidimensional array is not stored the same way.

the dirty way is the compile the code, and find out where the compiler places my arras, and then add the offset manually.

// definition of the arrey
const unsigned int Lys_tabel_data80[320][12]PROGMEM={......};


//my code where i want to read out the values
pwm_kanal_1=pgm_read_word_far(0x20000+(uint16_t)&(Lys_tabel_data80[min_point][0]));

pwm_kanal_2=pgm_read_word_far(0x20000+(uint16_t)&(Lys_tabel_data80[min_point][1]));

pwm_kanal_3=pgm_read_word_far(0x20000+(uint16_t)&(Lys_tabel_data80[min_point][2]));

pwm_kanal_4=pgm_read_word_far(0x20000+(uint16_t)&(Lys_tabel_data80[min_point][3]));

pwm_kanal_5=pgm_read_word_far(0x20000+(uint16_t)&(Lys_tabel_data80[min_point][4]));

Is there some way where i can " force " the compiler to place this variable @ 0x20000 or is this a good way to do it?
is there a good trick?

Im using AVR studio 5.1 with or without winavr2010 toolchain

Sivsko

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

You can use avr-gcc 4.7 and it's __memx address space:

const __memx unsigned int Lys_tabel_data80[320][12] = {...}; 

pwm_kanal_1 = Lys_tabel_data80[min_point][0];
pwm_kanal_2 = Lys_tabel_data80[min_point][1]; 
pwm_kanal_3 = Lys_tabel_data80[min_point][2]; 
pwm_kanal_4 = Lys_tabel_data80[min_point][3]; 
pwm_kanal_5 = Lys_tabel_data80[min_point][4];

avrfreaks does not support Opera. Profile inactive.

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

You might perhaps go back to that writeup of mine and read the "segments"-related part.

JW

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

Thanks for all the replays but i may need to mention that i have 20 of arrays, so the " segments " method have limitations.
Each array is 7680bytes big, so if only can use 16bit pointers i can only fit 8 pr 64kb Flash block, but the compiler will try to fill the flash completely out so i will have one array spread from one block to another.

SprinterSB wrote:
You can use avr-gcc 4.7 and it's __memx address space:
const __memx unsigned int Lys_tabel_data80[320][12] = {...}; 

pwm_kanal_1 = Lys_tabel_data80[min_point][0];
pwm_kanal_2 = Lys_tabel_data80[min_point][1]; 
pwm_kanal_3 = Lys_tabel_data80[min_point][2]; 
pwm_kanal_4 = Lys_tabel_data80[min_point][3]; 
pwm_kanal_5 = Lys_tabel_data80[min_point][4];

that function is not available if i run it, i get
"Error 1 expected '=', ',', ';', 'asm' or '__attribute__' before 'int' "

@Wek And im a bit unsure about attachment in your post http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=708225
The file i can see is a pthread_cond_destroy.c but its not made by Carlos???

I guess the quick and dirty way is to first the let compiler place the arrays then find out where the compiler have placed them, then add the offset.
If and array have bin placed over 2 block segments then i " add " a dummy array that fills the space out so that the real array ends up in one segment.
seems a bit iffy to do though.

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

S_i_v_s_k_o wrote:
SprinterSB wrote:
You can use avr-gcc 4.7 and it's __memx address space
The 24-bit address space was renamed on 2012-01-25 from __pgmx to __memx, so that in older snaphots of 4.7 you can simply
-D__memx=__pgmx

avrfreaks does not support Opera. Profile inactive.

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

If i use the __pgmx or __memx
i still get " internal error: out of range error " to my array file, and the program jumping around to random memory locations when its disasemblet.

im using the gcc 4,7 from http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/
and using that as my tool chain in avr studio 5.1

Any idear?

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

You have a small test case showing the problem? And post the i-file generated with -save-temps?

avrfreaks does not support Opera. Profile inactive.

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

@SprinterSB
i will make one later. need new toolchain see below.

I changed my storing of my arrays to:

const  unsigned int Lys_tabel_data950[320][12] __attribute__ ((section (".lys950")))

where i in avr studio have defined each segment in the flash to be starting at specific places.
then i came into a small thing in avr studio, when i want to place something at 0x20000 i write that in the linker memory setting, but the linker script that it shows it has bin placed in 0x40000 see png files attached. so it multiples everything with 2, and if you run the program you also see that it has bin placed in 0x40000 if you write 0x20000..?
So i divided all my flash segments with 2 to get it to be placed at the right place in my memory.

but when im reading from flash segment 3 ( 0x20000 to 0x2FFFF ) the compiler points me to segment 2 ( 0x10000 to 0x1FFFF ). however its doing it right when im reading from flash segment 4 ( 0x30000 to 0x3FFFF ).

If i disassembel the asm code i see that the compiler used R26 to move into RMPZ and that value is calulated wrong. i dont know if its a bug.

i read out values like this:

pwm_kanal_1=pgm_read_word_far( 0x30000 + (uint32_t)&(Lys_tabel_data80[min_point][0]));// right

pwm_kanal_1=pgm_read_word_far( 0x20000 + (uint32_t)&Lys_tabel_data660[min_point][0]);  // FFFF

i add the offset my self.

I have added my memory demo, where the bug can be seen. im running on a new installed computer with avr studio 5.1 only, have not installed other toolchains.

Attachment(s): 

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

S_i_v_s_k_o wrote:
but when im reading from flash segment 3 ( 0x20000 to 0x2FFFF )
Segment counting in 4.7 starts at 0 with __flash, so that 0x2**** is segment no. 2, i.e. __flash2.

Likewise, if you apply __builtin_avr_flash_segment() on such an address, you will get 2 as result.

avrfreaks does not support Opera. Profile inactive.

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

yes ok but we are talking about the same:
block 64kb 0x00000 to 0x0FFFF i call that 1 ( you call it 0)
block 64kb 0x10000 to 0x1FFFF i call that 2 ( you call it 1)
block 64kb 0x20000 to 0x2FFFF i call that 3 ( you call it 2)
block 64kb 0x30000 to 0x3FFFF i call that 4 ( you call it 3)

and im getting this error on the avr simulator also.
And no optimization.

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

SprinterSB wrote:
You have a small test case showing the problem? And post the i-file generated with -save-temps?

This program just jumps around and never enters main loop.
This i made in AVR studio 5.1 with the newest gcc toolchain 4.7 from http://sourceforge.net/projects/mobilechessboar/files/avr-gcc%20snapshots%20%28Win32%29/
no optimization.

Attachment(s): 

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

I don't get "internal error: out of range error". What tools throws the error? Looks like from the linker.

avrfreaks does not support Opera. Profile inactive.

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

And I fail to find the post where you say what options and linker skript you use.

Together with -g I see the following ICE: http://gcc.gnu.org/PR52472

You mean that?

avrfreaks does not support Opera. Profile inactive.

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

SprinterSB wrote:
And I fail to find the post where you say what options and linker skript you use.

I made a new one where the messages pops up.

Avr-gcc options in avr studio:
-funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -mmcu=($DEVICE)

avr linker options in avrstudio:
-Wl,-Map="$(OutputFileName).map" -Wl,-lm -save-temps -mmcu=($DEVICE) ($MEMORY_SETTINGS)

avr assambler options in avrstudio:
-Wa,-gdwarf2 -x assembler-with-cpp -c -mmcu=($DEVICE)

when compiled i get 26 warnings saying:
"Warning 1 internal error: out of range error c:\....\Debug\avr_memory_demo2.o 1 1 avr_memory_demo2 "

when i try to run the program in the simulator i never enters my " find_lys " function and the program jumps around randomly

Edit:
Did not see that you linked to a bug, but the message dont look the same, i have no idear if they are they the same.

Attachment(s): 

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

Sorry, that AS stuff is of no use on this side of the cable.

These are *not* avr-gcc options, it's some part of a script that will expand to the options eventually.

Just post the compiler output with -v

avrfreaks does not support Opera. Profile inactive.

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

this?

------ Build started: Project: avr_memory_demo2, Configuration: Debug AVR ------
Build started.
Project "avr_memory_demo2.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Compiler.targets" from project "M:\atmel projects\avr memory demo2\avr_memory_demo2\avr_memory_demo2.cproj" (target "Build" depends on it):
	Task "RunCompilerTask"
		C:\Program Files (x86)\Atmel\AVR Studio 5.1\make\make.exe all 
avr_memory_demo2.c
		Invoking: AVR/GNU C Compiler
		"C:\avr-gcc-4.7\bin\avr-gcc.exe"  -funsigned-char -funsigned-bitfields -O0 -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -v -MD -MP -MF "avr_memory_demo2.d" -MT"avr_memory_demo2.d"  -mmcu=atmega2560  -o"avr_memory_demo2.o" ".././avr_memory_demo2.c" 
		Using built-in specs.
		COLLECT_GCC=C:\avr-gcc-4.7\bin\avr-gcc.exe
		COLLECT_LTO_WRAPPER=c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/lto-wrapper.exe
		Target: avr
		Configured with: ../../gcc.gnu.org/trunk/configure --target=avr --prefix=/local/gnu/install/gcc-4.7-mingw32 --host=i386-mingw32 --build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared --disable-lto --disable-checking --disable-libquadmath --with-dwarf2
		Thread model: single
		gcc version 4.7.0 20120102 (experimental) (GCC) 
		COLLECT_GCC_OPTIONS='-funsigned-char' '-funsigned-bitfields' '-O0' '-fpack-struct' '-fshort-enums' '-g2' '-Wall' '-c' '-std=gnu99' '-v' '-MD' '-MP' '-MF' 'avr_memory_demo2.d' '-MT' 'avr_memory_demo2.d' '-mmcu=atmega2560' '-o' 'avr_memory_demo2.o'
		 c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/cc1.exe -quiet -v -imultilib avr6 -iprefix c:\avr-gcc-4.7\bin\../lib/gcc/avr/4.7.0/ -MD avr_memory_demo2.d -MF avr_memory_demo2.d -MP -MT avr_memory_demo2.d .././avr_memory_demo2.c -quiet -dumpbase avr_memory_demo2.c -mmcu=atmega2560 -auxbase-strip avr_memory_demo2.o -g2 -O0 -Wall -std=gnu99 -version -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -o C:\Users\sste\AppData\Local\Temp\ccEvOcm1.s
		GNU C (GCC) version 4.7.0 20120102 (experimental) (avr)
			compiled by GNU C version 3.4.5 (mingw-vista special r2), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.2
		GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
		ignoring nonexistent directory "c:\avr-gcc-4.7\bin\../lib/gcc/avr/4.7.0/../../../../avr/sys-include"
		ignoring duplicate directory "c:/avr-gcc-4.7/lib/gcc/../../lib/gcc/avr/4.7.0/include"
		ignoring duplicate directory "c:/avr-gcc-4.7/lib/gcc/../../lib/gcc/avr/4.7.0/include-fixed"
		ignoring nonexistent directory "c:/avr-gcc-4.7/lib/gcc/../../lib/gcc/avr/4.7.0/../../../../avr/sys-include"
		ignoring duplicate directory "c:/avr-gcc-4.7/lib/gcc/../../lib/gcc/avr/4.7.0/../../../../avr/include"
		#include "..." search starts here:
		#include <...> search starts here:
		 c:\avr-gcc-4.7\bin\../lib/gcc/avr/4.7.0/include
		 c:\avr-gcc-4.7\bin\../lib/gcc/avr/4.7.0/include-fixed
		 c:\avr-gcc-4.7\bin\../lib/gcc/avr/4.7.0/../../../../avr/include
		End of search list.
		GNU C (GCC) version 4.7.0 20120102 (experimental) (avr)
			compiled by GNU C version 3.4.5 (mingw-vista special r2), GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.2
		GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
		Compiler executable checksum: afdfce2a7797df9535e30568ba8f538f
		COLLECT_GCC_OPTIONS='-funsigned-char' '-funsigned-bitfields' '-O0' '-fpack-struct' '-fshort-enums' '-g2' '-Wall' '-c' '-std=gnu99' '-v' '-MD' '-MP' '-MF' 'avr_memory_demo2.d' '-MT' 'avr_memory_demo2.d' '-mmcu=atmega2560' '-o' 'avr_memory_demo2.o'
		 c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/bin/as.exe -mmcu=atmega2560 -o avr_memory_demo2.o C:\Users\sste\AppData\Local\Temp\ccEvOcm1.s
		COMPILER_PATH=c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/;c:/avr-gcc-4.7/bin/../libexec/gcc/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/bin/
		LIBRARY_PATH=c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/avr6/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/avr6/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/;c:/avr-gcc-4.7/bin/../lib/gcc/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/
		COLLECT_GCC_OPTIONS='-funsigned-char' '-funsigned-bitfields' '-O0' '-fpack-struct' '-fshort-enums' '-g2' '-Wall' '-c' '-std=gnu99' '-v' '-MD' '-MP' '-MF' 'avr_memory_demo2.d' '-MT' 'avr_memory_demo2.d' '-mmcu=atmega2560' '-o' 'avr_memory_demo2.o'
		Finished building: .././avr_memory_demo2.c
		Building target: avr_memory_demo2.elf
		Invoking: AVR/GNU C Linker
		"C:\avr-gcc-4.7\bin\avr-gcc.exe" -o avr_memory_demo2.elf  avr_memory_demo2.o   -Wl,-Map="avr_memory_demo2.map" -Wl,-lm  -save-temps -v  -mmcu=atmega2560  
		Using built-in specs.
		COLLECT_GCC=C:\avr-gcc-4.7\bin\avr-gcc.exe
		COLLECT_LTO_WRAPPER=c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/lto-wrapper.exe
		Target: avr
		Configured with: ../../gcc.gnu.org/trunk/configure --target=avr --prefix=/local/gnu/install/gcc-4.7-mingw32 --host=i386-mingw32 --build=i686-linux-gnu --enable-languages=c,c++ --disable-nls --disable-shared --disable-lto --disable-checking --disable-libquadmath --with-dwarf2
		Thread model: single
		gcc version 4.7.0 20120102 (experimental) (GCC) 
		COMPILER_PATH=c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/;c:/avr-gcc-4.7/bin/../libexec/gcc/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/bin/
		LIBRARY_PATH=c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/avr6/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/avr6/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/;c:/avr-gcc-4.7/bin/../lib/gcc/;c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/
		COLLECT_GCC_OPTIONS='-o' 'avr_memory_demo2.elf' '-save-temps' '-v' '-mmcu=atmega2560'
		 c:/avr-gcc-4.7/bin/../libexec/gcc/avr/4.7.0/collect2.exe -m avr6 -Tdata 0x800200 -o avr_memory_demo2.elf c:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/avr6/crtm2560.o -Lc:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/avr6 -Lc:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib/avr6 -Lc:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0 -Lc:/avr-gcc-4.7/bin/../lib/gcc -Lc:/avr-gcc-4.7/bin/../lib/gcc/avr/4.7.0/../../../../avr/lib avr_memory_demo2.o -Map=avr_memory_demo2.map -lm -lgcc -lc -lgcc
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
M:\atmel projects\avr memory demo2\avr_memory_demo2\Debug\avr_memory_demo2.o(1,1): internal error: out of range error
		Finished building target: avr_memory_demo2.elf
		"C:\avr-gcc-4.7\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature  "avr_memory_demo2.elf" "avr_memory_demo2.hex"
		"C:\avr-gcc-4.7\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "avr_memory_demo2.elf" "avr_memory_demo2.eep" || exit 0
		"C:\avr-gcc-4.7\bin\avr-objdump.exe" -h -S "avr_memory_demo2.elf" > "avr_memory_demo2.lss"
		"C:\avr-gcc-4.7\bin\avr-size.exe" -C --mcu=atmega2560  "avr_memory_demo2.elf"
		AVR Memory Usage
		----------------
		Device: atmega2560
		Program:  144098 bytes (55.0% Full)
		(.text + .data + .bootloader)
		Data:         24 bytes (0.3% Full)
		(.data + .bss + .noinit)
	Done executing task "RunCompilerTask".
Done building target "CoreBuild" in project "avr_memory_demo2.cproj".
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "C:\Program Files (x86)\Atmel\AVR Studio 5.1\Vs\Avr.common.targets" from project "M:\atmel projects\avr memory demo2\avr_memory_demo2\avr_memory_demo2.cproj" (entry point):
Done building target "Build" in project "avr_memory_demo2.cproj".
Done building project "avr_memory_demo2.cproj".

Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The problem is generate stubs by gs() in a jump offset table and these stubs are not located in the expected memory chunk, i.e. segment #0.

You can work around that by -fno-jump-tables but this is just a hack because there are situations where you cannot avoid stubs.

For now that's all I can say and otherwise I get lost in the big files...

Beside that, you should use own linker script to place all that data after the code, not before it.

avrfreaks does not support Opera. Profile inactive.

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

You should not locate the lengthy tables to .progmem, as that pushes vital segments such as .trampolines etc. beyond the usable area (64kB/64kW). As they are accessed through ELPM anyway, they should be deliberately positioned above all "conventional" segments, including .text. That was one of the key points in my writeup and the reason why I suggested changes in the default linker script.

JW

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

As a solution, you can use a custom linker script and place .trampolines before .progmem, not after.

You can also locate .trampolines at, say, 0x30000, and everything works smooth, bit you need so set EIND = 1 in the startup code then nbecause 0x30000 is in the second 64 KiW chunk of flash.

wek wrote:
I suggested changes in the default linker script.
Ah, what PR number is it?

avrfreaks does not support Opera. Profile inactive.

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

SprinterSB wrote:
wek wrote:
I suggested changes in the default linker script.
Ah, what PR number is it?
I have no idea what "PR number" is, although I've seen you using that a lot.

I've requested said changes in original post in https://savannah.nongnu.org/bugs/?26365 , and explained in the related discussion on the reflector that I don't know how to accomplish the changes (and I add that I don't want to accomplish them by now). I then posted an example modified linker script to that tracker item and explained the changes in the extensive post here I linked above.

JW

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

wek wrote:
I have no idea what "PR number" is, although I've seen you using that a lot.
PR is short for "problem report".

Bugs, feature requeste etc. in GCC, binutils and other GNU projects have a PR number. For example, GCC's PR52261 is XMEGA enhancement for avr-gcc.

To go to the respective bugzilla page, simply append PR52261 to gcc.gnu.org for GCC PRs, or append to sourceware.org for binutils PRs, e.g.

http://sourceware.org/PR13410

Quote:
I've requested said changes in original post in https://savannah.nongnu.org/bugs/?26365 [...] I then posted an example modified linker script to that tracker item and explained the changes in the extensive post here I linked above.
As far as I can see it's bunch of changes for _far resp. _PF support for AVR-libc.

The default linker scripts are supplied by binutils.

I still don't understand what the problem with "(.progmem.gcc_sw_table+0x26): warning: internal error: out of range error" is about.

For example, if I locate .trampolines at 0x30000 everything works smooth and the code is correct (except EIND initialization which must me made by hand).

Size of arrays is limited by the C language and the ABI; even with 3-byte pointers all objects must be smaller than 32768 bytes.

And I am unsure if all that > 64k stuff is supposed to work out of the box. If I had to use such devices (I never used them and will never use them), I'd expect to write my own linker scripts, anyway.

In order to locate data in upper part of flack you could use avr-gcc 4.7 and its __flash1/2/3 but there is still still of home brew linker script for that because the default scripts know nothing about .progmem.data1/2/3

You think the far stuff is still needed in times of named address space support?

avrfreaks does not support Opera. Profile inactive.

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

SprinterSB wrote:
PR is short for "problem report".
[...]simply append PR52261 to gcc.gnu.org for GCC PRs, or append to sourceware.org for binutils PRs[...]
Ah, I see, thanks. I doubt this is common knowledge outside the gcc/binutils developer circles.

SprinterSB wrote:
Quote:
I've requested said changes in original post in https://savannah.nongnu.org/bugs/?26365 [...] I then posted an example modified linker script to that tracker item and explained the changes in the extensive post here I linked above.
As far as I can see it's bunch of changes for _far resp. _PF support for AVR-libc.
And what would you expect exactly from a feature request, and a writeup by a user who does not know how nor want to dig deeper?

SprinterSB wrote:
I still don't understand what the problem with "(.progmem.gcc_sw_table+0x26): warning: internal error: out of range error" is about.
I'd expect that the vast majority of the >64kW devices' users would need the huge flash for extensive data, and the code is less, sometime far less than 64kW - as is the case of our OP, too. Increasingly so in these days of cheap ARM devices with virtually unlimited address space. That voids all concerns with EIJMP-kind of stuff in the majority of cases, as long as the users know how to put the data high enough and how to use them. This is why I'd not put more effort into trampolines etc. and concentrate on methods and documentation on how to handle big constant data.

Actually, I even wasn't aware of the EIJMP-related problems at the time of writing that writeup, even if my code of the project involving 'M256x eventually did cross the 64kW boundary. It was just through trying to support those who posted about these problems here I realized this.

SprinterSB wrote:
In order to locate data in upper part of flack you could use avr-gcc 4.7 and its __flash1/2/3 but there is still still of home brew linker script for that because the default scripts know nothing about .progmem.data1/2/3

This puzzles me. You seem to blame me - who can't tell PR from "public relationships" ;-) - for not pushing through the proposed changes to binutils, yet you - an already established gcc developer - didn't do the very same thing?

SprinterSB wrote:
You think the far stuff is still needed in times of named address space support?
If completed to the point where it's easy to use by the mere users (which involves exhaustive and precise documentation), far/PF might get obsolete by then - but I don't see that coming into mainstream that soon. Please don't take this personally - you hardly can do more for this, but the support your work receives from the "integrators" apparently lags far behind your effort. And seing Atmel refocusing onto ARMs apparently in the belief that that would boost their sales to the skies, I don't see that support to come in the near future either.

JW

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

wek wrote:
SprinterSB wrote:
PR is short for "problem report" [...]simply append PR52261 to gcc.gnu.org for GCC PRs, or append to sourceware.org for binutils PRs[...]
Ah, I see, thanks. I doubt this is common knowledge outside the gcc/binutils developer circles.
You can use bugzilla/bug tracker of the respective project, of course, to go to the report or search for specific problems. But bugzilla is slooow...

wek wrote:
SprinterSB wrote:
Quote:
I've requested said changes in original post in https://savannah.nongnu.org/bugs/?26365 [...] I then posted an example modified linker script to that tracker item and explained the changes in the extensive post here I linked above.
As far as I can see it's bunch of changes for _far resp. _PF support for AVR-libc.
And what would you expect exactly from a feature request, and a writeup by a user who does not know how nor want to dig deeper?
If it's extension to binutils, I'd expect a feature request for binutils.

If a request is hidden between a bunch of other, technical unrelated requests it's not unlikely it's been overseen or no-one gave a hint that some parts of the request aim at a different project.

wek wrote:
SprinterSB wrote:
In order to locate data in upper part of flach you could use avr-gcc 4.7 and its __flash1/2/3 but there is still need of home brew linker script for that because the default scripts know nothing about .progmem.data1/2/3
You seem to blame me [...] for not pushing through the proposed changes to binutils, yet you - an already established gcc developer - didn't do the very same thing?
I am not a GCC developer. I am AVR hobby guy that is more focused at avr-gcc than at AVR at the moment. BTW, it's quite comfortable to have this second degree of freedom: If some code sequence is suboptimal, hack the compiler instead of the application :P So you can blame me for doing co-development of a hobby project and a hobby compiler, and for doing Atmels homework.

For the __flash spaces and .progmem.data sections: I don't think it would be any good to add them to the default linker scripts. This would assert a certain anatomy of the software, and all sorts of problems would arise with section overlaps, overflows etc. if the software did *not* fit that specific anatomy.

This as all documented:

What's missing is a similar section on RAMP*

And if a feature/extension is needed, I file a feature request for it. See for example

http://sourceware.org/PR13503

IMHO, the very problem is that developers grab some silicon, drop tons of code, drop tons of data, click a button and expect everything to work as if they programmed a PC with gigabytes of memory, and without even thinking a second about the implications made by a segmented Harvard architecture that only supports 16-bit pointers, without even thinking a second about what tools that click triggers, without ever having read a single like of documentation of that tools, etc.

If I started such a big project, I would not even expect for a single second that this works without juggling data and own sections by means of own linker script. And I am a *hobbyist*!

wek wrote:
SprinterSB wrote:
You think the far stuff is still needed in times of named address space support?
If completed to the point where it's easy to use by the mere users (which involves exhaustive and precise documentation), far/PF might get obsolete by then
It's easy to use. But many people confuse "easy to use" with "what the fuck is documentation?"

wek wrote:
And seeing Atmel refocusing onto ARMs apparently in the belief that that would boost their sales to the skies, [...]
I think they are right moving away from AVR for bolide designs.

Adding even more dreaded features at the upper bound in order to hack a limited design must end up with dead horses...

avrfreaks does not support Opera. Profile inactive.

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

Quote:

I doubt this is common knowledge outside the gcc/binutils developer circles.

I don't know. Anyone using any kindof Bugzilla like system will be familiar with the concept of PRs and CRs (Problem Reports and Change Requests). One being something that needs fixing and the other being an idea for new functionality.

 

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

Lets sume up for a bit, there are 3 bugs here:
1.
When the data in the array is manually placed at specified location in the flash it is being read from some segments wrong.
See the iss file attached, when im trying to read from my segments in 0x20000 the compile generates code that reads from 0x10000, but if i read from 0x30000 the compiler gets it right.

const  unsigned int Lys_tabel_data950[320][12] __attribute__ ((section (".lys950"))) 

pwm_kanal_1=pgm_read_word_far( 0x30000 + (uint32_t)&(Lys_tabel_data80[min_point][0]));// right

pwm_kanal_1=pgm_read_word_far( 0x20000 + (uint32_t)&Lys_tabel_data660[min_point][0]);  // FFFF 

2.
The minor bug in avr studio where your flash segment is multiplied with 2. see posts higher.

3.

The internal error when im storring variables with __pgmx

And if i had the option to change from AVR to ARM yes then i would have done that, but that is not an option.

Attachment(s): 

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

Quote:

The minor bug in avr studio where your flash segment is multiplied with 2. see posts higher.

That's not a bug - Atmel make Studio use word addressing as that's what they always use for flash in their datasheets. It is just a "percularity" of GCC that it uses byte adressing as a lowest common denominator that can apply to all architectures. So this word_addr X 2 = byte_addr thing has existed in AVR Studio right since it first statred interfacing with GCC.

 

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

S_i_v_s_k_o wrote:
1.
When the data in the array is manually placed at specified location in the flash it is being read from some segments wrong.
See the iss file attached, when im trying to read from my segments in 0x20000 the compile generates code that reads from 0x10000, but if i read from 0x30000 the compiler gets it right.

const  unsigned int Lys_tabel_data950[320][12] __attribute__ ((section (".lys950"))) 

pwm_kanal_1=pgm_read_word_far( 0x30000 + (uint32_t)&(Lys_tabel_data80[min_point][0]));// right

pwm_kanal_1=pgm_read_word_far( 0x20000 + (uint32_t)&Lys_tabel_data660[min_point][0]);  // FFFF 

This is caused by the compiler sign-extending the pointer when casting to uint32_t.

The compiler apparently treats pointers as signed int. While this is surprising, it appears to be perfectly legal according to C99 6.3.2.3#6.

You might want to cast the pointer twice, first to uint16_t and then to uint32_t, to avoid this.

JW

PS. You still can use the technique I described in the writeup and you dismissed in your previous post: apply Carlos Lamas's GET_FAR_ADDRESS() macro to the first member of the array and add the calculated offset of the needed member. This alleviates the need to manually locate the arrays and manually add the segment address.

If you don't know how to calculate the offset in a multidimensional array, or you don't want to calculate it for some reason, you can circumvent this problem by placing the array into a struct and taking offsetof() of that member (it's enough to typedef a type of same structure). This all could be hidden into a macro if needed.

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

All what you need is a costom linker script. Copy the default for avr6 from, say

./avr/lib/ldscripts/avr6.x

and arrange the sections according to your needs.

In particular, place .progmem* after .text* and you are done.

Then link with -Tyour-linker-script

That's it.

No hacks in the source.
No pointer mess.

avrfreaks does not support Opera. Profile inactive.

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

S_i_v_s_k_o wrote:
i still get "internal error: out of range error" to my array file
Filed a binutils bug for this one. If the default linker script from binutils is not changed to avoid the problem, there should be a descriptive error message at least:

http://sourceware.org/PR13812

avrfreaks does not support Opera. Profile inactive.

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

Ok i got it all to work now, also with studio 6.

in avr studio i have define the memory space for each variabel and the first part is the block off set, then to make it work i needed to double cast the adress like:

pgm_read_word_far( 0x30000 + (uint32_t)((uint16_t)&Lys_tabel_data80[min_point][0]));

Now it all works:-)
Thanks all for the help