Discussion Forum

Locating 2 parameters at the same address

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Author
Jeff Tonkinson
Posted
14-Jul-2011 16:32 GMT
Toolset
C51
New! Locating 2 parameters at the same address

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

Author
Per Westermark
Posted
14-Jul-2011 16:44 GMT
Toolset
C51
New! RE: Locating 2 parameters at the same address

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?

Author
Jeff Tonkinson
Posted
14-Jul-2011 17:09 GMT
Toolset
C51
New! RE: Locating 2 parameters at the same address

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.

Author
Andrew Neil
Posted
14-Jul-2011 17:17 GMT
Toolset
C51
New! RE: one of these functions is called by an ISR

The Linker copes with that - or gives a warning when it can't.

Author
Jeff Tonkinson
Posted
14-Jul-2011 17:26 GMT
Toolset
C51
New! RE: one of these functions is called by an ISR

What I meant was, does adding "volatile" to a parameter guarantee that the linker will not overlap it with another variable. Apparently it does not.

I un-did some of my work-arounds and those variables landed back on top of each other.

I guess I don't have a lot of functions called by ISRs, so a work-around is to use global variables. But I'd rather not. Is there a "right" way to do this?

Thanks.

Author
Ashley Madison
Posted
14-Jul-2011 18:00 GMT
Toolset
C51
New! RE: one of these functions is called by an ISR

"so a work-around"

why do you care, as long as the resulting code behaves correctly?

Author
Andrew Neil
Posted
14-Jul-2011 18:10 GMT
Toolset
C51
New! RE: "workarounds"

You seem to be trying to work around a problem that doesn't exist!

What the tools are doing is called Overlaying - it is a very well-established technique for getting around the fact that the 8051 has no stack suitable for the usual parameter passing & automatic variables.

Effectively, Overlaying does at link-time what "normal" compilers do with the stack at run-time.
It does mean that parameters share memory locations - hence the name, "overlaying" - but exactly the same is true when a "normal" compiler uses the stack!

There's information in the knowledgebase; eg, the Application Note about function pointers discusses it - because it has a big effect on the use of function pointers...

Author
Andrew Neil
Posted
14-Jul-2011 18:18 GMT
Toolset
C51
New! RE: "workarounds"

http://www.keil.com/appnotes/docs/apnt_149.asp

http://www.keil.com/appnotes/docs/apnt_129.asp

http://www.keil.com/support/man/docs/bl51/bl51_ol_fp.htm

http://www.keil.com/support/docs/1026.htm

Author
Jeff Tonkinson
Posted
14-Jul-2011 18:34 GMT
Toolset
C51
New! RE: "workarounds"

I don't see the relavance of this to my issue of overlaying parameters.

It is true that my ISR is calling the function by pointer. So it is necessarily passing the one parameter on the stack. Rather than leave this parameter on the stack, the compiler copies it into its DATA location. Unfortunately that location is overlayed with another, unrelated, function parameter.

Thanks.

Author
Erik Malund
Posted
14-Jul-2011 19:13 GMT
Toolset
C51
New! the linker has a real problem with ...

I don't see the relavance of this to my issue of overlaying parameters.

It is true that my ISR is calling the function by pointer

The linker has a real problem with resolving the call table when functions are called by pointers.

I have, realizing how cumbersome function pointers are in the '51 architecture, avoided function pointers totally when working with the '51, and can thus not answer with a link. However from other posts I know there is something in the documentation about how to resolve this issue by special linker usage.

Erik

PS note "how cumbersome function pointers are in the '51 architecture" not the tools, although as seen above, that is true too.

Author
Erik Malund
Posted
14-Jul-2011 19:16 GMT
Toolset
C51
New! there is a simple workaround

global bit blah = 0

in the ISR:
if (blah)
{ function_that_is_called_by_pointer();
}

Erik

Author
Erik Malund
Posted
14-Jul-2011 19:33 GMT
Toolset
C51
New! RE: there is a simple workaround

at least do it as 'proof'. If that does not remove the overlaid variable, you will need to post code

Erik

Author
Jeff Tonkinson
Posted
14-Jul-2011 18:26 GMT
Toolset
C51
New! RE: "workarounds"

Yes, there is a problem. While the linker is correctly overlaying parameters, I don't want the linker to overlay the parameters for a few of my functions. The reason being that these functions are called by an ISR. So a parameter in use by one function gets overwritten by an ISR-called function because the linker overlayed the two parameters. Very bad.

So the question is, how do I instruct the locator to not overlay the parameters for these particular functions?

Author
Ashley Madison
Posted
14-Jul-2011 18:57 GMT
Toolset
C51
New! RE: "workarounds"

"So the question is,"

maybe you can post a short but complete piece of code demonstrating this problem you are facing. if you are right, you have identified a huge bug in the compiler and everyone of us could benefit its airing.

so post the short piece of code you can that demonstrate this problem of yours.

otherwise, talking theory doesn't do anyone any good.

Author
Jeff Tonkinson
Posted
14-Jul-2011 19:39 GMT
Toolset
C51
New! RE: Concrete Example

I was trying to avoid lengthy code, but here is a concrete example that demonstrates my point.
Here is the code:

#include "compiler_defs.h"
#include "C8051F930_defs.h"


void Sub1( U8 SubVar1 )
{
        SubVar1 = SubVar1 + 1;
}

