Pumpkin, Inc.

Pumpkin User Forums

Inline services possible bug

If you think you've found a bug or other mistake in your Salvo distribution, post it here.

Inline services possible bug

Postby luben » Wed Dec 11, 2002 10:56 am

Hello,

I think that there is :
- or a small bug in the inline OS_Delay() service call
- or absense of information in the manulal
(I deny the opportunity for both of them to be true)

Here is the fragment of source that generates error (it should not do this):
if (RB0)
OS_Delay(2, _TASK02);
else
OS_Yield(_TASK02a);
****** generates erroer like - inappropriate <else> or something like that


and the fragment that is OK

if (RB0)
{
OS_Delay(2, _TASK02);
}
else
OS_Yield(_TASK02a);


BTW, I got this problem long time ago and I even don't try to use OS_Yield, OS_delay and other services without braces.

Possible fixing of the problem - to add curly braces before and after the operator.

regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby aek » Thu Dec 12, 2002 8:32 am

Hi Luben.

Yes, you're right. Here's the code for OS_Delay():

code:
#define OS_Delay(delay, label) { 
OSDelay(delay);
OS_Yield(label); }

We probably should change it to
code:
#define OS_Delay(delay, label) do { 
OSDelay(delay);
OS_Yield(label); } while (0)

and that would fix it ... I need to check to ensure that the various compilers handle do { ...} while (0) properly / efficiently ...

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 6:51 am

Hello,

Today I encountered more serious problem with OS_Delay(). I found that in the task, where OS_Delay() is the last operator in the non stopping loop and in the beginning is some variable operation, if the bank settings of the OSTCB and variable are different the variable operation fails....

Here is some code:

code:

_OSLabel(_TASK_Refresh1) // define labels
_OSLabel(_TASK_Refresh2) // define labels
_OSLabel(_TASK_Refresh3) // define labels
/***************************************************************/
void TASK_Refresh(void) // syncronize EEPROM with user variables in background mode
/***************************************************************/
{
bank2 static byte prescal_20s, i; // will do refresh every 20s

static byte array_settings[NUMBER_OF_SETTINGS+1]; // array that hold current settings

prescal_20s = 20;

while(TRUE)
{

prescal_20s = prescal_20s; // used to force the banking
if (prescal_20s)
{
prescal_20s--;
}
else
{
//------------ HERE PASSES every 20s - refresh EEPROM in background

prescal_20s = 20;

for (i=0; i < NUMBER_OF_SETTINGS; i++)
array_settings[i] = settings.bytes[i]; // move into new array to avoid changing of data
// while recording the values in EEPROM

for (i=0; i <NUMBER_OF_SETTINGS; i++) // check all settings
{
if (array_settings[i] != read_EEPROM(i))
{
write_EEPROM(i, array_settings[i]);

//----------- wait until EEPROM recorded, initially EEPROM is always in idling state

while (WR)
{
OS_Delay(time_20ms,_TASK_Refresh1); // use OS_Delay instead OS_Yield
// to decrease the load over kernel
}
}

} // end of loop that scans for changed settings

}

OS_Delay(time_1s, _TASK_Refresh2);


//==================================================

} // end of the main loop
}


If OSLOCALL is set to bank2 but prescal_20s in bank1 - prescal_20s will not be decrement in the beginning of the loop, even if dummy instruction stays before the operator...

I'll try to put you're recomended OS_Selay and will keep you in touch

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 7:30 am

Hello,

I changed the OS_Delay into salvo.h in INC directory (like you reccomended) ... nothing changed at all in the project. Seems that I discovered some other kind of bug in OS_Delay macro... maybe it will never be visisible in uP with no banking.

I got that adding dummy operation in the beginning of the program doesn't fix the problem. Somehow the compiler believes that the banks are set correctly and don't care for the new settings immediately after OS_Delay().

When the variable bank is the same like OSLOCALL bank, the problem somehow becomes more serious - it started to decrement the variable 2 or 3 time, but from one moment the task just hangs (no calling to this task).... Seems that OS_Delay at the end of the loop could cause problems.

I found that if immediately after OS_Delay I put var=var; everything is OK and I'm happy...

code:

while (1)
{
if (var)
var--; // this operator doesn't execute corretly if no var=var; after OS_Delay
.........
OS_Delay(time, Label);
var = var; // added operator that removes the problem
}

I began to wonder if this is really SALVO or its pure HiTech problem... in fact the C spelling is absolutely correct, but the compiled program doesn't work .. or what is worse - it hangs from time to time. BTW I lost 3 hours before I got from where the problem appeared... my SALVO MONITOR main processor programs hanged after I changed channels or area. Because the background saving task is waking every 20s, the program began to do strange things within 20s after something changed..... was really very strange and nasty problem.....

At least I'll put such dummy commands to all suspicious places....

regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 7:36 am

Maybe we should change the macro to

code:


#define OS_Delay(delay, label) do {
OSDelay(delay);
OS_Yield(label);
var =var; } while (0)


This var could be some SALVO variable, so the user will not care to define it

Regards
luben

[This message has been edited by luben (edited January 07, 2003).]

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby aek » Tue Jan 07, 2003 8:16 am

