Just what makes an architecture "C Friendly"?

The MIPS, combined with OS support for overflowing the register stack, is effectively similar. What makes the MIPS and the HP3000 work well here is that the addressing is very short (since you are really specifying offsets from the top of stack, not full explicit addresses), and the access is full speed (on the HP3000, the memory was fast compared to the processor, while on the MIPs, the directly accessible part of the register stack is in hardware registers).

Reply to
David Brown
Loading thread data ...

This is not the fault of the Harvard architecture.

Those "const" variables should never appear in the code space by definition.

It is simply stupid to store the initial values in the code space, since they do not belong there and in the case of e.g. PIC, the code width is 14 bits and the data bits is 8 bits, so direct copying one code space word to one data space byte is not very optimal. Only if you copy four 14 bit code words into seven 8 bit bytes, this copying makes sense.

No more inefficient compared to initialising automatic variables at the declaration.

In many languages, you do not even have the option to pre-initialise the global variables at startup, but you have to do it explicitly (as in PL/M-80).

Just an example that the hardware vendor does not understand the real needs.

Yes, you are right, I was still thinking about the global variable initialisers.

In many single chip controllers you have a moderate code size and a very small data space, but in bigger systems you have to decide between using external Flash (for permanent storage) or RAM (for temporary storage of data _and_ code).

In large systems, depending on the relative cost of Flash/RAM it might make more sense to use RAM and load the code/static data from external storage into RAM. The question is quite irrelevant if the load device is a 1" disk drives, IDE compatible flash or the program/data is loaded from some external source using the Ethernet or CANbus etc.

Software updates are also simple, if the code is booted each time from a centralised resource.

Paul

Reply to
Paul Keinanen

It's not the _fault_ of Harvad architecture, but when combined with Harvard architecture, it is C-unfriendly.

If the only non-volatile storage you have is code space what else are you going to do?

Of course it's bad. That's the point we're trying to make. Putting data in code space is a bad idea. But if the only non-volatile storage you have is code space, you don't have a choice. You have to put data in code space.

But there's no way to avoid that. There _is_ a way to avoid executing separate bits of code to initialize every single static storage scope variable.

Whatever. We're talking about how Harvar architecture in embedded microcontrollers is inherently C-unfriendly.

Ateernatively, if pigs had wings...

But, it's not a problem for VN architectures. Perhaps in some alternate universe, Harvard architecture uControllers have ROM in data space. In this one they don't.

--
Grant Edwards                   grante             Yow!  That's a decision
                                  at               that can only be made
 Click to see the full signature
Reply to
Grant Edwards

It's nice to be able to use immediate indexes, for instance.

The PIC18 stinks too (even with extended instruction set).

Reply to
toby

There is no register stack on MIPS, indeed there's no hardware support for any stacks[1]. What you do get is a few registers for passing subroutine parameters. Any more than that has to be put on the stack which is entirely software controlled. Even this is merely convention rather than anything to do with the underlying silicon.

