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
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)
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
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).