HI All,
I am trying to use FREE RTOS in cortex R5 dual core MCU.
Initially the MCU is in Supervisor mode. But in main function, i want to be a processor mode will be in system mode(0x1F).
But i do not find any instruction how to switch from supervisor mode(0x13) to system mode(0x1F).
Why we need to switch from supervisor mode to system mode if both are working in privilege mode because for the unitization of the RTOS, scheduler should be in system mode.
Can any one please tell me how to switch from supervisor mode to system mode.
I have tried to switch but the system will be reset automatically after change in system mode.
have see the mode in CPSR register.
Thanks and regard
Pankaj verma
In your write-back instruction, you use r0, not r1. Is this the issue?
HI Synnott,
I applogize this print mistake.
But actual case is
.def _CPU_system_mode_Switch .asmFunc_CPU_system_mode_Switch
MRS r0, CPSR ;read cpsr into r0 orr r0, r0, #0x1f ; set mode to SYS MSR CPSR, r0 ; write r0 back to cpsr bx lr ; return
.endasmfunc
After execution of this instruction system is going to reset condition and MCU System register shows SWRST.
When you switch to SYS mode, a different LR (and SP) will be banked in, and so the return address is corrupt.
Do you have a debugger attached? You should be able to step through the code and see what occurs.
thanks for your quick reply.
Yes you are right the LR register and SP register is clearing. and system is going to reset.
I am attaching few images for reference
This is before calling switching function
This is before MSR instruction
This is after MSR instruction
Can you please let me know why this happen?
How we solve this problem?
Thanks
Pankaj Verma
This seems correct to me.
The MSR instruction switches to SYS mode, and so new LR and SP are banked in. The LR of SYS mode is 0x0, and so when the BX instruction executes, you branch back to that address, which is most likely also your reset vector.
thanks again for your quick reply.
Yes you are correct
After execution of MSR instruction Mode is showing system mode and than the value at LR and SP register is 0x00000000.
If BX instruction is calling it is going to reset vector.
Is It possible?
"can i store LR and SP register value to R1 register and than update data of R1 to LR again before BX instruction".
I would not describe it as a 'problem'. the processor is doing exactly what it is supposed to do.
I don't know the larger code block you are integrating this into, but generally such code would be inline rather than a function call (for exactly the reasons you are seeing).
What does your code do after switching to SYS? From your initial posting, it seems you just need to Branch to __main (or _start), and go to the start of your C application.
I tell you whole application scenario.
I am using TMS570LC43 MCU with RTOS. Here we are also using safeTI diagnostic library for MCU self test condition.
So initially when the system power ON the system work on Supervisor mode "0x13".
After initialization of all the CPU core registers, clock, RAM, Flash, other memory, peripherals etc.
The code going inside main loop. After that we need to initialize RTOS Scheduler.
For initialization of RTOS Scheduler we need to change mode from supervisor to system mode otherwise the schedular will not successfully initialize. The scheduler is fail.
And for safeTI diagnostic we need to run all the safety test cases in supervisor mode only.
That is the reason we need to change from supervisor to system mode and after that we need to change it again in supervisor mode when the safety test will run again.
It is standard for an RTOS to run in SVC mode, and its applications to run in USR mode.
Applications running in SYS mode use the same physical registers as USR, but with privileged permissions.
I don't know why the scheduler init code would need to run in SYS specifically.
Assuming what you wish to do is valid... I've written (but not tested) code to switch to SYS. Would this work for you?
push {r0, r1, lr} // preserve r0, r1, lr on SVC stack mov r1, sp // copy sp_svc into r1 mrs r0, cpsr // read cpsr into r0 orr r0, r0, 0x1f // set mode bits to SYS msr cpsr, r0 // switch to SYS mode mov sp, r1 // copy sp_svc (r1) into sp_sys pop {r0, r1, pc} // return in SYS mode using SVC stack
Yes you are right and i have tried below code as per your suggestion.
It is jump to the supervisor mode to system mode by using below instruction.
MOV R1, LR MOV R2, SP MRS r0, CPSR //read cpsr into r0 orr r0, r0, #0x1f //set mode to SYS MSR cpsr, r0 //write r0 back to cpsr MOV LR, R1 MOV SP, R2 bx lr //return .endasmfunc
Is it correct?
I will also try your code.
Can you tell me that, if a application jump to system mode to supervisor mode at any time and vise versa . It will not effect to running application and RTOS behavior's.
Thanks for your great help, Have a nice day.
The code looks correct to me, but as I said, I don't believe this is really what you want to do...
Your application should run in SYS mode (ideally USR mode), and the RTOS in SVC mode, with independent stacks. The RTOS will manage switching between applications.
Regards. Ronan