Hi smart guys out there,
I am using µVision with TIs eval-kit LM3S9B92. I use µVisions C-Compiler.
I learned that it is not possible to read the CPU-Registers with C and I have to use asembler for that.
I have no idea of asembler and actually I don't work with it in future and I hope I never have to again :-) ...but right now I need to know the status of the carrybit.
So all I am asking is for a piece of code that gets me the status of bit 29 in the register 17 :) and how to implement that in my project.
I hope this doesn't sound sassy ;-) - at least it isn't meant that way.
Thank you so much.
A little clue:
int32u __asm processor_in_user_mode(void) { STMDB R13!, {R1} MRS R0, CPSR AND R0, R0, #0x1F // the lowest 5 bits of CPSR respresent the processor mode MOV R1, #0x10 // user mode = 0x10 CMP R0, R1 BEQ not_interrupt_context LDMIA R13!, {R1} // restore the file name and the line number. MOV R0, #0x0 // indicate called while not in user mode BX LR not_interrupt_context // restore original values of R1 LDMIA R13!, {R1} MOV R0, #0x1 // indicate called while in user mode BX LR }
Assuming you are working with an ARM7 core, you are interested in CRSR. What is that according to the user manual...?
For the sake of completeness -
STMDB R13!, {R1}
and
LDMDB R13!, {R1}
above can be discarded.
you are interested in CRSR -> you are interested in CPSR
Hey Tamir, thanks for your fast reply.
I am working on an ARM Cortex-M3. CPSR was unknown to the compiler, but APSR wasn't :) Anyways, I placed your code (with CPSR changed to APSR) in a new .c file and it compiled without grumping :]
For evaluation I tried that:
int main(void) { unsigned long dummy; unsigned long a=1000; unsigned long b=10000; dummy = a - b; //Carry-bit should be set UARTprintf("\n: %d \n", processor_in_user_mode); dummy = b - a;//Carry-bit shouldn't be set UARTprintf("\n: %d \n", processor_in_user_mode);
but both times it prints out '489' which is:
111101001
so nothing changed. But register 17 bit 31 is according to the datasheet the carry bit, which should have changed here... I also tried PSR instead of APSR: no change
By the way: CPSR is printed bold in code, PSR or APSR isn't.
Hi Susan
Couple of options:
Use this standardized CMSIS function portable between popular toolchains
__get_APSR(void)
Or use MDK/RVCT specific named register variables
uint32_t apsr __asm("APSR"); if (apsr & APSR_C) // do this else // do that
Hope this helps Marcus
Note that you can manage quite well without ever knowing the content of the carry bit.
if (b >= a) { b -= a; // no borrow } else { b -= a; // handle borrow }
unsigned a,b,c; c = a+b; if (c < a || c < b) { // addition overflow }
Marcus, I tried yours, too.
Do I need a special header or include file for this? Cause µVision tells me:
undefined symbol __get_APSR();
identifier "APSR_C" is undefined, respectively (when trying the other one)
__get_APSR() is defined in CMSIS, so yes, you do need to include a header file, namely core_cmFunc.h.
The identifier APSR_C was just a made up example, perhaps defined as macro, to demonstrate that you need to compare with a numeric value. BTW, CMSIS also defines a structure APSR_Type so that you could perhaps write something like:
if ((APSR_Type)apsr.b.C) // do this else // do that
But as others have said already: For your purposes, this is completely unnecessary.
Best regards Marcus