void Sub2( U8 SubVar2 )
{
        SubVar2 = SubVar2 + 1;
}

void main(void)
{
        while(1)
        {
                Sub1( 13 );
        }
}


static void ADC_ISR(void) interrupt 10
{
        U16 u16Result = 12;
        Sub2( u16Result );
        ADC0CN &= ~0x20;
}

And here are excepts from map file:

BL51 BANKED LINKER/LOCATER V5.12              07/14/2011  13:32:43  PAGE 1


BL51 BANKED LINKER/LOCATER V5.12, INVOKED BY:
Z:\TOOLS\SOFTWARE\KEIL\BL51.EXE C:\Users\JeffT\Documents\Temp\Main.obj TO C:\U
>> sers\JeffT\Documents\Temp\Main RS (256) PL (68) PW (78)


MEMORY MODEL: SMALL

  -------         PROC          _SUB1
  D:0007H         SYMBOL        SubVar1
  -------         ENDPROC       _SUB1
  -------         PROC          _SUB2
  D:0007H         SYMBOL        SubVar2
  -------         ENDPROC       _SUB2

The linker builds its call tree and don't think the Sub2 and Sub1 overlap. But obviously they can. When the ISR fires Sub2 will overwrite Sub1's value. I can turn off the variable overlaying entirely, but that would be a waste. I suppose most people don't call functions from within ISRs. I have my reasons for doing so.

Any ideas?

Author
Ashley Madison
Posted
14-Jul-2011 20:12 GMT
Toolset
C51
New! RE: Concrete Example
SubVar2 = SubVar2 + 1;

changed that to:

SubVar2 = 0;

and

        SubVar1 = SubVar1 + 1;

to

        SubVar1 = SubVar1 + 1; P2=SubVar1;

so if subvar1/subvar2 are indeed overlaid, you will see that subvar1/subvar2/P2 maintains 13 and then periodically (as the isr 10 is fired) gets reset to 0.

if the two variables are not overlaid, you will see P2 maintaining a value of 13.

I tried to use tmr0 isr and I got a constant value on P2.

Author
Hans-Bernhard Broeker
Posted
15-Jul-2011 23:25 GMT
Toolset
C51
New! RE: Concrete Example

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.

Author
IB Shy
Posted
16-Jul-2011 09:49 GMT
Toolset
C51
New! RE: Concrete Example

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.

Author
Andrew Neil
Posted
16-Jul-2011 11:03 GMT
Toolset
C51
New! RE: There's NO problem with calling a function from an '51 ISR.

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...

Author
Ashley Madison
Posted
16-Jul-2011 11:43 GMT
Toolset
C51
New! RE: There's NO problem with calling a function from an '51 ISR.

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.

Author
Andrew Neil
Posted
16-Jul-2011 12:02 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

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".

Author
Andrew Neil
Posted
16-Jul-2011 12:06 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

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?"

Author
Ashley Madison
Posted
16-Jul-2011 12:19 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"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.

Author
Andrew Neil
Posted
16-Jul-2011 12:35 GMT
Toolset
C51
New! RE: 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.

Author
Ashley Madison
Posted
16-Jul-2011 12:47 GMT
Toolset
C51
New! RE: a perfectly correct and reasonable message

"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.

Author
Per Westermark
Posted
16-Jul-2011 12:53 GMT
Toolset
C51
New! RE: a perfectly correct and reasonable message

"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.

Author
Ashley Madison
Posted
16-Jul-2011 12:59 GMT
Toolset
C51
New! RE: a perfectly correct and reasonable message

"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.

Author
Andrew Neil
Posted
16-Jul-2011 13:02 GMT
Toolset
None
New! RE: You don't seem to know what foot to stand on

Indeed!

One moment, you're criticising fine detail and ignoring the context; then, just to be contrary, you decide to do the opposite!

Make up your mind!

Author
Ashley Madison
Posted
16-Jul-2011 13:12 GMT
Toolset
None
New! RE: You don't seem to know what foot to stand on

"One moment, you're criticising fine detail and ignoring the context; then, just to be contrary, you decide to do the opposite!"

I thought I had answered that, in the post that yours above responded to.

but in case you missed it, sometimes fine details matter, and in other cases, they don't.

so it is hard and wrong to insist that one always pays attention to fine details - they are called "fine details" for a reason.

hope it helps.

Author
Andrew Neil
Posted
16-Jul-2011 13:28 GMT
Toolset
None
New! RE: You don't seem to know what foot to stand on

Making a bold statement like "There are NO problems" - with the big emphasis on the NO - is not a fine detail. It is plain wrong.

Author
Ashley Madison
Posted
16-Jul-2011 13:36 GMT
Toolset
None
New! RE: You don't seem to know what foot to stand on

this is exactly what IB wrote:

'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.'

vs. what you characterized what he wrote:

"There are NO problems"

come on. would any reasonably intelligent people equate the two?

as I stated before, the two of you said the same thing, with different emphasis. and there is no point in pushing any of your statements to the extreme to justify the other.

Author
IB Shy
Posted
16-Jul-2011 18:23 GMT
Toolset
None
New! It is plain wrong. Opinions, opinions.

"Making a bold statement like "There are NO problems" - with the big emphasis on the NO - is not a fine detail. It is plain wrong."

Well, thanks for that vote of confidence ;)

However - I do not believe it is wrong at all. There aren't any problems - So long as everything about the situation is understood. Nothing specific about '51 architecture there.

