Following code is used to generate delays on a cortex M0.
// for Cortex-M0 (subs for Cortex-M3) void y_delay_3x_cycles(uint32_t cycles) __attribute__((naked, used)); void y_delay_3x_cycles(uint32_t cycles __attribute__((unused))) { __asm( " sub r0, #1\n" " bne y_delay_3x_cycles\n" " bx lr" ); } #define CYCLES_PER_SECOND 12000000 void y_delay_us(uint32_t us) { y_delay_3x_cycles((us * CYCLES_PER_SECOND) / 3000000); } void y_delay_ms(uint32_t ms) { while (ms--) { y_delay_3x_cycles(CYCLES_PER_SECOND / 3000); } }
But when I compile with Keil, I get the following errors: ..\src\mp_micro.c(75): warning: #1207-D: unknown attribute "naked" void mp_micro_delay_3x_cycles(uint32_t cycles) __attribute__((naked, used)); ..\src\mp_micro.c(79): warning: #1267-D: Implicit physical register R0 should be defined as a variable " sub r0, #1\n" ..\src\mp_micro.c(79): error: #2829: Cannot perform desired action on condition flags " sub r0, #1\n" ..\src\mp_micro.c: 2 warnings, 1 error ___________________________________ I tried using a variable for the warning:
void mp_micro_delay_3x_cycles(uint32_t cycles __attribute__((unused))) { int regVariable; __asm( " sub regVariable, #1\n" " bne mp_micro_delay_3x_cycles\n" " bx lr" ); }
But still I get error #2829: Cannot perform desired action on condition flags
..\src\mp_micro.c(79): error: #2829: Cannot perform desired action on condition flags " sub r0, #1\n"
subs r0,r0,#1 ;??
If in-lining assembler is a problem, then put it in the startup_arch.s file
..\src\mp_micro.c(80): error: #2829: Cannot perform desired action on condition flags " sub regVariable, #1\n"
I'm trying to repair this. I've no idea on how this code could be moved to startup_MyArch.s file and then how to access that code through the current file (i.e. micro.c): Currently this code is written in micro.c file.
; In .C file extern void xx_delay_3x_cycles(uint32_t cycles); ; In .S file ;... xx_delay_3x_cycles PROC EXPORT xx_delay_3x_cycles subs r0, r0, #1 bne xx_delay_3x_cycles bx lr" ENDP ;...
Why does the compiler ignore "naked":
..\src\y.c(75): warning: #1207-D: unknown attribute "naked"
Why does the compiler ignore "naked"
What does the compiler manual say about the "naked" attribute?
I know the manual contains "used" but where did you find any documentation for "naked"? www.keil.com/.../armccref_babcighe.htm
Because it's not the GNU/GCC compiler? And it's not supported in Keil ARM compilers?
I did what u posted: Westonsupermare Pier ARM @ 7-Oct-2014 04:33 GMT . So I edited the .c and .s files.
Now I'm getting this error: .\obj\MyProj.axf: Error: L6218E: Undefined symbol xx_delay_3x_cycles (referred from xx_micro.o). Trying to figure out this error. Your feedback is valuable Mr. Pier. Thanks!
Note that the C language has a convention that a '_' is added first in the external symbol name - this is done to make sure that the C program has it's own "name space" that doesn't collide with assembler routines in the startup code etc.
So your C code might look for a symbol named _xx_delay_3x_cycles while your assembler code exports a symbol without any leading underscore.
So I made the following change (ONLY) in the .s file: I added an '_' infront of the function name:
;Delay 3x funtion _xx_delay_3x_cycles PROC EXPORT _xx_delay_3x_cycles subs r0, r0, #1 bne _xx_delay_3x_cycles bx lr" ENDP
But, I'm still getting the same error: .\obj\MyProj.axf: Error: L6218E: Undefined symbol xx_delay_3x_cycles (referred from xx_micro.o).
Not the problem here, most probably not assembling file, or not linking object.
Need to lose the quote after the lr, seems to have gotten in my cut and paste
Hi Pier,
I've this at the end of the startup_xx.s file:
;Delay 3x funtion xx_delay_3x_cycles PROC EXPORT xx_delay_3x_cycles subs r0, r0, #1 bne xx_delay_3x_cycles bx lr ENDP ;End of the file startup_xx.s
In the xx_micro.c file:
extern void xx_delay_3x_cycles(uint32_t cycles); //In this C file the funtion xx_delay_3x_cycles(CYCLES_PER_SECOND / 3000); is called a few times
still getting the same error: .\obj\MyProj.axf: Error: L6218E: Undefined symbol xx_delay_3x_cycles (referred from xx_micro.o).
And is it actually assembling the startup_xx.s file and creating the startup_xx.o file, is that being linked? Can you see the code in the .LST file?
Make sure the code is *not* after the END directive in the assembler file.
"Make sure the code is *not* after the END directive in the assembler file."
That's a classic mistake - quite a lot of different assemblers who has an "end" directive and silently allows any excess data after the end directive.
Thanks Pier. Included the assembly file thanks. Compile without an error. Hope this ASM code create a 3 cycles per loop.