Context switching and systick handling on the STM32F series

interruptsrtosstackstm32f4

I am using a STM32F407 board to build my own tiny RTOS and I have some questions.

  1. How can I define my own stack in different memory location, so I can have one stack for each queue of tasks?

  2. How do I push and pop to those stacks in my systick handler, what registers?

  3. Systick handler works fine for me, but when I put a function in an infinite while loop it stops working, why is this?

Example code for 1 and 2 would be very appreciated.

My current code is below:

#ifdef __cplusplus
extern "C" {
#endif
void SysTick_Handler(void) {
    /*1-Mask all interrupts except for E programs dependency*/
    OSD_maskUnE_Interuppts();
    OSD_SystimerISR();
}
#ifdef __cplusplus
}
#endif

int main(void) {
    SystemCoreClockUpdate();
    SysTick_Config(SystemCoreClock / 100);

    while (1) {}

    return 0;
}

Best Answer

1-how to define my own stack in different memory location one for each queue of tasks? i need example

You don't need to do anything special to allocate memory.

You can do it statically, or dynamically - it's up to you.

First decide how much memory you want for a stack, then create a variable of that size. For instance, a 1KB stack could be created as:

uint32_t stack[256];

(256 is 1024/4. 32 bis is 4 bytes). It's just memory. Nothing at all special.

The only special thing you need to do is set the stack pointer for a task or queue when you first create that task or queue. If you have a descending stack then you'd set it to the address of stack plus 1kB, so the top end of the stack.

2-how to push and pop to those stacks at systic handler ,what registers, i need example

You just need to store the stack pointer register somewhere. Where is entirely up to you. If you already have a structure with queue information in it, then just add a 32-bit integer (uint32_t) to that and store the stack pointer in it.

3-systick handler works fine for me ,when for testing i put a function in an infinite while loop ,it stop works,why???

Show us your code and we might be able to find out what's wrong with it. As it stands you're just saying "My car is broken. Why?".

The method I use for creating tasks is to first fill the TCB with all the right data, including the correct value for the stack pointer. The task is then marked as idle. When the scheduler selects the task it then loads the stack pointer you have already chosen into the SP register, then executes the task. When it switches out of that task the current SP is then stored back into the TCB for the task ready for the next time it's selected by the scheduler.