We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
is it quite normal, that a arm9 microcontroller starts in the supervisor mode? How could I changed the mode into user mode? Or is it better to work in the supervisor mode?
I've only the startup file and a short main.c file
#include <stdio.h> int main(void) { while(1); }
In the startup file I only can see that every mode will be initialized.
best regards tobi
Could you tell me where I can find this documentation? I'm working with the MDK package.
It should be included in the on-line documentation/library.
Alternatively, like all other documentation, it can be found on the Keil web site:
http://www.keil.com/support/man/docs/armlink/
now I have my own scatter-file included (Options-for-target -> linker)
I have no specific settings for the R/O and R/W base (because there are in the scatter file)...
but now the controller starts in the supervisor mode again... Are there any misc controls I can use so that the controller will start up in user mode??
tobi
Are there any misc controls I can use so that the controller will start up in user mode??
The controller cannot "start up" in user mode, since it'd be stuck in user mode forever if it did.
If the controller is in supervisor mode, you can enter user mode by setting the mode bits in the CPSR register appropriately. Note that this is a one-way road - once you're in user mode, you cannot simply get back to a privileged mode by manipulating the mode bits - doing so will generate an exception.
that means, I can't go back to supervisor mode during the program is running in user mode. But when I erase the code, I have the abilitiy to go back into the supervisor mode if I don't change the CPSR register.
The problem is, that my usart1 doesn't work in supervisor mode - it only works in the user mode. I don't know if that is normal.
And it is still normal that the processor starts the main function in user mode, if you select (option for target -> linker) "use memory layout from target dialog"?
when I take a look into my startup code file, the processor has to start in user mode (and the processor always starts in user mode as long as I don't use a separate scatter-file...)
; Enter User Mode and set its Stack Pointer MSR CPSR_c, #Mode_USR
It's the last mode in the startup code file. After this line the processor enter the c-code main function...
the other thing I don't understand is that the uasrt is not working - could there be a problem with the stack size within the supervisor stack size? I get no error during the program but I get no output by usart, too.
Moreover is it not common to run the whole programm in user mode and only if a excerption occured it runs in FIQ, IRQ mode or SWI mode, where I could changed mode...?
Is it a good choice to change the mode in the startup code file? but where? there are init-area for each mode - and the last mode is the user mode (is it not right, that the last mode is the mode where the processor starts the c-file code? And in the user mode is no I-bit or F-bit set?
maybe anyone of you have a explanation for me - why I'm not able to get into user mode...
I have nothing changed in the startup code file...
; Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit MOV SP, R0 SUB R0, R0, #SVC_Stack_Size ; Enter User Mode and set its Stack Pointer MSR CPSR_c, #Mode_USR IF :DEF:__MICROLIB EXPORT __initial_sp ELSE MOV SP, R0 SUB SL, SP, #USR_Stack_Size ENDIF ; Enter the C code IMPORT __main LDR R0, =__main BX R0 IF :DEF:__MICROLIB EXPORT __heap_base EXPORT __heap_limit ELSE
My C-code is as small as possible - one file one function...
int main(void) { while(1); }
the only thing I changed was that I installed the scatter-file (options for target -> linker)...
From this moment on, I'm not able to get into the user mode, when I start the application. When I use no scatter-file, the processor will start up in user mode... Is there a option in the keil enviroment, which I must select to run in user mode...
I'm right if I say that I'm only able to install my own scatter file in supervisor mode? And therefore the processor will start up (the main function) in supervisor mode? How can I changed to the user mode within the main function? Or is it better to change to the user mode within the startup file?
MSR CPSR_c, #Mode_USR
ok I know my mistake - it was in the scatter file... I forgot to install the *.o (RESET, +First) directive.
But could somebody explain me why the processor enters in the supervisor mode, if this directive are not installed?
It has already been explained to you. The processor always starts in it's toughest mode.
It needs to process instructions that tells it to enter user mode. With a broken scatter file, the application startup code is not run, so no instruction switches the processor into the user mode.
Yes I know that there must be an explanation which defines the user mode. And now I understand why it is not working in the user mode, because I never enterd the startup code file (because I have not installed a suitable section for it...) -> thanks for your answer - now it is clear for me.
Which sections are recommend to install in such a scatter-file? I have one section for the external flash (with the startup-code included), one section for the internal RAM and one section for the external RAM (only for the use of big structures and buffers from the peripherie).
But is it for example recommend to install my own heap and stack size within the scatter-file - or the vector table (for data abort handler, undefined handler and so on)?
How is it possible to install one section only for incomming data from all peripherials e.g. usart or usb. Do I have to install only a EMPTY section?
ARM_SECTION 0x20000000 EMPTY 0x8000
and now I'm able to say
int *ptr_buffer = 0x20000000;
Now I want to use two load regions - one for each storage (flash and internal ram) - but now I get the error No Algorithm found for: 00200000H - 0020000FH
LOAD_FLASH 0x10000000 0xFFFFFF ; start address and length { EXTERN_FLASH 0x10000000 { *.o (RESET, +First) *(+RO) } } LOAD_SRAM 0x00200000 0xFFFFF { INTERN_RAM 0x00200000 { *(+RW,+ZI) } }
The internal RAM is from 0x00200000 to 0x002FFFFF.
Now I get another stupid error - I have one section for one c-file (only +RW, +ZI) and the +RO data of this section where placed by the compiler to the default address 0x0000000. I thought that it would be enough to create one region with *(+RO) where all RO data would be stored????
LOAD_FLASH 0x10000000 0xFFFFFF ; start address and length { EXTERN_FLASH 0x10000000 0xFFFFFF { RM9200.o (RESET, +First) *(+RO) } SRAM 0x20000000 0xFFFFFF { timer.o (+RW,+ZI) } BUFFER_SRAM 0x21000000 EMPTY 0x2000000 { } INTERN_RAM 0x200000 0xFFFFF { *(+RW,+ZI) } }
If I wrote
timer.o (+RO)
in the executing section EXTERN-FLASH
I get the warning, that the compiler will removed unused sections (timer.o (RO)).
But I want to have all RO data from the c-file timer.c within the external flash.