Reputation: 13
The closest threads to my question are these Escaping a # symbol in a #define macro? and How to print a pound / hash via C preprocessor?, but they don't exactly answer my question. More explicitly, the second doesn't seem to work with the armcc compiler; it just prints hash4 and not the symbol defined by hash. Chris Lutz was especially disparaging of trying use a macro for this functionality in the second post, so maybe this is the incorrect method all together. I would like more thoughts than just one persons, though.
The problem is the following: I'm trying to write a macro that defines an embedded asm C function utilizing a macro. I've essentially implemented it except for one issue... expressing an immediate value. Immediate values' syntax requires (I believe) a pound symbol which is also the "stringify" symbol for the preprocessor. So, is it possible to escape a # symbol in a C macro?
The primary purpose behind this is to wrap an isr with a pico kernels thread context management procedures and that new procedure's function pointer will eventually be passed to the vectored interrupt controller.
Here's the code:
#define ISR_THREAD_MGMT(ISR_FUNC,FUNC_NAME) \
__asm void FUNC_NAME ( void ); \
__asm void FUNC_NAME (void ) \
{ \
STMDB sp!, {r0-r3}; \
MRS r0, SPSR; \
SUB lr, lr, #4; \ <----- Heres the problem
STMDB sp!, {r0, r10, r12, lr}; \
bl _thread_vectored_context_save; \
bl ISR_FUNC; \
b _thread_context_restore; \
}
I hope I've explained everything in sufficient detail. If not, please don't hesitate to ask for any more details.
Upvotes: 1
Views: 1511
Reputation: 753675
The second of your referenced questions shows you how to do it:
#define hash #
#define mash(x) x
#define immediate(a) mash(hash)a
#define ISR_THREAD_MGMT(ISR_FUNC,FUNC_NAME) \
__asm void FUNC_NAME ( void ); \
__asm void FUNC_NAME ( void ) \
{ \
STMDB sp!, {r0-r3}; \
MRS r0, SPSR; \
SUB lr, lr, immediate(4); \
STMDB sp!, {r0, r10, r12, lr}; \
bl _thread_vectored_context_save; \
bl ISR_FUNC; \
b _thread_context_restore; \
}
ISR_THREAD_MGMT(abc,def)
Output:
# 1 "x.c"
# 1 "<command-line>"
# 1 "x.c"
# 17 "x.c"
__asm void def ( void ); __asm void def ( void ) { STMDB sp!, {r0-r3}; MRS r0, SPSR; SUB lr, lr, #4; STMDB sp!, {r0, r10, r12, lr}; bl _thread_vectored_context_save; bl abc; b _thread_context_restore; }
Output reformatted:
# 1 "x.c"
# 1 "<command-line>"
# 1 "x.c"
# 17 "x.c"
__asm void def ( void );
__asm void def ( void )
{
STMDB sp!, {r0-r3};
MRS r0, SPSR;
SUB lr, lr, #4;
STMDB sp!, {r0, r10, r12, lr};
bl _thread_vectored_context_save;
bl abc;
b _thread_context_restore;
}
I'm not convinced it is a good idea, but it does at least work.
Upvotes: 1