Hi Luben.

There is no relation between OSLOC_ALL and the ticks parameter passed to OS_Delay(), so any bank failures you see are compiler bugs.

PICC has had a banking bug like this before -- see "While() statements and context switches" in the Tips, Tricks and Troubleshooting chapter of the user manual. However, that was fixed in v7.85.

If you can reduce it down to a simple test example, you should email it to HI-TECH support as a bug report.

Regards,

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 8:42 am

Hello,

Maybe this issue should be redirected to other Public forum.....

In short - You're absolutely right that OS_Delay macro is not connected with OSLOCALL banks at all - both operators into this macro don't point any variables into OSLOCALL area..... But the fact exists in my project - when changing the bank in OSLOCALL the error changes exactly in this place, that means - they are somehow connected (it's not a good idea, it's a fact :-).

Here is my explanation why (something like the theory of Big Boom, that needed to be proved) :

- in the macro OS_Delay there is really no calling to OSLOCALL variables, but you forgot that the OS_Yield() is just one gate to the SALVO kernel. OS_Yiled is one <return> command, but behind this return stays one big program, that operates with variables exactly in the OSLOACALL banks. Because the SALVO structure is not the standard program structure, here we should keep in mind the whole process.

- So, when you say that in the macro OS_Delay stays OS_Yield, you have to keep in mind that this is in fact the calling to the kernel of SALVO. The kernel uses explicitly the variables exactly in the OSLOCALL banks.

Maybe here the compiler fails - it interpretes OS_Yiled like simple return from subroutine, but this is not return - it's a CALL to other service!!! The compiler doesn't see anything wrong and "believes" that with OS_Yield the whole chain of events stops - the subroutine is finished and have to return the control to the main program. The reality is other - the main program calls other services with the operator RETURN, that is usually used for returning the control ..... SALVO uses RETURN in non standard manner!!!

So, if you call OS_Delay and after that the variable operation works - you should be happy and thankful - the compiler somehow succeeded to set the right settings of the banks.

In my opinion you should add some dummy operation after OS_Yield to keep alert compiler that the cotrol comes exactly back on this place and right banks are set.

Something like
*(unsigned char(*))()0x20 = *(unsigned char(*))()0x20;

Or just access some SALVO variable.
SALVO_var = SALVO_var;

The problem is that after RETURN the chain of program flow is broken and maybe the compiler will eliminate the operators after return and will not keep in mind that they exists at all.... something like

code:

if (0)
a++; // this operator will be just ignored and not added into program nor will be keep in mind when talking about banking

I think that playing with other dummy <If... while.. do> we could wrong the compiler to activate the bank calculating procedure.

In short.... OS_Delay could be misunderstood from the compiler and when returning back from the kernel the banks could be wronged. It's possible....

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 8:47 am

Or we could break the peace of OS_Yiled by changing it to

code:

#define OS_Yield(label)do { OSSaveRtnAddr(label);
asm(" return");
asm("_" _OSMkstr(label) ":");
var = var;
} while (0)


Don't forget that HiTech could not start banking calculation if there is assembler section.... 100% sure!

Regards
Luben

[This message has been edited by luben (edited January 07, 2003).]

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Re: Inline services possible bug

Postby aek » Tue Jan 07, 2003 8:49 am

Hi Luben.
quote:
Maybe here the compiler fails - it interpretes OS_Yield like simple return from subroutine, but this is not return - it's a CALL to other service!!!
Yes, that's basically the problem ... bank bits are being changed insideOS_Delay(), and because the compiler sees a "return" instruction, it figures that it doesn't have to maintain bank bits anymore ... this is exactly the kind of bug that was in there previously -- looks like it came back in PICC's optimizer.

So, to get this fixed, what you need to do is create a small program (preferably one that does not use Salvo) that they can use to reproduce the problem. You could create a function to replace OS_Delay() that plays with bits in other banks, and put an inline asm(" return") after it, and it should fail in the same way. Send that to HI-TECH and they'll get it fixed (like they did with the original bug).

Regards,

------------------

-------
aek
aek
 
Posts: 1888
Joined: Sat Aug 26, 2000 11:00 pm

Re: Inline services possible bug

Postby luben » Tue Jan 07, 2003 9:43 am

Hello,

OSLOCALL parameter directs all variables of SALVO to some bank. If this bank is the same like the variable in the beginning of while loop, then no problem exists.
If the banks are different, when returning from OS_Delay service the compiler doesn't change the banks and the variable is not preccessed correctly.

because I'm with the latest HiTech, maybe there is other problem.... like for example I forgot to call OSInit() and I got similar crazy behaviour...

From other side I had several projects with the the latest SALVO version, used Delays and I never had problems...

Now I'm 100% sure that it's outside of the SALVO - or HiTech or wrong playing with operators.

BTW, the SALVO monitor is ready (with LEDs).. now I'm testing it (MIN, MAX times; OVERTIME tracking, area settings... and much more).

Regards
Luben

luben
 
Posts: 324
Joined: Sun Nov 19, 2000 12:00 am
Location: Sofia, Bulgaria

Next

Return to Bug Reports

Who is online

Users browsing this forum: No registered users and 2 guests

cron