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 ;...
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).
View all questions in Keil forum