If I were to say that there were no problems with boiling an egg I guess I'd get a complaint from someone pointing out that it shouldn't be done because someone might leave the gas on and the house might burn down.

Author
Erik Malund
Posted
16-Jul-2011 12:52 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

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.

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)

Author
Ashley Madison
Posted
16-Jul-2011 12:55 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"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!)

:)

Author
Tamir Michael
Posted
16-Jul-2011 13:02 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

people learn a lesson far better if they experience it in a painful way. (Asheley)

That is often not an option in the commercial world...

Author
Erik Malund
Posted
16-Jul-2011 13:41 GMT
Toolset
C51
New! no award wanted

"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 want to hide your spewing bile behind anonymity, I am, at least, willing to stand behind what I post.

Erik

Author
Ashley Madison
Posted
16-Jul-2011 13:45 GMT
Toolset
C51
New! RE: no award wanted

"I am, at least, willing to stand behind what I post."

far more importantly, you have the bravery to put your name to your statement, as you proudly and publicly stated.

and that's just extremely heroic, and because of that and that alone, you should be the target of national admiration.

thus I think you deserve not just the nobel prize for bravery but also two (not just one) Metals of Honor!

Author
IB Shy
Posted
16-Jul-2011 15:01 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"True, the problems will not be significant in some designs..."

So how low down the significance scale exactly is no problem? I described how I have written plenty of assembler functions that were inherently re-entrant.

"...but, again, just saying there are "NO" problems is unhelpful."

But when does a professional/experienced programmer learn that what they've always been told they cannot do can in fact be done?

Saying it is unhelpful, I think, in itself is unhelpful - And doing a disjustice to budding competent future professional programmers.

There are quite a few professional programmers here. Do they think that what I suggested cannot work? If they do, then I'd (unfortunately) have to say that maybe they're not quite as professional as they think.

"Because Keil C51 functions are inherently not reentrant (due to the Overlaying) ..."

Actually, that is not totally true. If one were to take the time to read the Keil documentation, they'd learn that it is in fact possible to write inherently re-entrant functions in Keil C51 (and I don't mean by using the reentrant keyword). Of course there are limitations. The functions would generally be small, take few parameters and use few local variables - Just the sort of sensible function that could be included into an ISR.

Author
Erik Malund
Posted
16-Jul-2011 16:46 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

So how low down the significance scale exactly is no problem? I described how I have written plenty of assembler functions that were inherently re-entrant.
the thread is about C

"...but, again, just saying there are "NO" problems is unhelpful."
there are, indeed, - you say so yourself - some problems

Actually, that is not totally true. If one were to take the time to read the Keil documentation, they'd learn that it is in fact possible to write inherently re-entrant functions in Keil C51 (and I don't mean by using the reentrant keyword). Of course there are limitations. The functions would generally be small, take few parameters and use few local variables - Just the sort of sensible function that could be included into an ISR.

pray show a function that "don't use the reentrant keyword" and "use few local variables" and is "inherently re-entrant".

Erik

Author
IB Shy
Posted
16-Jul-2011 17:55 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"pray show a function that "don't use the reentrant keyword" and "use few local variables" and is "inherently re-entrant"."

Erik, I really expected better of you.

Anyway - As a starting point, take the simple/obvious example:

void foo(void)
{
  ;
}

You'd find it difficult to get fewer local variables. It doesn't need reentrant. It doesn't require any overlaying of data (simply because there isn't any).

In the past I have said to our junior trainees: "Here is the start. You have the manuals. Expand a step at a time and see how far you get".

If you have a few spare minutes, you could give it a go. The manuals really do have all the necessary information.

Author
Erik Malund
Posted
16-Jul-2011 23:10 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

my post was triggered by it is in fact possible to write inherently re-entrant functions in Keil C51 (and I don't mean by using the reentrant keyword). Of course there are limitations. The functions would generally be small, take few parameters and use few few is not none local variables

thus

"pray show a function that "don't use the reentrant keyword" and "use few local variables" and is "inherently re-entrant"."

Erik, I really expected better of you.

Anyway - As a starting point, take the simple/obvious example:

void foo(void)
{ ;
} You'd find it difficult to get fewer local variables. It doesn't need reentrant. It doesn't require any overlaying of data (simply because there isn't any).

of course not, with no local variables what I asked you to do was to show it "with a few local variables" as you stated would be no problem

Erik

Author
IB Shy
Posted
17-Jul-2011 07:54 GMT
Toolset
C51
New! Do the youth of today just want instant answers?

"of course not, with no local variables what I asked you to do was to show it "with a few local variables" as you stated would be no problem"

So I take it that you didn't pursue the finding of a solution yourself.

I did say that my little code snippet was the starting point. Just consider/remember that parameters and variables do not have to be stored in memory - Hint, no mention of registers.

Please remember, I did say in the same paragraph:

"Of course there are limitations."

And note that for this part, at least, I didn't say there would be 'no problem'.

Anyway ... I do not consider this part of the discussion to be particularly important and I'm not going to get dragged any further into it.

Author
IB Shy
Posted
16-Jul-2011 18:07 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"the thread is about C"

Yes, it is.

And that is precisely the reason why I dislike reading the statement:

"If at all possible, avoid calling any functios from a '51 ISR, period."

The budding professional might well read that and quite literally take it to assume it includes any scenario.

