Pumpkin, Inc.

Pumpkin User Forums

Trouble with Salvo Lite for 8051 -- HELP!!

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

Trouble with Salvo Lite for 8051 -- HELP!!

Postby DHenry » Wed Mar 27, 2002 1:26 am

The problem is likely due to the use of "using BANK1". Assuming the functions in the libraries are built without a "using" attribute, the register bank defaults to BANK0. The following paragraph is an excerpt from Keil's C51 manual on page 128.

"Functions called from an interrupt procedure must function with the same register bank as the interrupt procedure. When the NOAREGS directive is not explicitly specified, the compiler may generate absolute register accesses using the register bank selected (by the using attribute or by the REGISTERBANK control) for that function. Unpredictable results may occur when a function assumes a register bank other than the one currently selected. Refer to “Register Bank Access” on page 124 for more information."

My recommendation is to try removing the "using BANK1" attribute and see how you get along.

Regards,

--Dan Henry

DHenry
 
Posts: 18
Joined: Sat Aug 04, 2001 11:00 pm
Location: Boulder, CO, U.S.A.

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby Unregistered User » Wed Mar 27, 2002 10:35 am

So far I've been experiencing problems concerning the RTOS functions "OS_Delay",
"OS_DelayTS", which don't appear to work !! Obviously these functions use Timer0,
which I've enabled and I've verified that its' interrupt is vectoring to the following function:

code:
tf0_intr() interrupt 1 using BANK1 
{
OSTimer();
}

I'm sure that it's most likey a configuration issue or perhaps related to the limited (freeware) version, but frankly the whole configuration thing is a bit scary, as there's so many things to "set up" !! I'm not sure if I have enabled
these timer-based RTOS functions, as I can't seem to locate where I actually enable these funstions with the define "USE_INTERRUPTS"... I tried placing it in salvocfg.h and re-compiling, but it still doesn't seem to work. Basically,
when either delay function is called, the whole system "hangs up", and when I
stop execution, the Cygnal device is externally ruuning code in the RTOS's
kernel.

Any ideas ???

Unregistered User
 
Posts: 36
Joined: Thu Aug 09, 2001 11:00 pm

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby aek » Wed Mar 27, 2002 11:07 am

Let's start at the top -- I think we can get you up and running quickly.

1) With Salvo Lite, you call Salvo services that are present in a precompiled library that you link to. The only Salvo configuration options you need are:

code:
OSUSE_LIBRARY			
OSLIBRARY_TYPE
OSLIBRARY_GLOBALS
OSLIBRARY_CONFIG
OSLIBRARY_VARIANT

In other words, these are the only configuration options that should be in your salvocfg.h.

2) For Salvo Lite, OSUSE_LIBRARY is always TRUE and OSLIBRARY_TYPE is always OSF ("F" for freeware). The OSLIBRARY_GLOBALS, OSLIBRARY_CONFIG and OSLIBRARY_VARIANT must match the library you're using. For starters, please use

code:
#define OSUSE_LIBRARY             TRUE	
#define OSLIBRARY_TYPE OSF
#define OSLIBRARY_GLOBALS OSD
#define OSLIBRARY_CONFIG OSA
#define OSLIBRARY_VARIANT OSB

in your salvocfg.h and use a sfc51sdab.lib or sfcx51sdab.lib Salvo Lite library. These are libraries for the SMALL memory model (second "s"), with Salvo's global variables in the data ("d") RAM space, with all ("a") functionality enabled, and for Salvo services called from the background ("b"), i.e. from the task level. These series of libraries will give you all of Salvo Lite's functionality, and you should use them unless you need to shrink your code down.

3) Using this salvocfg.h, you need to also set your project to use C51's SMALL memory model and link to the appropriate library.

If you need to use, say, C51's LARGE memory model, then you'll need to link to the sfC51ldab.lib or sfcx51ldab.lib Salvo Lite libraries.

