Context Switching between multiple projects on STM32CUBEIDE

39 views Asked by At

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.

  1. 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.

  2. 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...!

0

There are 0 answers