CW10: __near doesn't force function to non-banked address

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CW10: __near doesn't force function to non-banked address

884 Views
tomlogic
Contributor III

I'm trying to force a function to be non-banked so I can store its address in a (void *).  I thought that this syntax:

 

int __near foo1( void){    return 42;}

would be sufficient, and it was enough to quiet the compiler warnings when trying to assign the address of foo to a void pointer.  But when I checked the MAP file, it had been compiled to banked memory.

 

I ended up using this syntax:

#pragma CODE_SEG __NEAR_SEG NON_BANKEDint foo2( void){    return 42;}#pragma CODE_SEG DEFAULT

Why doesn't the first version work?  In my test, foo1 was banked and foo2 was not.  The __near keyword is certainly cleaner, especially for multi-platform code (we can define a macro NEAR to be __near when necessary, or a null macro otherwise).

 

-Tom

Labels (1)
Tags (1)
0 Kudos
3 Replies

608 Views
tomlogic
Contributor III

As a followup, what's the correct syntax for a typedef of a near function pointer?  The help file entry for "The __near Keyword" is quite confusing, especially this entry which doesn't make sense (1 __far plus 2 __near = 1 __near plus 2 __far?):

 

void __far *__near (*__near f)(void)
OK
__near pointer to __far function returning a __far pointer to void

For my example below, what does a function pointer to a near, non-banked function look like?  The compiler doesn't like any of the following:

 

typedef int __near (* foo_fn)( void)

typedef int (* __near foo_fn)( void)

typedef __near int (* foo_fn)( void)

 

0 Kudos

608 Views
CompilerGuru
NXP Employee
NXP Employee

Use the pragma for defining/declaring near functions. As you noticed the __near keyword does not change where an object is allocated, only how it is accessed (or dereferenced for a pointer). So __near should almost eclusively be used for pointers.

For functions it rarely makes sence, one rare situtation would be to use near calling convention for a function which is allocated in a bank, but for which it is known that all callers are in the same bank.

For example when all code of a C file gets placed in a specially named section allocated on a particular bank, then all static functions could be __near qualified. In "normal" code: use the pragma.

 

About the function pointer, the __near is always after the * for any kind of pointer, including function pointers.

I noticed that the ide did flag a warning for the __near function pointer below, but the compiler does fully accept it.

 

 

typedef int (* __near foo_fn)( void);#pragma push#pragma CODE_SEG __NEAR_SEG NON_BANKEDint fun_function(void){    return 42;}#pragma popfoo_fn funPtr = fun_function;void main(void) {  for(;;) {   (void)funPtr();  }}

 

Daniel

0 Kudos

608 Views
tomlogic
Contributor III

Daniel,

 

In my case, I want to pass a function pointer in as the "void *context" parameter of an existing API.  In order for that to work, the function needs to be in non-banked memory so it fits in the 16-bit void pointer and I can cast it back out to the function pointer.

 

I would like to say that it's inconvenient to require pragmas to force a function into non-banked memory, and it certainly makes writing code that compiles on multiple embedded platforms more difficult -- I need to wrap the pragmas in #if/#endif blocks so they only apply on the Freescale target.

 

Regarding the function pointer declaration, after reading up on error C18005, I've learned that this is the correct syntax for a near pointer to a near function:

 

typedef int __near (* __near foo_fn)( int param);

 If the return type is a far pointer though, it gets ugly:

typedef void __near * __far (* __near bar_fn)( int param);

 Come on.  It's so confusing that the help file even gets it wrong on the page for "The __near keyword" (see my first message in this thread).

0 Kudos