AVR Harvard architecture -- worst of both worlds?

And we won't even get into Little-Endian vs. Big-Endian...

An "interesting" situation arises when dealing with constants in programs. One would like to put these in ROM but with a Harvard architecture, one can't access the locations as directly (if at all) as one can if the values are in RAM. Thus, one has to have either special functions to call to copy the constants to RAM when needed or copy them to RAM at program initialization. The latter runs the risk of the RAM location getting overwritten and the constant not being as constant as one wishes. The former adds a layer of complexity and additional execution time to the programming that one would just as soon avoid.

The AVR just adds to the problem by having word-oriented addressing for the ROM space and byte-oriented addressing for the RAM space. This makes life especially "interesting" for linkers which have to be able to distinguish between ROM and RAM addresses to perform the proper offset calculations.

Reply to
Everett M. Greene
Loading thread data ...

Thank Bog!

I don't understand how it would even be possible to copy the constants to RAM if they can't be accessed "at all" when they are in the flash ROM. Good trick.

But of course, all that's necessary is to use the "special function" [sic] which is really just another opcode (LPM) to fetch a constant from ROM into a machine register vice using LD to fetch a value from RAM. What's the big deal? Seriously.

Or just fetch directly from ROM when needed?

Well, okay, but distinguishing between and managing the various code/data/bss/text/... segments is what linkers *do*.

Reply to
Rich Webb

Indeed linkers do link various sections - this is what they do. But if one sections address increment is worth one byte and anothers - two bytes, things become a bit messy. I had to deal with that when I included a DSP which had a word based address space (16 bits per address); what I generally did was add a switch to the linker, once it saw one such - 16 bits per address - section it switches to this mode. There was more to it than that, it still had to be able to use ASCT symbols from either size etc., so the issue is not non-existant. Having said that, it was not a huge issue either, I don't remember having to wrestle it for too long (must have taken me < a week, 5-6 years back).

Dimiter

------------------------------------------------------ Dimiter Popoff Transgalactic Instruments

formatting link

------------------------------------------------------

initialization.

Reply to
Didi

The big deal is the lack of the universal *. You have to explicitly use the different kinds of pointers depending on where is the object. Those pointers can't be casted. It also creates a major mess when you have to use several levels of indirection; when the different levels are located in the different classes of memory. For that reason, the IAR EC++ for AVR tends to keep the constant static objects in RAM rather then in ROM.

Vladimir Vassilevsky DSP and Mixed Signal Consultant

formatting link

Reply to
Vladimir Vassilevsky

To expand on this, it means you can't e.g. put all your constant strings in flash and use standard library functions with them. There are special versions of the standard library functions what will accept these "program strings", but these are then incompatible with your strings that *are* in ram.

It makes it very awkward to define things like menu tables.

In principle I think these issues could all be hidden by the compiler, but unfortunately none of them seem to do this, even the commercial ones as far as I know.

This is the main reason I now use ARM for new projects, unless the application is *very* small (in which case there won't be too many strings or complicate constant structures).

(All the above refers to C, of course).

--

John Devereux
Reply to
John Devereux

initialization.

I've worked with at least one CPU in the past that had no access to the code space at all.

You left out the steps of having to load the ROM address into the Z register, execute the LPM instruction, and then move the fetched value to where you want it if you want it somewhere other than R0. You have to move the value if you're dealing with a multi-byte entity.

And how do you pass by reference?

With quite some difficulty.

Reply to
Everett M. Greene

The same way C compilers for RAM-constricted Harvard architectures have done it since day one: have the C compiler add a special flag to generic pointers that indicates whether they point at RAM or ROM, and use it accordingly. Memory class-specific pointers (i.e. the 'code' keyword) then offer a significant speedup over those, but the rules of C pretty much require one of the following for generic pointers to const data on a Harvard:

1) an "intelligent" pointer implementation (the CPU may help here, by keeping code and data in numerically separate address ranges) 2) copying const data from code to data space at boot-up (losing the physical immutability) 3) mapping const from code into data space by memory access hardware (MMU, address decoding logics)
Reply to
Hans-Bernhard Bröker

You might want to rephrase that statement! :)

