Pumpkin, Inc.

Pumpkin User Forums

Salvo & interrupts

For issues specific to the 8051 family, including compilers (e.g. Keil C51) and IDEs (e.g. uVision2).

Salvo & interrupts

Postby ILIAKG » Wed May 05, 2004 2:33 am

Hello!
We have application with Salvo Pro 8051 v.3.2 with Keil Tools : C51 and BL51,
Large model memory,C8051F124. I use standard library slc51lxta.lib and
salvocfg.h:

/* Salvo LE & Pro library build
#define OSUSE_LIBRARY TRUE
#define OSLIBRARY_TYPE OSL
#define OSLIBRARY_GLOBALS OSX
#define OSLIBRARY_CONFIG OST #define OSLIBRARY_VARIANT OSA
#define OSEVENTS 20
#define OSEVENT_FLAGS 20
#define OSMESSAGE_QUEUES 1


#define OSTASKS 20

#define OSBYTES_OF_EVENT_FLAGS 2 // ????

#define OSENABLE_INTERRUPT_HOOKS TRUE
#define OSENABLING_IDLING_HOOK TRUE

#define OSENABLE_SEMAPHORES TRUE //??
#define OSENABLE_IDLING_HOOK TRUE // ??

#define OSTIMER_PRESCALAR 32 // ????
#define OSBIG_MESSAGES_POINTERS TRUE //

#define OSMESSAGE_TYPE xdata // ????

//***********************************************************

I've been experiencing problems concerning the RTOS and interrupts. There is extern interrupt INT0,which handlers incoming cyclic bursts and sends OSSignalBinSem and OSSetEFlag to the task.The task receive these events and get some intermediate
information from interrupt handler.I use interrupt because the application
needs high precision tied to time (binding) . The problem is that, sometimes,
the receiving is broken because Salvo disables interrupts in some specific times.
This is good for Salvo,but it is not very good for application.
What is the solution of this problem ?
Any ideas ???

Sincerely,
ILIAKG

I.K.
ILIAKG
 
Posts: 6
Joined: Wed Apr 21, 2004 11:00 pm
Location: Jerusalem, Israel

Re: Salvo & interrupts

Postby aek » Wed May 05, 2004 3:10 am

Hi Ilya.

This is the classic problem of interrupt latency due to the RTOS' need to disable interrupts while in critical sections.

The solution is to change how Salvo controls interrupts to suit your application AND to still access shared global variables correctly. This is pretty easily done in a Salvo Pro source-code build.

First, you're doing a library build (fine) but many of the options you're specifying (e.g. OSBYTES_OF_EVENT_FLAGS) are only for source code builds. Please remove everything in your salvocfg.h after

code:
#define OSTASKS 20

.

Next, to change the control of interrupts, you'll need to do a source-code build instead of a library build. So reconfigure your project for a Salvo source-code build.

Third, look in portkc51.h. There, you will see that Salvo disables and renables interrupts via EA=0 and EA=1 (see OSDi() and OSEi()), and also saves saves IE before entering critical sections and restores it when leaving a critical section (OSEnter|LeaveCritical()).

What you need to do is define new OSDi|Ei() and OSEnter|LeaveCritical() macros in your salvocfg.h, and do a source-code build. Your new macros will replace the ones that Salvo uses by default.

What you want to do is develop a macro that only disables the interrupt sources that call Salvo services from ISRs. E.g. if TimerN calls OSTimer(), then create macros that only disable the interrupt-enable flag for TimerN. This way, Salvo won't disable interrupts globally, and your other interrupts will be unaffected by Salvo. You can create multi-line macros, of course, where you control (for example) three of the C8051F124's individual interrupt-enable bits but leave the rest and the global interrupt enable bit alone.

Note that the existing OSEnter|LeaveCritical() macros save information on the stack -- you don't have to do that -- you could just do something simpler like

code:
#define OSEnterCritical do { IE_1=0; IE_2=0; IE_7=0; } while (0)

etc. This would forcibly disable certain interrupt sources within Salvo's critical sections, but leave everything else alone. Or, you can push things onto the stack as we do it.

Don't forget to enable interrupts globally at the start of your (new) program -- you won't be able to use OSEi() anymore (to control global interrupts).

The key thing to remember is this: anytime you call a Salvo service from an ISR, you must ensure that the interrupt is disabled during Salvo's critical sections. When we build Salvo libraries, we simply disable global interrupts, because that's the most general case. In your case, you need to control interrupts more distinctly.

When you have the new macros in place in your salvocfg.h, i recommend that you step through a Salvo service (e.g. OSSched() to verify that your code is now controlling the interrupt enable bits you want, and not the global EA.

BTW, did you end up doing code banking?

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

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

Re: Salvo & interrupts

Postby aek » Wed May 05, 2004 3:18 am

Oh, I guess I should add:

It sounds like your INT0 ISR needs to be able to operate without interference from Salvo. Yet you also want to call Salvo services from that ISR. Unfortunately, you can't do both, but here is how you can work around that -- here is an example from a PIC18 user:

code:
main()
{
for(;;)
{
if ( highISR_activity )
{
GIEH = 0;

transfer_highISR_data_to_a_safe_place();

OSProtect();
OSSignalMsgQ( highISR_data);
OSUnprotect();

GIEH = 1;
}

OSSched();
}
}


The idea here is that since you can no longer call OSXyz() from inside the "fast, unaffected-by-Salvo" ISR, you need to pass the information "up" to the RTOS. You do so by explicitly disabling that interrupt for a very short time (much shorter than the worst-case time in OSSched()), and while interrupts are disabled, calling OSXyz().

You can see more at this link.

Note: The Salvo for 8051 port doesn't need OSProtect() and OSUnprotect() -- that's PICC-18 specific.

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

[This message has been edited by aek (edited May 05, 2004).]

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

Re: Salvo & interrupts

Postby aek » Wed May 05, 2004 3:27 am

I guess I should mention that this sort of thing doesn't come up too often with Salvo users. It's a problem when you have a high-rate interrupt (e.g. I2C, every 90us) and you can't afford for anything to hold off the ISR. Since, for a typical 8-bit RISC processor, 90us is 90 instructions at 4MHz -- and the RTOS will often take more than 90 instructions to do something -- this sort of "fast" interrupt requires the approach I outlined below.

The neat thing about all this is that you end up "layering" Salvo on top of high-speed interrupts, and you can completely remove any interference / latency imposed by Salvo on the high-speed interrupts. Sort of a "machine within a machine".

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

[This message has been edited by aek (edited May 05, 2004).]

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

Re: Salvo & interrupts

Postby ILIAKG » Thu May 13, 2004 8:48 am

Hi, aek !
Thanks for help concerning interaction between Salvo and interrupts. I did not answer, as it took much time:
to rebuild project with Salvo sources,
to check how it work. Now it work !
By the way - some more question:
I use function "printf()" for debugging.
Now, after all changes, I could not to use
"printf" from inside tasks ( application is bugged and not responses ... ), only before main loop for(; . Is it causal relationship ?
Sincerely,
ILIAKG

I.K.
ILIAKG
 
Posts: 6
Joined: Wed Apr 21, 2004 11:00 pm
Location: Jerusalem, Israel

Re: Salvo & interrupts

Postby aek » Thu May 13, 2004 11:02 am

Hi Ilya.

Yes, it could be a causal relationahip. The Salvo for 8051 context switcher is very simple (and fast), and may not work when a function like printf() (which places parameters on the stack) is called from within the task.

The simplest way to avoid that is to call printf() "through" a dummy function that is called in the task, i.e.

code:

void myDummy (void)
{
printf(arg1, arg2, ... argn);
}

void myTask (void)
{
for (;;)
{
OS_Xyz(...);
myDummy();
...
}
}


This isn't a problem, for example, with the Salvo for TI's MSP430 and AVR context switchers.

We may update the Salvo for 8051 context switcher to handle this, but until then, use the solution outlined above.

Regards,

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

[This message has been edited by aek (edited May 13, 2004).]

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

Re: Salvo & interrupts

Postby ILIAKG » Fri May 14, 2004 11:35 am

Hi, aek !
Unfortunately, it does not work.
When I try it from task, bit TI(TI0)of SCON(SCON0) is not set at the end of the transmission and printf or putchar wait forever (I made debugging ).
Regards,
Ilia.
I.K.
ILIAKG
 
Posts: 6
Joined: Wed Apr 21, 2004 11:00 pm
Location: Jerusalem, Israel

Re: Salvo & interrupts

Postby aek » Mon May 17, 2004 8:22 am

Hi Ilya.

I feel that the fix I described should work.

if you want, zip up the whole uVision2 project (no need to send Salvo source files, but be sure to send any of your own, special, interrupt-related code, like OSEnterCritical(), etc.) and email them to support at pumpkininic dot com.

Ideally, as small an example as possible is what we would like, and we need to be able to see the problem in the uVision2 simulator.

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

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


Return to 8051 family

Who is online

Users browsing this forum: No registered users and 1 guest

cron