I am using an 8051 (C51/BL51) with no off-chip memory. I have two functions with parameters:
void Detect( U8 iLed )
and
static U8 INHSampleHandler( U16 u16Sample )
Now I understand that Keil will allocate a variable (in DATA) for these. The problem seems to be that the locator is using the same memory location for both. I cannot understand why.
Below are excerpts from the scratchpad showing 2 "D:0026H". These are the only places these symbols are declared. Any ideas what I'm doing wrong?
Thanks, Jeff
BL51 BANKED LINKER/LOCATER V5.12 07/14/2011 09:36:23 PAGE 1 BL51 BANKED LINKER/LOCATER V5.12, INVOKED BY: Z:\TOOLS\SOFTWARE\KEIL\BL51.EXE Z:\Software\FB_CPU_Init.obj, >> Z:\Software\Settings.obj, Z:\Software\Glo >> bals.obj, Z:\Software\Devices\Clock.obj, Z:\ >> Software\Devices\Flash.obj, Z:\Software\Devices\HMI.obj >> , Z:\Software\Devices\INH.obj, Z:\ >> Software\Devices\ADC.obj, Z:\Software\Devices\Timer.obj, Z >> :\Software\Builds\TestINH - 06-00039-21-09\Main.obj >> , Z:\Software\Test\Test_Button.obj, Z:\So >> ftware\Builds\TestINH - 06-00039-21-09\Version.obj TO Z:\ >> Software\Builds\TestINH - 06-00039-21-09\06-00039-21-09-xx.wsp >> RS (256) PL (68) PW (78) XDATA (?XD?SETTINGS (0X0)) CODE (?CO?VERSION (0X7 >> FC0)) MEMORY MODEL: SMALL Deleted for brevity ------- PROC _INHSAMPLEHANDLER D:0026H SYMBOL u16Sample C:0BF1H LINE# 150 C:0BF5H LINE# 151 C:0BF5H LINE# 207 C:0BF7H LINE# 208 ------- ENDPROC _INHSAMPLEHANDLER ------- ENDMOD INH Deleted for brevity C:09FEH PUBLIC _Detect C:074EH PUBLIC main ------- PROC _DETECT D:0026H SYMBOL iLed
If the two functions aren't calling each other and the compiler/linker can see that the two variables will never be needed at the same time - what is then wrong with optimizing the memory usage by using the same space for the two variables?
I see. In my case one of these functions is called by an ISR. So I changed my function declaration to
static U8 InhalationSampleHandler( volatile U16 u16Sample )
and now the locator keeps the data separate. Any idea if this is a guarantee that the linker will do the right thing?
Thanks for the help.
The linker builds its call tree and don't think the Sub2 and Sub1 overlap. But obviously they can.
The problem is precisely that that is not at all obvious to the linker. Static call tree analysis pretty much always fails as soon as function pointers get involved, and deep down, it really has no chance --- there's an impossible task hiding in there, equivalent to the Halting Problem. Keil is no exception to that rule.
So what you should do is: do not call functions via pointer from inside an ISR. Not on a '51, anyway. If at all possible, avoid calling any functios from a '51 ISR, period.
If you really can't see any way of accomplishing that, see the app notes already referenced in this thread about ways to fudge the linker call tree data. And brace yourself, because this will hurt.
Hello,
You are focusing in on the wrong section of the memory map. You need to view the "overlay analysis" section
If the overlay analysis is incorrect, you can use the OVERLAY command to correct it:
http://www.keil.com/support/man/docs/bl51/bl51_overlay.htm
For example look at page 5 of this application note.
http://www.keil.com/appnotes/docs/apnt_129.asp
It explains exactly the issue you describe, a function called by a function pointer.
Page 5 -6 show how to use the OVERLAY command to tell the linker that these functions are not independent. Once the linker is made aware of this, it will not overlay those variables.
If at all possible, avoid calling any functios from a '51 ISR, period.
There's NO problem with calling a function from an '51 ISR.
However, like most tasks, the programmer needs to understand the mechanism(s) involved and take appropriate steps to ensure the cogs fit correctly.
FWIW, we have plenty of code that calls functions from ISRs. It's all written in assembler and there have been no reported problems. Quite a few of those functions are inherently re-entrant. They are called from both ISR and mainline code. Most importantly, parameters and local variables are passed in registers.
No problem, so long as you know what you're doing, period.
Disagree.
Because Keil C51 functions are inherently not reentrant (due to the Overlaying) there are potential problems with calling Keil C51 functions from ISRs - specifically, when those functions are also called from non-ISR code.
I think the Linker will warn of this: http://www.keil.com/support/man/docs/bl51/bl51_l15.htm
So, as a blanket statement, I think "There's NO problem with calling a function from an '51 ISR" is less helpful than, "If at all possible, avoid calling any functios from a '51 ISR, period"
There is also the general issue (not specific to Keil or the 8051) that ISRs should generally be "short and sweet" - and calling functions generally indicates that the programmer has forgotten (or not understood) this...
both of you are correct - with IB being more correct.
it is true that calling a function from within the isr should be avoided as much as possible. but that's not always possible, and I would further state that it is unlikely to be possible if you are relying pre-made code modules.
in that sense, IB is more correct that you can do the undesirable / risk thing of calling a function from within an isr, as long as you know what you are doing.
sometimes, it is optimal to do the sub-optimal thing.
I think it is unhelpful to say, "There's NO problem" with the big emphasis on the "NO" like that.
Especially as the forum has many novice/inexperienced readers - who might take that at face falue. (in fact, it sometimes seems that the novice/inexperienced readers are the majority)
There most certainly are problems to be considered - so, again, the emphatic "NO" is unhelpful.
True, the problems will not be significant in some designs but, again, just saying there are "NO" problems is unhelpful.
H-B B did, at least, qualify his statement with "If at all possible" and "avoid".
Can't you just hear the novice/inexperienced 8051 programmer posting,
"I read that there is NO problem with calling a function from a '51 ISR - so why do I get this L15 warning?"
"who might take that at face falue."
sounds like poor programmers, rather than the message itself, are the problem.
then the real cure is to educate the programmers or let them suffer through prolonged debugging to learn their mistakes is the solution.
rather than bastardizing a perfectly correct and reasonable message.
I disagree that it is perfectly correct, and I disagree that it is reasonable.
"the real cure is to educate the programmers"
Indeed - by not giving misleading statements.
"I disagree that it is perfectly correct, and I disagree that it is reasonable."
if you look at IB's statements in their totality, he essentially said that it is ok to call a function from within an isr, as long as you know what you are doing.
he may not have put the two statements physically next to each other, but I think if anyone were to think the two in separation, s/he has a deeper problem, with comprehension.
"Indeed - by not giving misleading statements."
people learn a lesson far better if they experience it in a painful way.
unless you can shield everyone from every misleading / less-than-truthful statement, it is probably to their interest for them to learn to identify and interpret such statements on their own.
you are talking out of both sides of your mouth. Here you say "let them suffer" in other places you criticise that a solution is not provided.
Erik (who is not afraid of putting his name to his statements)
"unless you can shield everyone from every misleading / less-than-truthful statement, it is probably to their interest for them to learn to identify and interpret such statements on their own."
You don't seem to know what foot to stand on. In this case, it's "close enough". In other threads, you are willing to spend hours fighting for the use - or nonuse - of a single word.
"Erik (who is not afraid of putting his name to his statements)"
how heroic you are!
on that basis along, they should award you the Nobel prize for Bravery and two Metals of Honor (not just one!)
:)
"You don't seem to know what foot to stand on. In this case, it's "close enough". In other threads, you are willing to spend hours fighting for the use - or nonuse - of a single word."
because each case is different. while doing something is in-material in one case, doing the same thing may be material in others.
so the seeming contradiction is fairly easy to understand, if you have common sense.
As you well know, I'm not into C51. But I don't like the notion of people doing things in software that fly in the face of the processor architecture; that is asking for trouble. You may be sufficiently qualified to maintain the code, but the person that will take over in 5 years might not be; I think a better way is not being too smart. Keep it simple, straight forward and maintainable even if it costs you a few more instructions. But that's only my opinion.
View all questions in Keil forum