A CPU with "no access to the code space at all" cannot even fetch opcodes, and is thus going to be very easy to work with, as it is a paper-weight.

-jg

Reply to
Jim Granville

Vladimir, this is a shortcoming of the C language. I know others that let the programmers treat RAM and ROM and EEPROM the same.

Rene

--
Ing.Buero R.Tschaggelar - http://www.ibrtses.com
& commercial newsgroups - http://www.talkto.net
Reply to
Rene Tschaggelar

...

No, it's a shortcoming of some implementations of the C language. Nothing in the language requires that RAM and ROM share address space.

HI-TECH Software (for example) have been doing C compilers for Harvard architecture machines for a very long time which manage to use 'const X *' as a "universal" pointer, able to refer to RAM or ROM objects with no extra work from the programmer.

mlp (Yes, I'm currently employed by HI-TECH, but that's not relevant here

- I'm defending the language, not pushing an implementor.)

Reply to
Mark L Pappin

This implies RTTI in the pointers, with the corresponding tradeoff in performance.

Vladimir Vassilevsky DSP and Mixed Signal Consultant

formatting link

Reply to
Vladimir Vassilevsky

Copying constants to RAM on startup does not run any risk of the locations getting overwritten unless your program is totally messed up, and then "varying constants" is only one of your many problems.

If you can arrange for the compiler to see the constant's values before using them, it will generally use the values directly in the code. Otherwise, the only disadvantage of copying them into RAM is the RAM space used - for lookup tables, you might want to make sure they are in flash.

That's only a problem if you are writing an AVR linker or appropriate low-level library routines. For compiler users, you just read the FAQ for your compiler.

The real problem with multiple memory spaces is that C has no standard way of dealing with them, so that every compiler has its own syntax (some misuse "const" to mean data in flash, some have an extra "flash" keyword, others use macros).

Reply to
David Brown

The language *does* require a single address space (accessible via a "void*" pointer). It is perfectly possible to embed the separate address spaces into a larger virtual address space, and thus have universal pointers (at a cost in code space and run-time) - that way you are extending the multiple address space cpu into a C-compatible cpu.

Reply to
David Brown

You think so? "void *" is *not* a universal pointer, oh no, no, no. The language does not allow a function pointer to be compatible with void *, no siree. Hence, there is no requirement for CODE and DATA to be in the same address space. The fact that some customers wish const data to be placed in CODE address space is another matter entirely--and I'd agree that a void * is a universal pointer only for data objects, not for function objects.

-- Paul.

Reply to
Paul Curtis

Sorry - I was thinking only of data pointers, not function pointers (since that's what was mainly under discussion). You are entirely correct that data and function pointers don't have to be related (they can be different sizes and have different memory spaces).

Reply to
David Brown

Picky, picky, picky,... :-)

Alright, it could execute instructions from its program memory but could not access the program memory as data in any way whatsoever.

BTW: It wasn't much above the paperweight class as it was.

Reply to
Everett M. Greene

The AVR mega core allows you to do

LD Rn, [Z+]

--
Best Regards,
Ulf Samuelsson
 Click to see the full signature
Reply to
Ulf Samuelsson

I copy constants to the stack when needed. A little hassle, but not dramatic.

I seems to remembed someone telling me that the Harvard architecture of the AVR improved performance by about 35% performance.

--
Best Regards,
Ulf Samuelsson
 Click to see the full signature
Reply to
Ulf Samuelsson

I'm not sure I can think of any reason why that might help. The only two problems with constants in flash are the awkward syntax (either you've got extra keywords or macros added, or you've got a broken "const" implementation), and for pointers (such as passing around strings in flash).

Having separate buses for code and data is certainly a good thing for making simple and fast processors, although I think that any figure put on it is taken out of thin air (did someone make a complete AVR core with a shared bus for comparison? Any other method will have huge error margins). But having separate memory spaces, which is the issue here, has much less effect (you'd need a little extra decoding of memory accesses, but save the lpm instructions). The extra memory spaces make it easier to get more than 64K memory ranges, but are otherwise a big disadvantage.

Reply to
David Brown

David, the syntax is a matter of the compiler. The syntax of C has never been phantastic either.

Rene

Reply to
Rene Tschaggelar

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.