Author
Andrew Neil
Posted
16-Jul-2011 20:10 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

Just because you've managed to avoid the problems does not mean that there are no problems.

Just like crossing the road has many dangers - but most of us manage to do it every day by being aware of the dangers, and acting accordingly.

But saying there are NO dangers is untrue and unhelpful.

Author
IB Shy
Posted
16-Jul-2011 21:37 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"Just because you've managed to avoid the problems does not mean that there are no problems."

Andy, what problems are you talking about? I certainly didn't have to avoid any problems. There weren't any problems in what I did. Why? because I understood how the 51 works, how the assembler works, what the compiler produced, how the linker works, and what I wanted to achieve. There were no problems and no gotchas.

"Just like crossing the road has many dangers ..."

That's an extremely poor example. Processors are (in general) highly predictable. Crossing the road is totally different. You are not in control of all the variables - Most importantly there is that unknown variable sitting behind the wheel of a large mass.

"But saying there are NO dangers is untrue and unhelpful."

That seems to lack a certain amount of context. Go back and you'll see my post ended with:

No problem, so long as you know what you're doing, period.

So ... going back to the full post and full context, what I was saying is that there is no danger in doing it per se. You (and others) might consider it a danger in the context of Keil's implementation of C - But in itself I stand by what I said.

Author
Ashley Madison
Posted
16-Jul-2011 21:44 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"Just like crossing the road has many dangers - but most of us manage to do it every day by being aware of the dangers, and acting accordingly."

which of the following statement would you agree more?

1) don't cross the road (because there is danger);
2) it is OK to cross the road, as long as you understand the danger.

Author
Tamir Michael
Posted
16-Jul-2011 22:43 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

I would rephrase it like this:

"Would you like to establish a _habit_ of crossing the road at a dangerous spot for 10 other people, when you know that the risk involved is significant"?

To me, the question is not if it is dangerous or not. Risk can be managed, at least on the short term. The question is whether this is sustainable on the long term.

Author
Ashley Madison
Posted
17-Jul-2011 13:47 GMT
Toolset
C51
New! RE: There's NO (sic) problem with calling a function from a '51 ISR.

"Would you like to establish a _habit_ of crossing the road at a dangerous spot for 10 other people, when you know that the risk involved is significant"?

the answer to that would depend on many different factors:

1) if the pay-off is sufficient, I would;
2) if the 10 other people understand their risks they are taking, I would;
3) if we are prepared for the risk, we would;
...

it is stupid to say "there is risk so don't do it". we all take risks, one way or another. sometimes wisely and others not so.

there is nothing wrong with taking risks. you just need to plan out the pros / cons and be good at it. that's essentially what IB said, in a more generic form.

Author
Erik Malund
Posted
17-Jul-2011 14:20 GMT
Toolset
C51
New! not necessarily

it is stupid to say "there is risk so don't do it". we all take risks, one way or another. sometimes wisely and others not so.

It is not necessarily stupid to say "there is risk so don't do it".
There is a risk going very fast on a curvy road, to an inexperienced driver I'd say "there is risk so don't do it", to a NASCAR driver I would not.

Erik

Author
Ashley Madison
Posted
18-Jul-2011 13:53 GMT
Toolset
C51
New! RE: not necessarily

"There is a risk going very fast on a curvy road, to an inexperienced driver I'd say "there is risk so don't do it", to a NASCAR driver I would not."

but that's precisely what IB said: "there is nothing wrong with doing X if you understand what you are doing" aka your NASCAR example.

the converse of what IB said would be "don't do X if you are an inexperienced driver".

you guys really really need to improve your reading comprehension.

Author
Per Westermark
Posted
18-Jul-2011 15:12 GMT
Toolset
C51
New! RE: not necessarily

"you guys really really need to improve your reading comprehension."

So now it's "you guys"? Why the generalization? It seldom helps an argument. How much credibility would you give to the statement: "Everyone knows that all bikers are criminals"?

Author
Ron we
Posted
16-Jul-2011 04:58 GMT
Toolset
C51
New! RE: "workarounds"

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.

Author
Tamir Michael
Posted
16-Jul-2011 13:00 GMT
Toolset
C51
New! RE: "workarounds"

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.

Author
Jeff Tonkinson
Posted
18-Jul-2011 13:37 GMT
Toolset
C51
New! RE: A helpful post

Ron,

I'm the original poster here and I thank you for your post of AP note 129. While my original post didn't confess that I'm using function pointers, this clearly explains how I can get into trouble invoking (sorry, that's a C# term I've adopted) a function from a pointer. This also explains how to fix it.

I don't really follow all the discussion above regarding ISRs. Does the linker make sure that ISRs (and their associated call trees) never overlay anything else? It seems like it would have to.

Author
Erik Malund
Posted
18-Jul-2011 15:00 GMT
Toolset
C51
New! it does, except

I don't really follow all the discussion above regarding ISRs. Does the linker make sure that ISRs (and their associated call trees) never overlay anything else? It seems like it would have to.

it does, except when it runs into it's trouble with function pointers.

There is nothing inherintly wrong with using function pointers with C51 (or any code for the '51) but the mechanisms required makes it bug prone and less maintainable. Thus I (and many others) have a '51 specific coding style that avoids function pointers.

Erik

Author
Ron Wedge
Posted
18-Jul-2011 16:22 GMT
Toolset
C51
New! RE: A helpful post

Forums are good places for blanket statements, but blanket exceptions always miss caveats. If you included every caveat in the post, you would reproduce the manual ;)

