There are multiple problems on implementing my projects.
Let me introduce my tries here.
There are three projects : OS1, OS2, Monitor.
The linker script has been modified so that the three projects can be stored in separate memory.
for Monitor
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
RAM1 (xrw) : ORIGIN = 0x20008000, LENGTH = 32K
FLASH1 (rx) : ORIGIN = 0x8020000, LENGTH = 128K
RAM2 (xrw) : ORIGIN = 0x20010000, LENGTH = 32K
FLASH2 (rx) : ORIGIN = 0x8040000, LENGTH = 128K
SHARED (xrw) : ORIGIN = 0x20018000, LENGTH = 32K
}
for OS1
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20008000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 128K
SHARED (xrw) : ORIGIN = 0x20018000, LENGTH = 32K
}
for OS2
MEMORY
{
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K
RAM (xrw) : ORIGIN = 0x20010000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8040000, LENGTH = 128K
SHARED (xrw) : ORIGIN = 0x20018000, LENGTH = 32K
}
I am configuring this system to assume that each project is an OS and to do context switching between OSs.
Anyway, I also modified SCB->VTOR before jumping to each project, so that each interrupt of each project work well.
The final thing I want to do is context switching between OSs.
Before implementing context switching, I tried to jump at the start of each projects, it worked well.
(Monitor Start -> OS1 Start -> Monitor Start -> OS2 Start -> Monitor Start......)
But when I put context switching on this code, it breaks.
Monitor Start -> OS1 Start -> Monitor Start -> OS2 Start -> Monitor Start -> From the part where OS1 was running // Break
I used TIM2 interrupt to get trigger of context switching, so when TIM2 Interrupt comes in, I set SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;, and PendSV_Handler Starts.
Here's the main questions.
I used TIM2 interrupts of OS1, OS2. But I found that when one project's pendsv_handler is executed, another project's pendsv_handler ignores setting the bit even though it has previously cleared it and just passes it.
Here's main context switching code I used :
Saving CONTEXT in OS1, OS2
void PendSV_Handler(void)
{
__asm("push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12}");
__asm("MRS r0, XPSR");
__asm("push {r0}");
__asm("MOV %0, SP" : "=r" (OS1_CONTEXT->SP));
SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk;
__asm volatile ("MOV %0, PC" : "=r"(OS1_CONTEXT->PC));
jumpToApplication(0x8000000, 0x20008000);//Jump to Monitor
}
Restoring Context in monitor
moveSP(OS1_CONTEXT->SP);
__asm("POP {R0}");
__asm("MSR XPSR, R0");
__asm("POP {R0,R1,R2,R3,R4,R5,R6,R7,R8,R9,R10,R12}");
movePC(OS1_CONTEXT->PC);
Saving Context seems working well, but when Restoring Context, especially on movePC(), it fails.
I've been thinking about it for over a week and I'm not sure which part to fix.
My english writing is so bad, so if you want me to give more information about my project, just tell me.
Thank you for reading my question...!