We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I rarely ask questions on this forum, but since I couldn't [easily] find it in the help-files, or on-line, I'm asking you guys.
I usually (like never) don't use the 'reentrant' pragma, but I think I may have to do that with a particular routine.
BUT I can't find the key-word that declares a function as reentrant. Am I missing something? Is there one for Keil's IDE tools? If so, what is its form? Can I get a link to the 'official' use of it?
Thanks in advance, and I need it asap because I need to pass this class and I don't want to really learn how to do this 'embedded' stuff anyway but the teacher keeps hounding me.
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
No, Mr. Sprat. For the compiler, the possibility of recursion implies reentrancy. It's as simple as that. Hence, standard-compliant C compilers must produce reentrant functions by default.
It's basic logic, really: (recursive function calls allowed) -> (functions must be reentrant). Since you like using your brain, this should be very obvious to you.
When you start from a false premise you sure can come to a lot of wrong conclusions!
Feel free to retract your snide comments now.
I think I'll stick with them, thanks.
What troll started this thread?
Zeusti/
Always our freind, and yo'rs and yo'rs
When you start from a false premise you sure can come to a lot of wrong conclusions!<p>
The premise is "Recursive functions are permitted". Andy quoted the relevant part from the standard. If you're going to dispute that, you'll have to come up with a little more than jumping in circles and yelling "it's false, it's false!". Nebulous assertions don't make any argument at all, Mr. Sprat.
In that case, just keep making yourself ridiculous. You're doing a such a fine job.
=>allows non-standard pragmas to be issolated and documented well<=
Sorry for that, I am confused.
non-standard to ARM calling convention? or non-standard to C standard?
As I tried to say (in a previous post in this thread), in the embedded world many of the 'standards' cannot be easily implemented by the 'lesser processors' like the 8051.
So the compiler companies will sometimes deviate from the standard and require special pragmas or compiler/linker switches to allow for the code to generate full compliance. I am aware of this, and the processor limitations, and the challenges of compiler vendors, so in 'my book' it is a "cautionary" issue because of what Leandro Gentili said. (He said it very well too).
I also tried to say that sometimes a design is either optimized and changed. this can include the processor itself. "C" is fairly transportable from processor to processor, and can be 'transported' into VHDL for FPGA/ASIC needs.
If your software is organized properly, these transitions can be more easily handled *IF* you are aware of these potential issues.
I was the 'troll' that started this thread. *They* expanded it. The answer came after the 3rd reply by Robert McNamara.
Note that in one way, reentrant can be seen as less than recursive or more than recursive.
Recursion means that the same execution thread may call the same function again - directly or with a number of other function calls in-between.
A reentrant function can have multiple visitors from multiple call chains - such as a RTOS performing a task switch inside the function, and letting a new thread call the function at the same time.
A reentrant function would be expected to allow recursive calls, but a function that allows recursion may not be able to support reentrant calls.
A recursive function can control where it is, when it invites itself to further recursions. A reentrant function may be anywhere where a new thread tries to enter the function. The asynchronous events of a reentrant function is similar to signal handlers or interrupt handlers.
Recursion is just a question of stacks, and saving used registers. With a reentrant function, you may also have problems that the compiler creates code sequences or calls helper functions that are not atomic and where you may not call the function again during this code sequence.
The standard is way more clear about recursion than it is about reentrant functions.
The compiler vendors normally generates reentrant code, and leaves it to the developers if we call any non-reentrant RTL function or are playing with static data or simmilar.
The big problem is that compiler vendors don't spend any real time describing their generated code, and any use of helper functions for FP emulation, or arithmetic of 64-bit numbers or similar. They don't explicitly tells us what is, and what isn't reentrant.
In the end, a lot gets down to beliefs, trust, hope, prayers, ... and is one of the reasons why embedded developers so often spend time now and then reading through the generated code. It is also a reason why you may have to certify not only your product but also your development tools.
I now know why you're first name is Per.
Perfectly stated.
oops...
your not you are (you're) ... (not grammar checked)
We are just dieing to know what the false premise was, Jack.
I guess I should catch this opportunity. (Sorry for my limited English ability.)
Stage-A: You have processor-A and compiler-A, these are able to support A1/A2/A3. Stage-B: Then, you downgrade your processor to processor-B, and get a compiler-B, these are able to support A1/A2, but do not support A3.
So, at Stage-A, you write down a cautionary about A3, and isolate A3.
But how do you know that processor-B/compiler-B do not support A3, at Stage-A? Do you have a processor-Essential and compiler-Essential as a Standard?
John Linq, that is a very good question. Its a hard one, and I chose to 'ramble' about it since it is indeed a good question.
Stage-A: You get a good idea of what the project is and how far it is expected to go... is it a one-off? is it going to sell 50 units per year?, 500,000/yr?
Ah... it will go to 250,000/yr for about three years at peak production, but before you get there, you'll need to get some funding, so you need to do a Proof of Concept. Build five prototypes for a "dog-and-pony show" and you'll get funded for the low-rate initial production (LRIP) at 5-10k/yr (enough for 'marketing to begin'), and if that goes well, they'll ramp you up as soon as possible to 250,000 units/yr. Of course that LRIP design will have to be cheaper than the prototype, so you start the cost reduction phase.
Hmmmm. Pick the processor you know that will eventually get you into an FPGA and migrate over to an ASIC. The prototype looks like you'll need the power of an ARM processor. But knowing that you can parallel process in an FPGA, an 8051 style core can handle the sequential throughput needs. The smaller processor has a small footprint on the fabric, and you'll be able to put all of those 'other' chips into it with room to spare.
Stage-A1: Off-the-shelf ARM processor. Build prototype. Impress the money people.
Stage-A2: Demonstrate the ability to get it into LRIP with a 'cheap' version
Stage-A3: Start the conversion over to the high-rate production: FPGA
(You've chosen a reputable compiler like Keil, and not some 'freeware' un-verified brand).
Stage-B1: The ARM is no longer 'needed' and an 8051 will do it. Its in "C" so those 'functions' are now sub-components within the FPGA, and the Serial Processing requirements are now to be implemented on a stripped down 8051 core.
Fortunately, you've written your source modules so that this process can be done so that software-routines can become hardware circuits, and the 'need' for serial processing is also isolated. Nice and tidy.
Hmmmm... ARM to 8051? Oh gee, that whole stack issue and reentrancy is starting to look like a problem. Almost makes you wonder if that transition will go smoothly... after all it is in "Standard C."
Well, then there is that whole host of caveats in order to fully implement the new processor. They call them "#pragma."
Oh, that's right... its right there in that isolated module, and specially identified potential "cautionary" issues per the book's section on "things to be careful of before you start monkeying around."
Stage B2: Your FPGA prototype is done and ready. You've been qualified and your investment people are convinced that it wll work and so they dump the big bucks into ramping up to the 250,000 units per year... maybe more? But you know that the market will demand a cheaper product and fast. You'll have to go full ASIC soon. The market might explode.
Stage B3: Since you were so darned careful making that "C" to HDL conversion, now all you have to do is work with an ASIC vendor and make sure the HDL is good enough for them to build an ASIC.
Stage C1: Big Bucks, and ASIC Prototype 1 Almost works... It failed a tiny little feature, and the investor's lawyers don't like it.
Stage C2: More Big Bucks, and ASIC Prototype 2 works and passes all qualification testing.
Stage C3: Your widget has ramped up to over 125,000/yr and demand is climbing fast. Your investors want more money (funny how that is), and now you can release the cheaper version while the competition is still in Stage A3.
Stage D1: You've dominated market share, gotten enough feedback, improved the design on the ASIC with Version 3. It is now "Productions" project, and now its time for you to work on another project.
This NEW project is low rate. You pick a processor that can do the job and is cheap enough. You'll never really change the processor until five years from now when *that* processor is no longer available. You pick another one in its class, (it wasn't your choice. Your boss thinks it is the best one to use, and you are now forced to use it because he can get a 'deal' on the first 2000 processors, which will last the company for another five years). But its not supported by your current IDE! Its only supported by *that* processor vendor's compiler. So you buy another compiler.
Good thing you've separated out your code properly: the *new* IDE requires lots of #pragmas to comply with "The Standards," but since you already know which ones are 'potentially' or 'likely' needed by other processors and other IDEs, it has also been isolated and well documented.
Weird how that happens.
Ramble factor: I don't care.
The premise is "Recursive functions are permitted".
Oh dearie me, no it isn't. I have never disputed that, only pointed out that it is irrelevant.
Here's your post again - take note of the premise at the beginning from which you go on to derive your conclusions:
Seems pretty clear to me.
Nebulous assertions don't make any argument at all, Mr. Sprat.
No, they don't, do they?
You mean the part about the compiler being compliant to the C standard? If the compiler doesn't comply to the C standard, then the points in which it deviates from it must be mentioned in the manual (e.g. C51 and its "reentrant" keyword). Deviations from the standard that aren't mentioned in the manual are bugs in the compiler.
Oh ... and wasn't it you who claimed that Cpt. Vince was missing basic computer science knowledge, since he was looking for information about reentrancy in the compilers manual and couldn't find it? If there's nothing mentioned in the manual, then the standard applies. And the standard requires the compiler to create reentrant functions.
Many Thanks to Captain and Per for the detailed explaination.
You mean the part about the compiler being compliant to the C standard?
No, I made it quite plain that I was referring to the premise at the beginning of you post, which was:
the possibility of recursion implies reentrancy.
This is incorrect as are the things you go on to conclude from this statement.
Oh ... and wasn't it you who claimed that Cpt. Vince was missing basic computer science knowledge, since he was looking for information about reentrancy in the compilers manual and couldn't find it?
Yes, and my point was that reentrancy is a concept rather than something which must exist as a compile time option.
If there's nothing mentioned in the manual, then the standard applies.
Yes.
And the standard requires the compiler to create reentrant functions.
No.
Oh, and now that I have learned this 'basic computer science knowledge' from the Fish-Head, you can see how difficult it is to ensure that a "rule-book" is clear enough so that someone of Jack's caliber doesn't screw up a project.
Malice Factor: > 0
Recursive calls imply concurrent execution of the function in question. Concurrent execution is a synonym for reentering a function. Whether or not the concurrent execution is done from separate threads or from the same thread is irrelevant.
Mr Sprat, I see you've wholeheartedly failed to read and understand my postings. I think I've made it abundantly clear the the compiler trying to create reentrant functions is a necessary, but not sufficient condition for any particular function to be reentrant (that's also basic logic, you should know what those terms mean).
Hence, it is impossible to create a (meaningful) recursive function with a compiler that does not consider functions reentrant (such as C51).
I really don't think I need to, since you can undoubtedly read, but if you consider it necessary I'll show you the appropriate passages from my earlier postings.
Yes. It is not possible to broadly allow recursive functions (as the C standard does) without the compiler considering all functions reentrant by default and making the appropriate provisions.
We're getting close to the point here where I'll start considering more nebulous, unproven statements from you as a concession.