an 8051 is not a re-entrant device. If you call a function with local variables, say foo(), and an ISR occurs, and calls foo() - the ISR's version of foo() could stomp on the values in Registers R0 - R7 if you are not careful.

So calling a function from both main and an interrupt, or a low priority and high priority interrupt you introduce a possible failure point in your code. It is generally not recommended - but there are situation where it will make sense.

Common workaround are (from least to most preferred):

-Create a re-entrant Stack - every time the function is called, its registered are handled by a separate stack

http://www.keil.com/support/man/docs/c51/c51_le_reentrantfuncs.htm

- Create a foo_for_ISR and a foo_for_main

- Make all variables global for that foo()

- Try to hand code the function in assembly, and attempt to put safeguards in

- Switch to a RTOS, such as RTX, and instead have the ISR send a signal, and have a task which calls foo() handle the timing.

Author
Jeff Tonkinson
Posted
18-Jul-2011 16:49 GMT
Toolset
C51
New! RE: A helpful post

I find it curious that the App Note's method (using the OVERLAY command) doesn't even make it to your Top 5 Workarounds.

Re-entrancy is not my problem. I'm not calling "foo()" from two places. The issue is that foo()'s parameters are overlaid with bar()'s parameters. And in the middle of running bar() an interrupt happens. Unbeknownst to the linker, the ISR called foo().

In my situation, where all the design and 98% of the coding is complete, the OVERLAY command seems the easiest to implement. Next next best option would be to call the functions explicitly rather than by pointer.

Author
Ashley Madison
Posted
18-Jul-2011 16:53 GMT
Toolset
C51
New! RE: A helpful post

"I find it curious that the App Note's method (using the OVERLAY command) doesn't even make it to your Top 5 Workarounds."

but why use such a simple solution when more convoluted ones exist? how can we possibly justify our existence if a simple OVERLAY command does what we can do in a month's time?

not to mention our ego for sophistication.

:)

Author
Ron Wedge
Posted
18-Jul-2011 16:57 GMT
Toolset
C51
New! RE: A helpful post

Overlay solves the 'Linker missed a relationship between 2 functions" issue.

Once you solve that - you may not know it yet - you will have to solve the re-entrancy issue.

If you are calling foo() via main() and via an ISR, (and if foo has local variables) you have introduced a failure point.

To see start the debugger and run to foo()

while in foo, go to Peripherals -> Interrupt. Find your Interrupt and set its flag.

Pay attention to the Registers window, especially the values of R0-R7. Note how the ISR's version of foo will step on these values.

Author
Jeff Tonkinson
Posted
18-Jul-2011 17:55 GMT
Toolset
C51
New! RE: A helpful post

I understand that the OVERLAY command doesn't solve re-entrancy. I understand that the C51 is basically non-re-entrant. Ok. I get it. As I said, I do not think re-entrancy is my problem.

The OVERLAY command should work very nicely for me. However I still don't have it working. I feel like a 2nd grader who keeps getting is homework returned "incomplete".

Without posting lengthy code, here is the function I'm calling via pointer from an ISR. (I don't need the local variable - I just threw it in there to ensure that the problem isn't limited to parameters.)