4) Salvo Lite is very powerful -- the only limits it puts are on the numbers of tasks, events, etc. All Salvo libraries are compiled for default configurations (e.g. 8-bit delay resolutions). The Salvo library configurations (OSLIBRARY_CONFIG) range from multitasking-only (OSM) to full-blown with support for delays, events and timeouts (OSA, "A" for "all). This is outlined in the Libraries Chapter of the User Manual.

5) Your code for tf0_intr() looks fine (assuming BANK1 is a valid bank specifier).

6) Adding USE_INTERRUPTS to your project's salvocfg.h won't have any affect, because it's not a Salvo configuration option.

While we recommend that you use our example projects as a guide, it's important to realize that those example projects (e.g. salvo ut u1-tu6) have a lot of symbols that we use to make managing these projects easier. For example, USE_INTERRUPTS (note that it's not OSUSE_INTERRUPTS) allows us to minimize the number of files that are part of the tutorial projects. USE_INTERRUPTS has nothing to do with Salvo code per se -- it's used only to control which parts of the source code in tu1-tu6main.c and tu1isr.c are compiled for each project tu1-tu6. Otherwise we'd have a maintenance nightmare on our hands because of all the different platforms we support. So, consider any symbols that do not have an OS prefix to be ones that we used to create working projects, but are not related to Salvo directly.

7)

quote:
Basically, when either delay function is called, the whole system "hangs up", and when I stop execution, the Cygnal device is externally ruuning code in the RTOS's kernel.

First, can you run the various tutorials successfully? Especially tu5 and tu6? They use the timer and call OSTimer(), and you can see (in bit 0 of P1 -- use the simulator if you don't have the Cygnal hardware) that OSTimer() is being called and TaskBlink() is in fact happening every 50 system ticks -- this shows that the whole interrupt system is working properly with Salvo.

Second, can you successfully create a very small, non-Salvo app that has the timer? I assume you can...

Next, can you add the call to OSTimer(), and link to an appropriate Salvo library? Assuming you compile OK (no warnings or errors) but crash when running, then you've probably chosen the wrong library or C51 memory model.

Once you have an app that runs without crashing and calls OSTimer() from an ISR, then you probably have all of your microVision2 build settings correct, and you can start expanding your application with tasks, Salvo calls, etc.

BTW, you can do all of this stuff in the microVision2 simulator.

8) Just use OS_Delay() for now, not OS_DelayTS().

I hope this helped.

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

[This message has been edited by aek (edited March 27, 2002).]

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

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby aek » Fri Mar 29, 2002 1:26 am

Hi Dan.