[1] This point is arguable - by convention, there is a stack register (29 if memory serves, but that memory's quite old) that the assembler JAL instruction (Jump And Link - for subroutine calls) implicitly addresses. However there's also a JALR (Jump And Link to named Register) instruction. If you compare the opcodes, you will see that JAL is merely a synonym for JALR that implicitly addresses the usual stack pointer - again, convention for programmers rather than anything etched into silicon.
--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply to
Andrew Smallshaw

Try writing a printf routine which will write out all strings below with capital 'T', on a Harvard architecture and you see the problem.

__flash unsigned char s1[] = "This is a string"; unsigned char s2[] = "this is another string";

void printout(void) { s2[0] = 'T'; printf("This is a few string"); printf(s1); printf(s2); }

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

But "C friendly" means several things. When GCC says this, I'm pretty sure it means "friendly environment in which to implement a GCC compiler". So you've got several meanings here:

Friendly for a C programmer to use as the destination platform. Friendly for C compiler writers (as a destination). Friendly for running a C compiler on.

I'm pretty sure that the third wasn't what the original question was asking. The second is interesting of course, but there are far more C users than C compiler writers. But too much unfriendliness for the compiler writers can translate into unfriendliness for the compiler user (or the compiler writers may just decide that it's not worth the time and money to implement some feature if the expected audience isn't likely to use it).

It's also not clearly defined what "friendly" means. All features of C most certainly can be implemented on the PIC16 family, but few would classify it as C friendly. The snag is that many of the features come with limitations or efficiency costs (size or speed). So I'd say that "friendly" means that the author of C code runs into a minimum of snags and gotchas. Fewer limitations, less effort involved in getting fast or small code, fewer workarounds, etc.

For instance, the C compiler for the PIC I sometimes use seems to have a lot of features, and the code it accepts if very much like C. But it is more difficult for me to maintain the PIC C code in my job than it is to maintain the 32-bit RISC C code. That's because of the C style necessary to get fast and small code on the PIC. It has lots of global variables, long unfactored functions, miscellaneous unique keywords, and so forth. Some may be due to the small size of code space, but much is due to other limitations.

So the C compiler for the PIC is unfriendly because in order to use it efficiently one must be careful of how they write the code and be aware of the limitations - reading the compiler manual thoroughly is mandatary, and examining generated output code is highly recommended.

While the PIC assembler writer may have to jump through the same hurdles as the PIC C compiler writers or C writers, assembler writers know up front that they're writing non-portable code and what the various snags are. C authors generally use the language as a tool to express their application in, and may often find out much later that what looked like decent code has contributed to bloat or slowness. So "C friendly" may mean that you can just start writing without worrying about the target processor and still get a reasonable result.

Here's something to think about from a philosophical point of view. If a C compiler has to jump through hoops and use lots of instructions to do something that would be simple on comparable processors, but the equivalent human written code in assembler has to jump through the same hoops, then is the C compiler unfriendly? For instance, accessing constants that are stored in code space. On one hand there are hurdles for the C programmer, and possible a restricted style of C has to be used. But on the other hand it may still save a lot of time and be more maintainable than writing in assembler. The processor might be considered unfriendly to all programmers, not just C programmers.

-- Darin Johnson

Reply to
Darin Johnson

No. C works just fine on Harvard architectures. Function pointers are treated differently enough from data pointers that von Neumann architecture doesn't gain you much of anything.

What does make a somewhat huge difference for C-friendliness, though, is having a completely flat, uniform memory space at least for data. I.e. no 'far', little to no segmentation visible to the C programmer, all I/O memory-mapped, and a sane reserved value for null pointers.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

GCC works fine for a 68HC12 with 1 general purpose register.

Nonsense. I've use GCC for 8 and 16 bit targets.

Bah. I've used GCC for targets that don't even have enough memory to run DOS.

--
Grant Edwards                   grante             Yow!  FOOLED you! Absorb
                                  at               EGO SHATTERING impulse
 Click to see the full signature
Reply to
Grant Edwards

Of course not. This is comp.arch.embedded. The second question is obviously what was meant.

--
Grant Edwards                   grante             Yow!  One FISHWICH coming
                                  at               up!!
 Click to see the full signature
Reply to
Grant Edwards

The problem isn't function pointers. It's pointers to read-only data that you need to store in ROM.

Which you don't have on Harvard architectures because all of the embedded systems I've ever used used at least some read-only data.

--
Grant Edwards                   grante             Yow!  My pants just went to
                                  at               high school in the Carlsbad
 Click to see the full signature
Reply to
Grant Edwards

There is a problem with char string constants with small processors having only I-space ROM. Maybe the phrasing should be that Harvard architecture is less C-friendly than von Neumann architecture.

And speaking of degrees of friendliness, could we say that the ARM instruction set is too C-friendly?

I once did some work with a special-purpose image processing Harvard architecture machine that had no provisions for accessing I-space as data. That really restricted one's options.

Reply to
Everett M. Greene

As an assembly-language programmer, I avoid jumping through hoops if I don't feel like it. For instance, I found bank-switching on the PIC gave me access to (what would be in C) an array of structs virtually for free.

I'd still commiserate with compiler-writers who found it painful to get all the C facilities contrapted into the PIC resources. The better job they did (and/or could do), the less the C programmers would find the resulting C environment unfriendly.

Mel.

Reply to
Mel Wilson

Yes. I think the GCC definition for C practice is expressed by a growing number of people. I do think it is a stretch for embedded use, but it is becoming an option more often to take the library and file system and OS from development platform to the embedded target with the minimal effort.

I don't live in that space, but I see more and more people offering that point of view, so I commented that I think C does mean somewhat different things to different people. I intended to enumerate several meanings.

There is another thread about the most unfriendly-for-C architecture for which people actually use C. And architectures for which no one has used C are probably those that are WAY too small for something like GCC. If you are working with an embedded design that has only a few words of ROM, no RAM or a few words of RAM, no general purpose registers, non-byte address, non-power of two bus width, no hardware error traps, no interrupts, etc. type architecture for which there is no C compiler you probably consider it C un-Friendly enough to not make the effort to try to use C.

And even if you are just generating a small bit of embedded code for that environment by running Linux and GCC quite happily on a PC you probably were not thinking of running GCC out of a dozen words of target ROM.

Yes. But I wasn't really refering to compiler writers but compiler users. Of course compiler writers are compiler users, so they are a subset of the people who might want to run a C compiler.

I was just pointing out that some C compiler users want to stick to architectures, even for embedded systems, that are C compiler hosting friendly, not just C comiler target friendly.

One responder said that 'C Friendly' was about the quality of code generated by the C compiler compared to the quality of code generated some other way. I first thought that sounded very circular.

But as you point out, there are more compiler users than compiler writers, and most will decide if something is C friendly based on how good a job some other people have done in writing the compiler for them so they can focus on describing a problem solution in C code and getting it to work properly.

So I think we have discussed quite a range of different types of C programmers from those who want to stay at the Linux level on embedded targets, those who want to stay at the C level in embedded targets, those that mix C and assembler or other things in their embedded targets, and those who sometimes say that an architecture that they programmed was just too C unfriendly to use C at all.

Yes. I think that's a good way to see the idea of 'C friendly.'

Yes, That's what I was thinking too.

When I worked at the iTV Corporation they started work on a C compiler that had layer of compromise upon layer of compromise until almost no one would be willing to put up with the snags and the gotchas and hopelessly slow and bloated code. The architecture was unfriendly enough to C that a great deal of effort would have been required to anything decent out of a C compiler.

Yes. That is what I was thinking too.

If you had a tiny ROM/RAM, or no RAM at all or something like that you probably would not try to generate the code with C if that was going to mean lots of global variables, long unfactored functions, etc.

Not that with enough effort it could not be done. And friendliness is related to the effort to use C vs something else.

And if no one had written a C compiler for the PIC even more people would see the PIC as even more unfriendly to C.

And if they didn't notice it until later, it might not have even been all that important that code was bloated or slow compared to how small or fast it might have been. If it did what it needed to do, and the architecture was friendly enough to make C a viable option it might not have made sense to bother optimizing it further.

I think so.

Yes, but if it is not friendly to anything else either it is not the sort of thing I have talked about. Sure there are crazy architectures done as experiments by students, built with tinker toys or whatever, or that use one opcode with memory locations that perform ALU operations. And they are going to be pretty unfriendly to programming in general.

Of course. A one-bit one-opcode processor might be fun for some student to design, but it is not likely to be very friendly to any programmers.

If you look only at architectures that are friendly to C it might be easy to think that if an architecture is not freindly to C that it is just not friendly to programming.

But that isn't true where I live as I have worked on a lot of Forth machines. We tended to think that Forth programming was easy and friendly. And we wanted to have easy to program and fast and cheap hardware too. And we didn't need all the things that a processor needs to be friendly to C to be friendly to Forth.

Without going to what an architecture needs to be friendly to GCC and sticking to the embedded and tailored C on PIC there is still a list of what C needs. And that list is very different than the list of say what Forth needs.

If you have the minimum hardware that you need for C you can do a good Forth. But if you have the mininum hardware that you need for a good Forth it may be well below the level of the minimum hardware that you need for an architecture to be C Friendly.

Consider that the inventor of Forth says two stacks are essential and that addressable registers are nice if you can afford them (since they are more architecturally expensive than stack registers) and that Forth is word oriented both semantically and architecturally. So it only needs word addressing, while C wants bytes.

Since Forth only needs stacks which can be fast LIFO registers, not stack frames with pointers into slow memory and arrays for locals as typcially done in C, hardware stacks that resemble those on a PIC are perfectly friendly for Forth but not for C.

And if the instruction set of the processor are the primtives in the Forth language so that instead of needing dozens of words of memory and many processor cycles to execute each Forth primitive they become tiny native opcodes then the code can become very dense, very fast, and the architecture can be low cost and low power. And it just can't get much more language friendly than to have 80% of a language directly mapped to native opcodes. Compilers and applications get really small and simple that way. Yet that same architecture that is as friendly as possible to one language is also seen as very C unfriendly.

So while I would acknowledge that not being C friendly does in some cases mean not being software friendly at all. But I would also point out that in the sort of cases that I talk about, from the perspective that I talk about, being C friendly is not the same as being software friendly at all.

We tend to think that for the sort of programs that we write that Forth programs on Forth hardware is about as simple and friendly as language/architecture can get.

We also think that it takes quite a lot in comparison to make an architecture C friendly. What makes something cheap and fast and easy to program in Forth might make it rather unfriendly to a C software approach.

People tend to forget how much effort was required by how many people for how long on both the hardware and software over the years to allow programmers to use GCC with a minimal amount of effort on their part. Once the money has been spent, once you have learned it, once it becomes a habit and a comfortable tool you tend to forget that it became friendly because of a lot of effort in the past.

Reply to
fox

That's kind of the path I have been on, new embedded stack architectures not the antique mainframes. But since stack registers can be inherently faster than randomly addressable registers in an instruction set and make it cheaper and lower power too we think they are a good match for embedded use.

Example, Intel got 64MHz register access using deep pipelines on the Pentium in .8u technology using superior transistors to those in the .8u technology that we were using, and we had 500MHz stack register access. The main reason for that difference in speed was the lack of register address decode in stack based instructions.

Reply to
fox

Huh?

Unless I'm misunderstanding something, we're not talking about the platform that the C compiler runs on. That's of no interest (to me). We're talking about the target it compiles for.

As for "it is becoming an option more often to take the library and file system and OS from development platform to the embedded target with the minimal effort" - if you're talking about embedded PCs, fine. Again that's of no interest to me, and I don't see how it's relevant to this thread.

Steve

formatting link

Reply to
Steve at fivetrees

Why? I've used GCC for a number of embedded targets ranging from the low end of the 6811 up through the MSP430 and H8/300 to the ARM. GCC works perfectly fine for embedded use, and is far better than some commercial cross-compilers I've used.

What do the library and file system have to do with it?

No more than you would be thinking of using any other compiler.

I've never run across anybody like that.

--
Grant Edwards                   grante             Yow!  I'm EMOTIONAL
                                  at               now because I have
 Click to see the full signature
Reply to
Grant Edwards

... snip ...

For many architectures there is little point in even trying to implement an HLL. However it is still possible to use one to organize the code, which will necessarily be in assembly. For this purpose you can either simply use the HLL purely as descriptive commentary, when its accuracy doesn't much matter, or try to make that high level description compilable on something else. In that latter case you want a language with the maximum security, such as Pascal, since C won't catch many of your errors due largely to its extremely loose typing. I call the last step of this technique hand-compilation. It helps if the compiler is facile with the end assembly language.

--
 Some informative links:
   news:news.announce.newusers
 Click to see the full signature
Reply to
CBFalconer
[...]

I've been using a 32 bit processor with MMU running Linux as a fairly deeply embedded processor for years. The source is 100% compilable with the PC (development system) as a target, and about 80% functionally portable between the development system and the actual embedded target. I think that's what he means.

And yes, the development system for the processor was the starting point. Axis provides a stable starting point, royalty free tools and Linux and GCC ports.

The target filesystem and minimal user space (mostly BusyBox) on the embedded target would not be suitable for a PC, and I don't think that was an argument.

Reply to
Bryan Hackney

Oops. It's late. I used the term "development system" to mean different things. The first instance should have read "host system" and the second instance should have read "development board and associated s/w".

Reply to
Bryan Hackney

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.