static U8 InhalationSampleHandler( U16 u16Sample )
{
        U8 u8InhalationSampleHandlerLocal;
...

Below are excepts from the linker and you'll see that addresses 26H & 28H are overlaid among several functions. I did include the Overlay command to specify that my ISR calls InhalationSampleHandler(). You'll also see that I included ?C_C51STARTUP ~ ?PR?_INHALATIONSAMPLEHANDLER?INHALATION as an attempt to solve the warning WARNING L15: MULTIPLE CALL TO SEGMENT, but it didn't help much.

BL51 BANKED LINKER/LOCATER V5.12              07/18/2011  11:39:17  PAGE 1


BL51 BANKED LINKER/LOCATER V5.12, INVOKED BY:
Z:\TOOLS\SOFTWARE\KEIL\BL51.EXE Z:\MicroDose\Phase2\Software\FB_CPU_Init.obj,
Deleted for bevity
>> -21-02-xx.out RS (256) PL (68) PW (78) XDATA (?XD?SETTINGS (0X0)) CODE (?CO
>> ?VERSION (0X7FC0)) OVERLAY (?PR?ADC_ISR?ADC ! ?PR?_INHALATIONSAMPLEHANDLER?
>> INHALATION, ?C_C51STARTUP ~ ?PR?_INHALATIONSAMPLEHANDLER?INHALATION)


Deleted for bevity

  -------         ENDPROC       FLASH_VERIFY
  -------         PROC          _FLASH_WRITE_BYTE
  D:0026H         SYMBOL        pu8Address
  D:0028H         SYMBOL        u8Data

Deleted for bevity

  -------         ENDPROC       INHALATION_DETECTED
  -------         PROC          _INHALATIONSAMPLEHANDLER
  D:0026H         SYMBOL        u16Sample
  -------         DO
  D:0028H         SYMBOL        u8InhalationSampleHandlerLocal
  -------         ENDDO

Deleted for bevity

  -------         PROC          SLEEP_NOW
  -------         DO
  D:0026H         SYMBOL        u8Save_ADC0CN
  D:0027H         SYMBOL        u8Save_P0MDIN
  D:0028H         SYMBOL        u8Save_P1MDIN


*** WARNING L12: NO REFERENCE BETWEEN SEGMENTS
    SEGMENT1: ?PR?_INHALATIONSAMPLEHANDLER?INHALATION
    SEGMENT2: ?C_C51STARTUP


*** WARNING L15: MULTIPLE CALL TO SEGMENT
    SEGMENT: ?PR?_INHALATIONSAMPLEHANDLER?INHALATION
    CALLER1: ?PR?ADC_ISR?ADC
    CALLER2: ?C_C51STARTUP
Author
Jeff Tonkinson
Posted
18-Jul-2011 18:05 GMT
Toolset
C51
New! RE: A helpful post

Found the problem and fixed it. I had to remove the connection between the function that passed the function pointer from the function itself. This is explained in the App Note. (I was thrown off by the cryptic warning from the linker.)

Now both the parameter and local are unique in the data segment.

Call me happy.

Author
Ashley Madison
Posted
18-Jul-2011 19:32 GMT
Toolset
C51
New! RE: A helpful post

"Found the problem and fixed it."

how about this little piece of code:

#include <regx51.h>
#include <intrins.h>

//test to see if var1/var2 overlay creates problems.
//if var1/var2 overlaid incorrectly, P2 will be pulled down to 0 periodically.
//otherwise, P2 = 0x22+1;

#define NOP()                   _nop_()
#define NOP2()                  {NOP(); NOP();}
#define NOP4()                  {NOP2(); NOP2();}
#define NOP8()                  {NOP4(); NOP4();}
#define NOP16()                 {NOP8(); NOP8();}
#define NOP32()                 {NOP16(); NOP16();}
#define NOP64()                 {NOP32(); NOP32();}
#define NOP128()                {NOP64(); NOP64();}
#define NOP256()                {NOP128(); NOP128();}


void sub1(unsigned char var1) {
        var1=0;                                                 //reset var1/var2
        if (var1) var1=0;                               //make sure var1 is always 0
        //P2=var1;                                              //make sure tmr0 is working
}

void sub2(unsigned char var2) {
        var2=var2+1;                                    //increment var1/var2
        if (var2==0) var2=1;                    //make sure var2 is never zero
        NOP256(); NOP256();                             //delay 512 ticks - create opportunity for tmr0 to fire at least once
        P2=var2;                                                //output var2 on P0
}

void tmr0_isr(void) interrupt TF0_VECTOR {
        sub1(0);                                                //call sub1 periodically to reset var1/var2
}

int main(void) {
        TR0=0;                                                  //turn off tmr0
        TMOD = (TMOD & 0xf0) | 0x02;        //tmr0 in mode 2 (auto reload tl0 with th0
        TH0=-100;                                               //tmr strikes every 100 ticks
        TL0=TH0;
        ET0=1;                                                  //enable tmr0 interrupt
        TR0=1;                                                  //turn on tmr0
        EA=1;                                                   //enable global interrupt

        while (1) {
                sub2(35);
        }
}

it follows the example you gave earlier, except that it uses a tmr isr to fire sub1() periodically.

you can play with the compiler settings to get var1/var2 to overlay. what do you think you will get on P2?

Author
Jeff Tonkinson
Posted
18-Jul-2011 20:17 GMT
Toolset
C51
New! RE: A helpful post

Having mocked you of having less curiosity than me, I could hardly ignore your request. (I had to change your header files as I don't have those - I'm using an 8051F930 - so perhaps it's not an apples-apples comparison.)

With optimization 4+ var1/var2 are at the same address. However the actual assembler code doesn't reference these and uses registers. Not a fair test.

With optimization at 2, var1/var2 do not overlay each other. I would not expect this program to write anything other than 36 to P2.

I have to change the code as follows to get the data to overlay:

static void (*mHandler)(unsigned int uData);

void sub1(unsigned char var1) {
        var1=0;                                                 //reset var1/var2
        if (var1) var1=0;                               //make sure var1 is always 0
        //P2=var1;                                              //make sure tmr0 is working
}

void sub2(unsigned char var2) {
        var2=var2+1;                                    //increment var1/var2
        if (var2==0) var2=1;                    //make sure var2 is never zero
        NOP256(); NOP256();                             //delay 512 ticks - create opportunity for tmr0 to fire at least once
        P2=var2;                                                //output var2 on P0
        if ( var2 == 0 )
        {
                P2 = 1;
        }
}

void tmr0_isr(void) interrupt 1 {
//              sub1(0);
        (*mHandler)(0);                                                //call sub1 periodically to reset var1/var2
}

int main(void) {
                mHandler = sub1;
        TR0=0;                                                  //turn off tmr0
        TMOD = (TMOD & 0xf0) | 0x02;        //tmr0 in mode 2 (auto reload tl0 with th0
        TH0=-100;                                               //tmr strikes every 100 ticks
        TL0=TH0;
        ET0=1;                                                  //enable tmr0 interrupt
        TR0=1;                                                  //turn on tmr0
        EA=1;                                                   //enable global interrupt

        while (1) {
                sub2(35);
        }
}

This code seems to suffer from the same problem as my program. In fact, from within Sub2 I got var2 == 0.

Author
Ashley Madison
Posted
18-Jul-2011 20:29 GMT
Toolset
C51
New! RE: A helpful post

"This code seems to suffer from the same problem as my program. In fact, from within Sub2 I got var2 == 0."

if you really had curiosity, you probably would have run it on different platforms and observed the differences in behavior and asked yourself why.

Author
Jeff Tonkinson
Posted
18-Jul-2011 20:41 GMT
Toolset
C51
New! RE: Case closed

I actually claimed to have a lack of curiosity - and proud of it.

Thanks to everyone here to for their contributions to a case solved. Especially to Ron who, strangely enough, found the solution but didn't recommend it.

Author
Jeff Tonkinson
Posted
14-Jul-2011 18:43 GMT
Toolset
C51
New! RE: one of these functions is called by an ISR

Until now I thought I had a high lack of curiosity - now I find myself surpassed.

I care because it means the "volatile" did nothing for me. It was just a coincidence.

Author
Andrew Neil
Posted
14-Jul-2011 18:20 GMT
Toolset
C51
New! RE: I understand that Keil will allocate a variable (in DATA) for these

Note necessarily in DATA - the memory space used depends upon the Memory Model selected.

Author
Andrew Neil
Posted
14-Jul-2011 21:09 GMT
Toolset
C51
New! Optimiser.

The trouble with your example is that neither function does anything - so the compiler generates no code for them:

ASSEMBLY LISTING OF GENERATED OBJECT CODE


             ; FUNCTION _Sub1 (BEGIN)
                                           ; SOURCE LINE # 6
;---- Variable 'SubVar1' assigned to Register 'R7' ----
                                           ; SOURCE LINE # 7
                                           ; SOURCE LINE # 8
                                           ; SOURCE LINE # 9
0000 22                RET
             ; FUNCTION _Sub1 (END)

             ; FUNCTION _Sub2 (BEGIN)
                                           ; SOURCE LINE # 11
;---- Variable 'SubVar2' assigned to Register 'R7' ----
                                           ; SOURCE LINE # 12
                                           ; SOURCE LINE # 13
                                           ; SOURCE LINE # 14
0000 22                RET
             ; FUNCTION _Sub2 (END)

We need a slightly more realistic example...

Author
Andrew Neil
Posted
14-Jul-2011 21:16 GMT
Toolset
C51
New! RE: Optimiser.

If I change the source code to:

#include "c8051f9xx.h"

typedef unsigned char U8;
typedef unsigned int U16;

void Sub1( volatile U8 SubVar1 )
{
        SubVar1 = SubVar1 + 1;
}

void Sub2( volatile U8 SubVar2 )
{
        SubVar2 = SubVar2 + 1;
}

void main(void)
{
        while(1)
        {
                Sub1( 13 );
        }
}


static void ADC_ISR(void) interrupt 10
{
        U16 u16Result = 12;
        Sub2( u16Result );
        ADC0CN &= ~0x20;
}


The result is:

             ; FUNCTION _Sub1 (BEGIN)
                                           ; SOURCE LINE # 6
0000 8F00        R     MOV     SubVar1,R7
                                           ; SOURCE LINE # 7
                                           ; SOURCE LINE # 8
0002 0500        R     INC     SubVar1
                                           ; SOURCE LINE # 9
0004 22                RET
             ; FUNCTION _Sub1 (END)

             ; FUNCTION _Sub2 (BEGIN)
                                           ; SOURCE LINE # 11
0000 8F00        R     MOV     SubVar2,R7
                                           ; SOURCE LINE # 12
                                           ; SOURCE LINE # 13
0002 0500        R     INC     SubVar2
                                           ; SOURCE LINE # 14
0004 22                RET
             ; FUNCTION _Sub2 (END)


And the map file says:

-------         MODULE        OVERLAY
  C:0000H         SYMBOL        _ICE_DUMMY_
  D:00E8H         PUBLIC        ADC0CN
  D:00A8H         PUBLIC        IE
  C:0003H         SYMBOL        ADC_ISR
  D:00B8H         PUBLIC        IP
  C:0023H         PUBLIC        main
  D:0088H         PUBLIC        TCON
  C:002AH         PUBLIC        _Sub1
  C:002FH         PUBLIC        _Sub2
  D:0098H         PUBLIC        SCON0
  D:00D0H         PUBLIC        PSW
  -------         PROC          _SUB1
  D:0008H         SYMBOL        SubVar1
  C:002AH         LINE#         6
  C:002CH         LINE#         7
  C:002CH         LINE#         8
  C:002EH         LINE#         9
  -------         ENDPROC       _SUB1
  -------         PROC          _SUB2
  D:0009H         SYMBOL        SubVar2
  C:002FH         LINE#         11
  C:0031H         LINE#         12
  C:0031H         LINE#         13
  C:0033H         LINE#         14
  -------         ENDPROC       _SUB2

Author
Jeff Tonkinson
Posted
14-Jul-2011 21:36 GMT
Toolset
C51
New! RE: Volatile

To use the keyword "volatile" was my first thought, and it worked for a while in my program. In this simplistic program it works as well. As I continued working with my code the problem got "unfixed".

I think I've demonstrated the problem here and I'm not confident that this solution with "volatile" is at all guaranteed. I'd guess that we a bit afield of the ANSI standard it it's up to how Keil designed their optimization.

I'll probably send this over to Keil technical support.

Author
Andrew Neil
Posted
14-Jul-2011 21:55 GMT
Toolset
C51
New! No Volatile

Another thing is to disable passing parameters in registers, and make sure that the functions do something:

#pragma NOREGPARMS
#include "c8051f9xx.h"

typedef unsigned char U8;
typedef unsigned int U16;

U8 Sub1(  U8 SubVar1 )          // No 'volatile'
{
        SubVar1 = SubVar1 + 1;
        return SubVar1;
}

U8 Sub2(  U8 SubVar2 )          // No 'volatile'
{
        SubVar2 = SubVar2 + 1;
        return SubVar2;
}


void main(void)
{
        while(1)
        {
                Sub1( 13 );
        }
}


static void ADC_ISR(void) interrupt 10
{
        U16 u16Result = 12;
        Sub2( u16Result );
        ADC0CN &= ~0x20;
}

Which then gives:

             ; FUNCTION Sub1 (BEGIN)
                                           ; SOURCE LINE # 7
                                           ; SOURCE LINE # 8
                                           ; SOURCE LINE # 9
0000 0500        R     INC     SubVar1
                                           ; SOURCE LINE # 10
0002 AF00        R     MOV     R7,SubVar1
                                           ; SOURCE LINE # 11
0004         ?C0001:
0004 22                RET
             ; FUNCTION Sub1 (END)

             ; FUNCTION Sub2 (BEGIN)
                                           ; SOURCE LINE # 13
                                           ; SOURCE LINE # 14
                                           ; SOURCE LINE # 15
0000 0500        R     INC     SubVar2
                                           ; SOURCE LINE # 16
0002 AF00        R     MOV     R7,SubVar2
                                           ; SOURCE LINE # 17
0004         ?C0002:
0004 22                RET
             ; FUNCTION Sub2 (END)

and

-------         MODULE        OVERLAY
  C:0000H         SYMBOL        _ICE_DUMMY_
  D:00E8H         PUBLIC        ADC0CN
  D:00A8H         PUBLIC        IE
  C:0003H         SYMBOL        ADC_ISR
  D:00B8H         PUBLIC        IP
  C:0024H         PUBLIC        main
  D:0088H         PUBLIC        TCON
  C:002CH         PUBLIC        Sub1
  C:0031H         PUBLIC        Sub2
  D:0098H         PUBLIC        SCON0
  D:00D0H         PUBLIC        PSW
  -------         PROC          SUB1
  D:0008H         SYMBOL        SubVar1
  C:002CH         LINE#         7
  C:002CH         LINE#         8
  C:002CH         LINE#         9
  C:002EH         LINE#         10
  C:0030H         LINE#         11
  -------         ENDPROC       SUB1
  -------         PROC          SUB2
  D:0009H         SYMBOL        SubVar2
  C:0031H         LINE#         13
  C:0031H         LINE#         14
  C:0031H         LINE#         15
  C:0033H         LINE#         16
  C:0035H         LINE#         17
  -------         ENDPROC       SUB2

Author
Ashley Madison
Posted
14-Jul-2011 22:42 GMT
Toolset
C51
New! RE: Volatile

"I think I've demonstrated the problem here"

I am not as confident.

I have tried to replicate your code, using a timer isr instead of your adc isr. Both variables are allocated at the same address.

and I never observed them having the same value.

so unless shown otherwise, I am going to agree with others that you are trying to solve a problem that doesn't exist.

Author
Andrew Neil
Posted
14-Jul-2011 23:54 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

No, I don't think that you have demonstrated it here.

That may or may not mean that there is no problem - it might just be because the example presented here is over-simplified so that the problem doesn't arise.

Probably worth a discussion with Keil support - likely to be easier to share a more substantial example with them...

Author
Jeff Tonkinson
Posted
15-Jul-2011 14:18 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

I've tried to make my example more "complicated" but that darn optimizer is too smart. On the other hand my actual code is more than one swallow. I'll see if I can work up an example that actually fails.

Author
Per Westermark
Posted
15-Jul-2011 14:26 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

Make sure your functions make use of the parameter, and have them write the parameter value to a volatile variable. Volatile variables are normally a good way to get the optimizer to stop removing code - you want to convince the compiler that there is an important side effect that must not be optimized away.

Author
Erik Malund
Posted
15-Jul-2011 14:47 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

I've tried to make my example more "complicated" but that darn optimizer is too smart

try optimize = 2. this is basically variable overlay and nothing else.

to the homewrecker and the sardine: please not the word basically

Erik

Author
Ashley Madison
Posted
15-Jul-2011 15:11 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

"please not the word basically"

is it too much to ask that you write complete and comprehensible sentences, erik?

Author
Ron Wedge
Posted
18-Jul-2011 16:49 GMT
Toolset
C51
New! RE: A Helpful Post

Folks, I think you are gallantly galloped way, way off the beaten path if the original poster is posting summary's like "A helpful post"

I love a good name calling and the pedantic arguments session, but maybe it would be better to create a new thread next time we want to do this? I do not think it was benefiting the OP.

Scratch that, I bet we can get this done without the name calling, especially the dreaded "s" word (sardine).

Author
Ashley Madison
Posted
15-Jul-2011 15:13 GMT
Toolset
C51
New! RE: I think I've demonstrated the problem here

"I'll see if I can work up an example that actually fails."

I have one that follows your basic structure but uses a tmr isr to trigger one of the subroutines.

as andrew pointed out, you need to make sure that both subroutines actually operate on those two variables.

Next Thread | Thread List | Previous Thread Start a Thread | Settings