Despite your Junior status on these Forums (there's a laugh if I ever saw one ... :-) ), no post of yours is ever a Chicken Little post!

quote:
Explicitly specifying "using 0" is different than not specifying any register bank at all.

That's good to know ... With no "using" directive, C51 saves all 8 registers R0-R7 before calling OSTimer() from within the ISR. I presume it does this "worst-case" scenario because it can't see into OSTimer()'s register usage. With a "using 0" directive, the ISR enforces the 0 register bank, but does no saving. So "using 0" would be decidedly non-C51-standard, as you rightly point out, and no hack is required by leaving the "using" attribute off.

As for library builds, etc. -- I have to look at the code C51 generates for other functions (e.g. OSSignalBinSem()), but I think it's probably a non-issue. AREGS / NOAREGS has no effect on OSTimer(). I suspect it will have no effect on any other Salvo services, but I have to confirm it. So there should be no need to require Salvo services to be invoked from any particular register bank -- the code (e.g. OSTimer(), perhaps also OSSignalBinSem(), etc.) appears to be completely absolute-register-independent anyway.

We should make the AREGS/NOAREGS stuff configurable. Right now I've simply added the NOAREGS #pragma to timer.c.

Regards,

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

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

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby aek » Fri Mar 29, 2002 8:43 am

The NOAREGS is an interesting issue ...

As a test, I compiled tu6 and tu6lib with the Timer0 interrupt declared as "using 2", "using 1" and "using 0". The only difference in the code (apart from the fact that tu6lib's OSTimer() has a 32-bit increment of OStimerTicks, whereas tu6's does not since it was compiled with OSBYTES_OF_TICKS set to 0, the default) is in the register bank select code immediately prior to the call to OSTimer. For example,

code:
PUSH  ACC
PUSH B
PUSH DPH
PUSH DPL
PUSH PSW
MOV PSW,#0x10
LCALL OSTimer
POP PSW
POP DPL
POP DPH
POP B
POP ACC
RETI

is the code for the interrupt handler when "using 2" is selected. "Using 1" results in MOV PSW,#0x08, and "using 0" results in MOV PSW,#0x00.

Naturally, "using 0" doesn't work, since the ISR fails to push and pop all of the registers. "using 1" and "using 2" work fine, as should "using 3".

Note that in all of these cases, OSTimer()'s code doesn't change (apart from branch/call addresses), i.e it's unaffected by the "using" attribute, as one would expect. Here's OSTimer():

code:
MOV		R7,OSglStat			
MOV A,R7
CLR C
RRC A
JNB 0xE0.0,C:048E
MOV A,R7
ORL A,#0x01
MOV OSglStat,A
MOV A,OSglStat
ORL A,#0x02
MOV OSglStat,A
RET

OSTimer() is not compiled with NOAREGS. In this particular case, i.e. for OSTimer() in the current release of Salvo for 8051 family, the AREGS/NOAREGS issue appears to be moot. That's because C51 does not make use of any absolute addressing modes in OSTimer() that might be broken by calling it from an ISR that's using an alternate register bank.

So, I conclude that in the current release (v3.0.1), OSTimer() can be called from an ISR with "using 1", "using 2" or "using 3" attributes without problems. To make it work with "using 0" / no using attribute, you'd have to explicitly save R7, and that would be a real hack, so I wouldn't recommend it.

We will add the NOAREGS attribute to OSTimer() for the next release. I suspect we'll also add it to any and/or all functions that might be called from interrupts.

Comments?


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

[This message has been edited by aek (edited March 29, 2002).]

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

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby aek » Fri Mar 29, 2002 9:53 am

I forgot to add that OSTimer() compiles to the same machine code with NOAREGS or AREGS ...

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

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

Re: Trouble with Salvo Lite for 8051 -- HELP!!

Postby DHenry » Fri Mar 29, 2002 12:44 pm

First, my apologies for the misdirection. The register bank ("using") issue was something I had observed and reported while beta testing Salvo. My observation at that time was when calling OSSignalEFlag() from an ISR, not OSTimer(). Upon seeing the OP's use of a different register bank when invoking a library function, I was immediately reminded of my observation -- and with such a simple ISR, I thought "that's about the only thing it could be". I should have checked the settings for the library builds, compiled, and examined the resulting OSTimer() code before my Chicken Little post. However, I am quite curious to learn why the OP's ISR was/is failing.

quote:
To make it work with "using 0" / no using attribute, you'd have to explicitly save R7, and that would be a real hack, so I wouldn't recommend it.

Explicitly specifying "using 0" is different than not specifying any register bank at all. Explicitly "using 0" would be an unusual case where the user is "going against (Keil) convention" and using some other register bank as the default. When explicitly "using n", the compiler does not save the contents of the switched-to registers. When implicitly "using 0" (i.e., no "using" attribute), the compiler saves registers used in the ISR. A hack should be a non-issue.

quote:
We will add the NOAREGS attribute to OSTimer() for the next release. I suspect we'll also add it to any and/or all functions that might be called from interrupts.

I suppose that enabling the NOAREGS attribute for library builds would be safest, while recoginizing that performance will suffer a bit. I also wonder, would limiting library users to invoking Salvo services from register bank 0 be too restrictive? Hopefully source code users would not be saddled with NOAREGS and it would be configurable.

Regards,

--Dan Henry

DHenry
 
Posts: 18
Joined: Sat Aug 04, 2001 11:00 pm
Location: Boulder, CO, U.S.A.


Return to 8051 family

Who is online

Users browsing this forum: No registered users and 1 guest

cron