GCC with large memory AVRs

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

I feel that this has been discussed before, but finding the information has proven painful so here is my question/comments.

With AVRs (xmegas) that have more that 64k, 128k, and 256k of flash with GCC (WinAVR) I have ran into problems. From what I found is that PGM_P is 16bit thus it appears that Carlos has made a patch to libc, not yet in WinAVR as of 3/8/2011, which has PGM_PF and basically _PF replacements. This patch allows 32bit access to program memory, which is good.

First question is does Carlos patch work with the xmegas, found some reference that it might have problems?

The second question, I have is does GCC handle the calls to functions using 32bit address? That is am I going to run into a problem where I can not call code above some boundry?

Third question, would it be reasonable for GCC and libc to know about processor and use correct code. That is could the sprintf_P and related functions be macros and based on the processor selected pick the correct libc function. This way it keeps newbies from having problems.

Fourth question, is there beta build of WinAVR with Carlos' patch or would I need to rebuild libc myself, or include his code in my project?

Note just for the key word searching I found this problem in my code on a ATxmega256 when the code would magically jump to random locations, usually high memory locations and thus reboot. I have used the dead code removal to get code under the 64k boundry and it works now, but I am scared that GCC might have other address limitations besides the PGM_P issue and hence my questions.

Thanks
Trampas

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

> does GCC handle the calls to functions using 32bit address?

Yes, but you have to specify the -mrelax compiler option when linking.

> would it be reasonable for GCC and libc to know about processor and
> use correct code. That is could the sprintf_P and related functions
> be macros and based on the processor selected pick the correct libc
> function

The question here is: "which one is the ``correct'' one?" The
traditional _P versions work well even on large AVRs, provided the amount
of constant strings/data is below the 64 KiB (- sizeof vector table). For
those who fit into that, forcing everything to 32-bit addressing is
wasteful.

> is there beta build of WinAVR with Carlos' patch or would I need to rebuild
> libc myself, or include his code in my project?

Right now, it's only available as a patch, awaiting inclusion into the
tree. I haven't looked into the patch whether it actually even involves
changing compiled functions, or whether it's perhaps header-file only.
In the latter file, it would be a matter of replacing the header file
only, otherwise you indeed have to recompile.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

I installed the 1.7.1 libc with Carlos' patch and found that vsprintf_P has not been ported to vsprintf_PF, along with the other _P functions in the stdio.h.

With out the -mrelax option is the code size limited to 64k for the xmegas? The reason I ask is I was wondering if the random jumps to no where (and reboot there from) would be fixed with -mrelax? I will try it anyway but thought I would ask....

As far as the 'correct' action what I would recommend is that at link time check were the string table ends and then use correct library (assuming two libraries) with a Warning displaied from compiler letting user know what is happening. Optionally just as good is to display a warning if the 16bit library is used with the string table larger than 64k. This way the tool creates working code with default settings.

Thanks Again!
Trampas

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

For more information...

My code broke (jump to high memory and reboot) when it got above the 64k memory boundry. The library code (some _P functions) were across the line. However the code appeared to work most of the time but broke in weird places, where _P functions were not called. Slight changes in source code, like adding printf(), would mask the problems.

I put in the dead code removale, function sections, and the problem went away as the memory dropped below 64k.

What I have read is that -mrelax is passed with -Os option, which I have on. Also the -mrelax is for 128k barrier, thus this should not apply, correct?

Thus I am wondering if with the xmega does the EBI register make a difference on the strings? That is from what I have read the -mrelax should not apply and the text is below 64K thus _P and _PF does not apply. Thus is there something I am missing, like strings are find below 64K as long as code is below 64K too?

Thanks Again!
Trampas

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

-Os is unrelated to -mrelax. The first is a compiler option, the second
one is (basically) a linker option.

Yes, it's about things beyond 128 KiB regions, in particular about
indirect jumps or calls across that region. The 64 KiB "barrier" only
relates to LPM instructions which are byte-addressed, while all code
addressing is in terms of 16-bit units (which they call "word" on AVR).

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Does it make any difference where the PC is when the LPM is called?

Again if it makes a difference this is an xmega256A3.

It looks like my string tables end at:
00002750 <__ctors_end>:

Thus the LPM should not be an issue, correct?

Thanks Again
Trampas

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

tstern wrote:
The second question, I have is does GCC handle the calls to functions using 32bit address? That is am I going to run into a problem where I can not call code above some boundry?

Third question, would it be reasonable for GCC and libc to know about processor and use correct code. That is could the sprintf_P and related functions be macros and based on the processor selected pick the correct libc function. This way it keeps newbies from having problems.

Fourth question, is there beta build of WinAVR with Carlos' patch or would I need to rebuild libc myself, or include his code in my project?

Note just for the key word searching I found this problem in my code on a ATxmega256 when the code would magically jump to random locations, usually high memory locations and thus reboot. I have used the dead code removal to get code under the 64k boundry and it works now, but I am scared that GCC might have other address limitations besides the PGM_P issue and hence my questions.

At present, avr-gcc knows only about 16-bit addresses. It would not be a big deal to change this in avr-gcc so that function pointers are 24-bit provided the user is willing to attach a named address space to function pointers (as introduced in the draft technical report of the ISO/IEC JTC1 S22 WG14 N1275). With this extension no jumping pads were needed and indirect calls/jumps would work.

For [e]lpm it is not so easy because _both_ [E]LPM and LD* Z use RAMPZ as their MSB. This would lead to bulky code like save/restore around LPM.

However, the major problems are:

