Page 1 of 1

reentrant code uses wrong register bank

PostPosted: Mon Aug 19, 2002 12:09 am
by dfleck
I'm using the latest version of the Keil C51 compiler and BL51 linker, and I'm using slc51siaa.lib. Here are the config definitions from my salvocfg.h:
#define OSUSE_LIBRARY TRUE
#define OSLIBRARY_TYPE OSL
#define OSLIBRARY_GLOBALS OSI
#define OSLIBRARY_CONFIG OSA
#define OSLIBRARY_VARIANT OSA

The problem occurs in OSReturnSem, which I'm calling from the ISR, and which uses register bank 1. The reentrant code saves AR5 and AR7, but the parameters are actually in R5 and R7 of bank 1. Does the library support what I want to do, or must I build the source and use NOAREGS around OSReturnSem?

------------------
Donald A. Fleck


Re: reentrant code uses wrong register bank

PostPosted: Mon Aug 19, 2002 9:24 am
by aek
Hi Don.

Our mistake. As currently supplied, the particular Salvo libraries for the 8051 were not compiled with

code:
#pragma NOAREGS

, and as a result you'll end up with the problem you're experiencing when the ISR's register bank is not bank 0.

So, the solution (and a surprisingly non-costly one, as I see a growth in OSReturnSem() of only 3 bytes of ROM) is to apply the pragma to that function. Please cut-and-paste the code after the first #endif below and place it immediately after the __SALVOMCG_H endif, i.e.:

code:
#endif /* #ifndef __SALVOMCG_H */


#if ( OSCOMPILER == OSKEIL_C51 )

#if defined(__OSRETURNBINSEM_BINSEM2_C)
|| defined(__OSRETURNEFLAG_EFLAG2_C)
|| defined(__OSRETURNMSG_MSG_C)
|| defined(__OSRETURNMSGQ_MSGQ2_C)
|| defined(__OSRETURNSEM_SEM2_C)

#if OSCALL_OSRETURNEVENT == OSFROM_ANYWHERE
#pragma NOAREGS
#endif

#endif


To be on the safe side, you should do a source-code build. However, there is a sneaky way to avoid this -- just add sem2.c to your library-based project and rebuild ... I'll leave it to you as to why ... I'd also recommend reviewing the object code to ensure that the change has taken place (the position of that code snippet in salvomcg.h is very important -- read the comment just below it).

Please let me know if that solves your problem. We will roll this fix into the next update. I also have to think about how this applies to the 'e'-variant libraries.

Regards, and sorry for the trouble ...

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

[This message has been edited by aek (edited August 19, 2002).]


Re: reentrant code uses wrong register bank

PostPosted: Thu Aug 22, 2002 5:56 am
by dfleck
Thanks Andrew.

Prior to receiving your reply I experimented by adding sem2.c to my project, and adding NOAREGS after including salvomcg.h:

code:
#include "salvomcg.h"
#pragma NOAREGS

It worked and added only 3 bytes of code.

I also want to use OSSignalSem from an ISR. So I have some more questions:


  1. I don't want to do a source code build, so can I just include sem.c and sem2.c in my project, and make your suggested change to salvomcg.h?
  2. Do I need to add '|| defined(__OSSIGNALSEM_SEM_C)' to the #if statement?
  3. Your code snippet contains 3 #if but only 2 #endif. Should there be another #endif?

------------------
Donald A. Fleck


Re: reentrant code uses wrong register bank

PostPosted: Thu Aug 22, 2002 7:38 am
by aek
Hi Don.

1) You can add sem.c to your library build and it should still work.

2) Don't just add to the existing if defined()... Instead, create another one like this:

code:
#if defined(__OSSIGNALBINSEM_BINSEM_C) 
|| defined(__OSSIGNALEFLAG_EFLAG_C)
|| defined(__OSSIGNALEVENT_EVENT_C)
|| defined(__OSSIGNALMSG_MSG_C)
|| defined(__OSSIGNALMSGQ_MSGQ_C)
|| defined(__OSSIGNALSEM_SEM_C)
#if OSCALL_OSSIGNALEVENT == OSFROM_ANYWHERE
#pragma NOAREGS
#include "salvolvl.h"
#endif
#endif

and put it right after the first.

3) That first #endif is just there to show you where to put the snippet -- i.e. you'll paste it "over" the identical #endif in your existing salvomcg.h.

Regards,

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