Hello, Dears First I say,I'm afraid I don't have good skills writing in English.
Please see my code. I defined my inline function code at seva.c file. This is the seva.c file
#include "seva.h" ... ... __inline void delay_ms(uint32_t ms) { register uint32_t i = ms; for ( ; i ; --i ) { delay_us(250); delay_us(250); delay_us(250); delay_us(250); } } __inline void delay_us(uint32_t us ) { register uint32_t i = us; for (; i; --i) { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } } ... ...
and I declare function prototypes at seva.h file. seva.h
... ... __inline delay_us(uint32_t us); __inline delay_ms(uint32_t ms);
when I try to call these delay functions in main.c file. main.c
#include "seva.h" ... ... void main(void) { P04 = 1; delay_us(100); P04 = 0; }
As you guess, It cause L6218E error. and I found http://www.keil.com/forum/13177/ this column. I defined every my inline code from seva.c to seva.h file. and It works well(means no compile error).
But there is one thing still confused.. See, Next code. seva.c
... ... __inline void delay_loop1( ) { register uint32_t i = 500; for (; i; --i) { __NOP(); } } ... ...
seva.h
... ... __inline void delay_loop1(void); ... ...
and I call this function at main.c file like above. but It doesn't have any comfiler errors. As I think, the difference delay_loop1 function and delay_ms function is only whether has parameter or not.
please tell me why delay_loop1 function compile without error, and why inline function has parameter occur errors.
Did you understand what I try to saying? I think I wrote too difficult.
Thanks for reading.
Thanks Sir! Thanks to your kind explanation, my head be cleared. To demonstrate what you said, I used __forceinline instead of __inline in delay_loop1 function.
__forceinline void delay_loop1( ) { register uint32_t i = 500; for (; i; --i) { __NOP(); } }
Can I ask one more question? This is about optimizations in my delay function.
How about using volatile qualifier? Does it still non rely delay function??
__inline void delay_loop1( ) { volatile register uint32_t i = 500; for (; i; --i) { __NOP(); } }
Thanks,
Most probably, the compiler has already added a magic marker to the __NOP() intrinsic to make sure that the compiler knows that the nop instruction should be seen as required even if it isn't seen to generate any side effect.
The reason the compiler does support the __NOP() intrinsic, is to allow extremely short delays between two other instructions. Some ARM chips with an external interrupt handler required one or more nop to delay the processor until enable/disable interrupt had been effectuated because of the signaling delay between core and interrupt controller.
And it's also common when togging I/O pins that there might be a need for one or more clock cycles of setup/hold times.
But the important thing is that you can't much control what code the compiler produces for a "dumb" busy-loop. So it's better to use a timer for your delays. Either with interrupt or the code may busy-loop polling the current timer value or timer zero-count flag.