1) Any such extension would have to be smooth with current interfaces, like the ones of avr-libc. Moreover it would mean to put RAMP* resp. EIND under the control of the compiler and that user code that changes such a reg would be as erroneous as changing some GPR.

2) avr-gcc suffers from lack of developers and that hardly anyone is actually testing new releases of avr-gcc to give narrow feedback-loops. Within the next few weeks we will see GCC 4.6.0 being released (opening development for 4.7), but avr-gcc still suffers from bugs and shortcomings that can alredy be seen in 4.3 or 4.4.

I actually never used bolide avr and don't know how application cope with their segmented layout. Guess it's basically triggering RAMP* and EIND by hand. For dirct jump ld build jump pads, but that's not possible for indirect jumps/calls.

Johann

avrfreaks does not support Opera. Profile inactive.

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

> Does it make any difference where the PC is when the LPM is called?

No, LPM is 16-bit only anyway, and ELPM uses RAMPZ to extend the 16-bit
address range of the Z register pair.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Are you talking about https://savannah.nongnu.org/patc... ?

Back then I was interested in the topic, maybe . https://www.avrfreaks.net/index.p... could shed some more light (and a couple of more shadows, too :-O )

JW

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

I have looked at my code, stepped through it, etc. I still have not found the issue. Did find that compiler was setting RAMPZ to 0x01 and not setting back to zero but did not fix my problems.

Trampas

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

All the above is why, for me, if it won't fit in a 128KB or less AVR, go use ARM/Cortex.

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

Well with Atmel's current supply problems I am getting worried about the company as a whole myself. I do like the xmega and the AVR32 but....

Trampas

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

tstern wrote:
Well with Atmel's current supply problems I am getting worried about the company as a whole myself.
They made a record profit last year. And they had the supply problems already last year.

It is more that the record profit makes them arrogant. Something that will cost them in the future.

Stealing Proteus doesn't make you an engineer.

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

I really love the xmega, I have done about 10 products with it and have a nice library of code. Thus I hope Atmel sticks around and dumps money into the WinAVR and GCC. I would really like to get a new release of WinAVR....

Trampas

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

I forgot to mention that I might have fixed my problem. I found that adding code would mask problem commenting out a function call (which was called earlier thus valid code) would mask problem. Thus it just appeared as though the xmega was reading wrong instructions or something. So I dropped the clock rate down to 2Mhz from 32Mhz and I don't have a problem....

the processor is running at 3.3V with BOD at 2.9V thus well in 32Mhz spec, but.

It got the point that if I commented out a delay_ms(1) the code would run...

Therefore I hope this fixes problems....

Trampas

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

Well I did another test... Put processor at 3.5V and crash still happens.

Took the code compiled with F_CPU=32Mhz but set clock at 2Mhz, thus same code as much as possible just ran at lower clock. Hence delay loops to 16 longer. The results was the code crashes.

Trampas

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

For the next piece of data....

Since I have the interrupts disabled I moved the .text section using the linker. If I move the code 0x0100 bytes then the code works perfect. If I move it 0x002 it still crashes. NOTE this does move the ISR vector table but since I am not using interrupts it just executes nop before calling reset vector.

Another piece of information. While running the divide routine which is located at high memory ~(0x98xx word address) I get a byte out my serial port. If I single step through the code, no byte. If run about 20 instructions in the code at speed I get the byte. Shortly there after code breaks. Note this divide routine is called about 10 times with same data before this happens. Thus it does not happen every time in the code...

Right now I am wondering if the higher memory flash is a different die or chip select that might have different timing causing issues?

Thanks
Trampas

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

I swapped out the processor with a 192A3 version and it still has the same issue. Since moving the code 0x0100 bytes masks the problem and the crashing occurs in code that is called several times before hand I tend to belive that avr-gcc is doing the correct thing. Additionally we only notice any problems when the code is located about 64K bytes, thus we are to the point that it appears to be a problem with processor.

The question becomes how much time do we spend determining if the problem is the processor or not. The results of which would be to continue using the xmega or not. Therefore it might be best not to use the xmega.

Trampas

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

> when the code is located about 64K bytes,

Ah well... that rings a bell: is it possible that you accidentally
hit a jump table around the 128 KiB boundary? If so, the linker
might move a trampoline in there. But it wouldn't explain any odd
behaviour for a 64 KiB boundary.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Do you use any of the xxx_PF() or pgm_read_xxx_far() functions?

JW

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

The code is around 80k bytes. All the strings are in lower memory thus I do not use any _PF() or far(). I am using the the older libc from the January 2010 WinAvr release.

Trampas

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

I see no trampolines in the listing file. I don't think I am anywhere near the 128KiB boundry. again code is only 80K. Also that does not explain why code works with single stepping and strange behaviors when running...

Trampas

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

I did a quick test by allocating code in the upper 64K but so far it has not crashed. I guess I need to write a test generator that generates some code to place in upper 64k and run throuh all the addresses.

Trampas

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

Does the xmega power down unused flash sections?

Trampas

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

I have downloaded and install AVR Studio 5.0 which includes avr-gcc using GCC 4.5.1. I am not sure about which libc is included but so far the code works!

Thanks
Trampas

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

The manual in "\Program Files\Atmel\AVR Studio 5.0\extensions\Application\AVR Toolchain\doc\avr-libc" says it is 1.7.1

Quote:

Does the xmega power down unused flash sections?

No but the memory is static (and non-volatile) so it cannot be consuming more than a fraction of a micro-amp anyway.

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

I miss WinAVR, little things like avrdude and srec_cat make a big difference. I finally had to reinstall WinAVR and copy the tools over...

Trampas