Hello,
has anybody expierienced with the Realview Compiler (ARM) and C++ interrupt programming? How can I call an non static method as a interrupt handler? I use ATMEL AT91SAM7 controllers. It's not easy if one has just started to learn C++ at all ... (the reviews I found haven't helped me much).
How can I call an non static method as a interrupt handler?
Do you have to use a method as an interrupt handler? Won't a plain function do?
The following is an example of what I use on an the STR711Z2 (STmicro ARM 7)
As Per states you will need to call 1 C or Assembly language function that saves your context properly (i.e. ceic_irq_function). If ALL of your interrupt routines are in C++, you could call the ceic_IRQhandler as your single IRQ_HANDLER. I am sure this could be easily adapted to your ARM processor.
As for myself, I have found C++ to allow me to make my code smaller (yes, I said smaller) as well as more likely to be correct algorithmically. ( I have certainly written code that does not work in both C and C++ and still can, but I find it easier to do correctly in C++ than C)
I am not trying to start a war here. If you prefer C that's find and you should stick with C. No reason you can't provide the same functionality, just in a different way. I just sometimes find people claim C++ has "issues" in ways that it really does not. And sometimes these so called issues are actually strengths of the language.
#include "callback.h" // Callback definitions #include "eic.h" // ux types and STR eic library defs // that is all the includes class devCeic { public: devCeic() {}; static void setHandler(IRQChannel_TypeDef channel, CallbackBase<void> *callback, u16 prio = 1, FunctionalState NewState = ENABLE); static void setConfig(IRQChannel_TypeDef channel, FunctionalState NewState); static void setPriority(IRQChannel_TypeDef channel, u8 prio) { EIC_IRQChannelPriorityConfig(channel, prio); }; static void setIRV(void *irv) { EIC->IVR = (u32) irv; }; // static CallbackBase<void>* operator[] (u16 channel) { return vectors[channel]; }; friend void ceic_IRQhandler(void) __irq; private: static CallbackBase<void>* vectors[32]; }; extern devCeic CEIC;
void ceic_IRQhandler(void) __irq { u16 vector; vector = EIC->CICR; //determine vector // Enable and save IRQ nesting here if desired if (devCeic::vectors[vector]) (*devCeic::vectors[vector])(); // This is a none static member function call // i.e. call to a member function of a specific instance of an object // Interrupt routine has no knowledge of the object // other than the member function to be called takes no parameters // Called member function has full knowledge of the instance of the object, because it is the object EIC->IPR = 1 << vector; // acknowledge interrupt }
The following link gives one definition for the Generic Callback class. It is worth the time to go through it and understand it (complexity rating of 5 out of 10). Understanding means you can define templates that handle callbacks that return a value of a generic type and handles anywhere from 0 to at least 2 parameters.
www.gotw.ca/.../083.htm
"implicit type conversions can lead to unexpected program behavior."
This is basically the operator overloading I'm talking about. Elegance dictates that overloading should be invisible. When talking about performance or interrupts, invisible "extras" can be dangerous. This isn't so much a problem with the language. I think it is more a question of experience to not always do it the academic way and strive for maximum elegance. Sometimes it helps to make operations visible. In an performance-oriented world, you do not want to have to single-step in the debugger to be able to understand the code.
"using arrays polymorphically will destroy and program."
Some object-oriented languages solves this elegantly by not allowing you to create arrays of objects - just arrays of primitive data types or arrays of pointers. A very academic solution that may result in millions of memory allocations. And since they don't like pointers, the call them references and let the garbage collector solve the problem. It looks elegant, but consumes many, many extra MW of processing power. The people who complains about TVs left in stand-by should probably take a closer look at the power consumption of todays PCs, and what percentage of the power that is lost because of programming languages or how the languages are used. I have programs that can consume more processor instructions/second when I move the mouse cursor over their icon in the menu bar than my old dual-processor P90 could peak.
A C++ program with heavy use of operator overloading etc can be such a wasteful program. But a C++ program may on the other hand be just as lean as a C program. I think that is one of the advantages of C++. Since it was originally designed to be a direct superset of C, the developer may decide how to use it. In a PC environment, you may go for smart pointers to get similar behaviour as the garbage collect of Java. In a tiny embedded environment, you may write C code with very limited objectification.
But the rule is the same as for any other language: You are expected to know your tools. And you are epxected to know _why_ a specific code construct works. It is the "magic black boxes" that will hurt.
I suspect that the 'C' programmers that make such claims are very much like the assembler programmers who assume that all 'C' code is inherently bloatware.
And I also suspect that the same 'C' programmers that so vehemently defend 'C' against such ill-founded acusations from ill-informed (or just antagonistic?) assembler programmers are the same ones that make the similar accusations against C++...
But I am just a 'C' programmer, so I can't see it from the C++ programmer's viewpoint...
Not necessarily. It just so happens that for a many (most?) embedded applications C is the best tool for the job.
I have worked with C++ in the past. I have made up my mind based on my experience and quite some reading.
Mike and Tamir, you guys should stay with what you are comfortable with. There is nothing more detrimental to a project than someone coding in C++ that would really rather code in C.
I find C++ to be an excellent choice for embedded applications. This would be based on experience. I would be interested to know what bad experiences any of you have had with C++. Maybe you should consider these as learning experiences. Identify the mistakes that were made and don't do them again. I am sure this is how you became "good" C programmers. I am also 100% certain it was not the C++ language itself that caused your issues and that using the C language in itself would not have solved them.
Thank you for all your answers,
to be honest, it was not my intention to start a general discussion on C++ or C programming. However I notice that there is a big interest in this. Sometimes I also wonder what is better. But since I am requested to program in C++ at work there's no real choice. Scott Meyers says C++ should be seen as a combination of languages (which includes C, Object Oriented C++ Template C++ and STL). The rules can change if you change from one "sub-language to another". I think this is exactly where the problem lies. With langauges like Java there was a clear cut to a completely new language. Another problem lies in the many possibilities of the language. When you are a beginner you don't know where to start learning to get the most for your applications. Another thing is that there are (at least to my knowledge) no books about C++ for embedded systems, which show how to solve specific problems of embedded systems (not repeating basics already covered many times elsewhere). I know there are books with embedded C/C++ in the title but there isn't much C++ really in them.
To come back to my original intention - to discuss interrupt implementations of embedded systems (ARM7/9 etc.) controllers:
I have found the following article about interrupts: " href= "http://www.freewareweb.com/cgi-bin/ftpsearch.pl?t=n&l=en&q=ftp.embedded.com/pub/2001/c"> www.freewareweb.com/.../ftpsearch.pl
I didn't get it to work with the realview compiler yet. I tried to strip it down and managed to compile but not to link.
Another article can be found at: www.ddj.com/.../184401485
I have implemented my own simple version to call a non static member from an interrupt useing a me method pointer (initialized with the this pointer at the constructor) as described in the article above. Before I knew how to do it I studied Michael Melkonian's comment which can be found at: www.ddj.com/.../184401534
Best wishes and a happy new year to all of you,
Oliver Debus
View all questions in Keil forum