This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Custom RTOS - general ideas veryfication

Greetings Community !

Im currently working on my custom real time kernel project (STM32F7). It was really in mature stage of developement, when i figured that its not compleately ISR safe, gets stucked sometimes, corrupts some data etc. Im rebuilding it and right now and need some clarifycation about certain things which I could made wrong back then. Lets start !

Question 1: Is my interrupt flow ok ?

- Im currently using 3 interrupts: SysTick (cyclical maintenance, scheduling), PendSV (task yielding, context saving/switching), SVCall (starting first task)

Question 2: Should SysTick and PendSV have equal and lowest priority ?

Question 3: Is it ok to yield task just by pending SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk ?

- PendSV is an interrupt so it does not call its handler immediately. Does only pending this bit ensures that the code wouldn't go any further and reach invalid data? (i.e when task is waiting for semaphore). When in debug mode it looks like code goes beyond this point and unprepared data could be reached (but maybe its only debugger prespective). freeRTOS adds __DSB() + __ISB(), but they are commenting it to be unnecessary.

Question 4: Kernel is using global pointer to actual task. Is it a good practice? Should it be volatile pointer or not?

- This methodology was forced by asm functions. Global variable can be referenced there.

Question 5: Is my context save/switch code is safe ? Could it be optimised ?

// for saving

"cpsid     i                       \n" // disable all interrupts
"mrs       r12,    psp             \n" // load psp to r12
"stmdb     r12!,   {r4 - r11}      \n" // store r4-r11 registers
"ldr       r0,     =_current_task  \n" // load pointer to pointer tocurrent tcb
"ldr       r0,     [r0]            \n" // load pointer to current tcb
"str       r12,    [r0,#16]        \n" // store r12 (new top of stack)

"cpsie     i                       \n" // enable all interrupts
"isb                               \n" // isb
"dsb                               \n" // dsb
"bx        lr                      \n" // branch back

.
// for switching

"cpsid     i                       \n" // disable all interrupts
"ldr       r0,     =_current_task  \n" // load pointer to pointer to current tcb
"ldr       r0,     [r0]            \n" // load pointer to current tcb
"ldr       r0,     [r0,#16]        \n" // load SP value

"ldmia     r0!,    { r4 - r11 }    \n" // load r4-r11 registers
"msr       psp,    r0              \n" // update psp
"movs      lr,     #0xFFFFFFFD     \n" // prepare branch code

"cpsie     i                       \n" // enable all interrupts
"isb                               \n" // isb
"dsb                               \n" // dsb
"bx        lr                      \n" // branch back to thread

.

Question 6: Should scheduling be marked as critical section ?

- Disable all interrupts or maybe just rise BASEPRI ?

Question 7: User code modyfing kernel objects (i.e semaphore signaled from user code -> semaphore waiting list must be flushed to kernel ready list). Is it a really bad practice ?

- That code should be also marked as critical section. Any other way to tackle this problem?

Question 8: How to verify correctness of RTOS working in ISR heavy enviroment ?

- Currently im using agressive timer update interrupt alongside with RTOS working. Is it sufficient ?

Uff ! Thats all ! If any of you have some idea on any of this do not hesistate to help !!

Thanks in advance