From c657fe17e7c67545e3334fa2c1b4129f8a5e07f4 Mon Sep 17 00:00:00 2001 From: Ridha Noomane Date: Thu, 5 Dec 2024 15:25:54 +0100 Subject: [PATCH] Add Os Scheduler --- .gitignore | 1 + LPC55S69_cm33_core0_flash.scf | 4 +- RidhaOs/Inc/ridhaOs.h | 26 ++++++ RidhaOs/Inc/ridhaOsKernel.h | 15 ---- RidhaOs/Inc/ridhaOsScheduler.h | 23 ++++++ RidhaOs/Inc/timebase.h | 14 ---- RidhaOs/RIDHAOS_CONF.h | 17 +++- RidhaOs/Src/ridhaOs.c | 85 ++++++++++++++++++++ RidhaOs/Src/ridhaOsKernel.c | 16 ---- RidhaOs/Src/ridhaOsScheduler.c | 140 +++++++++++++++++++++++++++++++++ RidhaOs/Src/timebase.c | 71 ----------------- main.c | 60 +++++++++++--- 12 files changed, 339 insertions(+), 133 deletions(-) create mode 100644 RidhaOs/Inc/ridhaOs.h delete mode 100644 RidhaOs/Inc/ridhaOsKernel.h create mode 100644 RidhaOs/Inc/ridhaOsScheduler.h delete mode 100644 RidhaOs/Inc/timebase.h create mode 100644 RidhaOs/Src/ridhaOs.c delete mode 100644 RidhaOs/Src/ridhaOsKernel.c create mode 100644 RidhaOs/Src/ridhaOsScheduler.c delete mode 100644 RidhaOs/Src/timebase.c diff --git a/.gitignore b/.gitignore index ad54b07..97e3441 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ **/Objects **/Listings **/DebugConfig +**/.vscode/ osProject.uvguix.nxf54496 diff --git a/LPC55S69_cm33_core0_flash.scf b/LPC55S69_cm33_core0_flash.scf index b1ec872..2b13a8e 100644 --- a/LPC55S69_cm33_core0_flash.scf +++ b/LPC55S69_cm33_core0_flash.scf @@ -31,13 +31,13 @@ #if (defined(__stack_size__)) #define Stack_Size __stack_size__ #else - #define Stack_Size 0x0400 + #define Stack_Size 0x1000 #endif #if (defined(__heap_size__)) #define Heap_Size __heap_size__ #else - #define Heap_Size 0x0400 + #define Heap_Size 0x1000 #endif #define m_interrupts_start 0x00000000 diff --git a/RidhaOs/Inc/ridhaOs.h b/RidhaOs/Inc/ridhaOs.h new file mode 100644 index 0000000..5bdcf82 --- /dev/null +++ b/RidhaOs/Inc/ridhaOs.h @@ -0,0 +1,26 @@ +#ifndef __R_KERNEL_H__ +#define __R_KERNEL_H__ + +#include "RIDHAOS_CONF.h" +#include "ridhaOsScheduler.h" +/* This Struct used to restore next thread and save the running thread */ +typedef struct tControlBlock +{ + int32_t * stackPt; + struct tControlBlock * nextPt; +}tControlBlock_t; + +/* Define typdef of static task to execute in the future */ +#if (USE_STATIC_THREAD) +typedef void(*StaticTask)(void); +#endif + + + +uint8_t ridhaOsAddThreads(StaticTask fn0, StaticTask fn1, StaticTask fn2); + +void ridhaOsStart(void); + + + +#endif /* __R_KERNEL_H__ */ \ No newline at end of file diff --git a/RidhaOs/Inc/ridhaOsKernel.h b/RidhaOs/Inc/ridhaOsKernel.h deleted file mode 100644 index 7cc7700..0000000 --- a/RidhaOs/Inc/ridhaOsKernel.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __R_KERNEL_H__ -#define __R_KERNEL_H__ - -#include "RIDHAOS_CONF.h" - -/* This Struct used to restore next thread and save the running thread */ -typedef struct tControlBlock -{ - int32_t * stackPt; - struct tControlBlock * nextPt; -}tControlBlock_t; - - - -#endif /* __R_THREAD_H__ */ \ No newline at end of file diff --git a/RidhaOs/Inc/ridhaOsScheduler.h b/RidhaOs/Inc/ridhaOsScheduler.h new file mode 100644 index 0000000..b7fe034 --- /dev/null +++ b/RidhaOs/Inc/ridhaOsScheduler.h @@ -0,0 +1,23 @@ +#ifndef __R_SCHEDULER_H__ +#define __R_SCHEDULER_H__ + +#include "ridhaOs.h" + + +#include "RIDHAOS_CONF.h" +#include + +uint32_t ridhaOsSchedulerGetTick(void); +void ridhaOsSchedulerDelayS(uint32_t delay); +void ridhaOsSchedulerDelayMS(uint32_t delay); +void ridhaOsSchedulerInit(void); +inline void ridhaOsSchedulerStart(void) +{ + /* Enable Systick */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; +} + +void ridhaOsSchedulerLaunch(void); + + +#endif /* __R_SCHEDULER_H__ */ \ No newline at end of file diff --git a/RidhaOs/Inc/timebase.h b/RidhaOs/Inc/timebase.h deleted file mode 100644 index 4aa29cc..0000000 --- a/RidhaOs/Inc/timebase.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __TIMEBASE_H__ -#define __TIMEBASE_H__ - -#include "RIDHAOS_CONF.h" -#include - - -uint32_t get_tick(void); -void delay_s(uint32_t delay); -void delay_ms(uint32_t delay); - -void timebase_init(void); - -#endif /* __TIMEBASE_H__ */ \ No newline at end of file diff --git a/RidhaOs/RIDHAOS_CONF.h b/RidhaOs/RIDHAOS_CONF.h index ad33d47..7960ba0 100644 --- a/RidhaOs/RIDHAOS_CONF.h +++ b/RidhaOs/RIDHAOS_CONF.h @@ -1,20 +1,29 @@ #ifndef __R_CONFIGURATION_H__ #define __R_CONFIGURATION_H__ +#warning Be Sure to configure this file, when you start your project. + /* Here Define your MCU REGISTER MAP FILE */ #include "fsl_device_registers.h" +#define CPU_ARM_VERSION 33 /* SysTick Configuration for TimeBase */ extern uint32_t SystemCoreClock; -#define CPU_CLOCK_HZ SystemCoreClock // Use Default System Clock in Hz -#define MAX_DELAY 0xFFFFFFFFU // Max Wayt Delay -#define TICK_RATE_HZ 1000 // Getting SystemCoreClock divide by 1000 to get interrupt every 1ms +#define CPU_CLOCK_HZ SystemCoreClock // Use Default System Clock in Hz +#define MAX_DELAY 0xFFFFFFFFU // Max Wayt Delay +#define TICK_RATE_HZ 1000U // Getting SystemCoreClock divide by 1000 to get interrupt every 1ms +#define MAX_DELAY 0xFFFFFFFFU // MAX DELAY +#define ROUND_ROBIN_QUANTA 10U // QUANTA For round robin schedular change tasks. /* Thread Configuration Size and Number Max for TCB */ -#define NUM_OF_THREADS 3 +#define USE_STATIC_THREAD 1 +#define USE_DYNAMIC_THREAD 0 +#define NUM_OF_THREADS 3 #define STACKSIZE 100 + + #endif /* __R_CONFIGURATION_H__ */ \ No newline at end of file diff --git a/RidhaOs/Src/ridhaOs.c b/RidhaOs/Src/ridhaOs.c new file mode 100644 index 0000000..eb53564 --- /dev/null +++ b/RidhaOs/Src/ridhaOs.c @@ -0,0 +1,85 @@ +#include "ridhaOs.h" + +/* Define a fixed linked list of Stack */ +tControlBlock_t tcbs[NUM_OF_THREADS]; + +/* Define current Pointer to point to first of the list of Stack*/ +tControlBlock_t * currentPt; + +/* Each Thread will have STACKSIZE * 4. */ +int32_t TCB_STACK[NUM_OF_THREADS][STACKSIZE]; + +void ridhaOsStackInit(int i) +{ + tcbs[i].stackPt = &TCB_STACK[i][STACKSIZE - 16]; + + /* Set bit24 Thumb state bit to one, operate in thumb mode */ + TCB_STACK[i][STACKSIZE-1] = (1U << 24); // PSR register + +#ifdef DEBUG + /* @Note: Block below need to delete after for debug purpose */ + /* Dummy stack content */ + TCB_STACK[i][STACKSIZE-3] = 0xAAAAAAAA; // R14(LR) + TCB_STACK[i][STACKSIZE-4] = 0xAAAAAAAA; // R12 + TCB_STACK[i][STACKSIZE-5] = 0xAAAAAAAA; // R3 + TCB_STACK[i][STACKSIZE-6] = 0xAAAAAAAA; // R2 + TCB_STACK[i][STACKSIZE-7] = 0xAAAAAAAA; // R1 + TCB_STACK[i][STACKSIZE-8] = 0xAAAAAAAA; // R0 + + TCB_STACK[i][STACKSIZE-9] = 0xAAAAAAAA; // R11 + TCB_STACK[i][STACKSIZE-10] = 0xAAAAAAAA; // R10 + TCB_STACK[i][STACKSIZE-11] = 0xAAAAAAAA; // R9 + TCB_STACK[i][STACKSIZE-12] = 0xAAAAAAAA; // R8 + TCB_STACK[i][STACKSIZE-13] = 0xAAAAAAAA; // R6 + TCB_STACK[i][STACKSIZE-14] = 0xAAAAAAAA; // R7 + TCB_STACK[i][STACKSIZE-15] = 0xAAAAAAAA; // R5 + TCB_STACK[i][STACKSIZE-16] = 0xAAAAAAAA; // R4 +#endif +} + +#if (USE_STATIC_THREAD) +uint8_t ridhaOsAddThreads(StaticTask fn0, StaticTask fn1, StaticTask fn2) +{ + /* Disable Global interrupts */ + __disable_irq(); + tcbs[0].nextPt = &tcbs[1]; + tcbs[1].nextPt = &tcbs[2]; + tcbs[2].nextPt = &tcbs[0]; + + /* Init Stacks for first thread */ + ridhaOsStackInit(0); + + /* Init Program counter (PC) to task functions */ + TCB_STACK[0][STACKSIZE-2] = (int32_t)(fn0); + + /* Init Stacks for first thread */ + ridhaOsStackInit(1); + + /* Init Program counter (PC) to task functions */ + TCB_STACK[1][STACKSIZE-2] = (int32_t)(fn1); + + /* Init Stacks for first thread */ + ridhaOsStackInit(2); + + /* Init Program counter (PC) to task functions */ + TCB_STACK[2][STACKSIZE-2] = (int32_t)(fn2); + + /* Start from thread 0 */ + currentPt = &tcbs[0]; + + /* Enable global IRQ */ + __enable_irq(); + + return 1; +} +#endif + +void ridhaOsStart(void) +{ + /* Init the Time base */ + ridhaOsSchedulerInit(); + + /* Launch schedular */ + ridhaOsSchedulerLaunch(); + +} diff --git a/RidhaOs/Src/ridhaOsKernel.c b/RidhaOs/Src/ridhaOsKernel.c deleted file mode 100644 index 92019ee..0000000 --- a/RidhaOs/Src/ridhaOsKernel.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "ridhaOsKernel.h" - -/* Define a fixed linked list of Stack */ -tControlBlock_t tcbs[NUM_OF_THREADS]; - -/* Define current Pointer to point to first of the list of Stack*/ -tControlBlock_t * currentPt; - -/* Each Thread will have STACKSIZE * 4. */ -int32_t TCB_STACK[NUM_OF_THREADS][STACKSIZE]; - -void ridhaOsKernalStackInit(int i) -{ - /* Set bit24 Thumb state bit to one, operate in thumb mode */ - TCB_STACK[i][STACKSIZE-1] = (1U << 24); // PSR register -} \ No newline at end of file diff --git a/RidhaOs/Src/ridhaOsScheduler.c b/RidhaOs/Src/ridhaOsScheduler.c new file mode 100644 index 0000000..3421fdf --- /dev/null +++ b/RidhaOs/Src/ridhaOsScheduler.c @@ -0,0 +1,140 @@ +#include "ridhaOsScheduler.h" + +/* Define current Pointer to point to first of the list of Stack*/ +extern tControlBlock_t * currentPt; +volatile uint32_t g_curr_tick; +volatile uint32_t g_curr_tick_p; +volatile uint32_t tick_freq = 1; + +uint8_t tick_freq_div = 1; + +static void tick_increment(void) +{ + g_curr_tick += tick_freq; +} + +static inline void ridhaOsSchedulerReset(void) +{ + /* Reset Systick configuration*/ + SysTick->CTRL = 0x0000; + + /* Clear Systick current Value */ + SysTick->VAL = 0; +} + +void ridhaOsSchedulerDelayS(uint32_t delay) +{ + ridhaOsSchedulerDelayMS(delay * 1000); +} + +void ridhaOsSchedulerDelayMS(uint32_t delay) +{ + uint32_t tickstart = ridhaOsSchedulerGetTick(); + uint32_t wait = delay; + if(wait < MAX_DELAY) + { + wait += (uint32_t)(tick_freq); + } + + while((ridhaOsSchedulerGetTick() - tickstart) < wait){} + +} + +uint32_t ridhaOsSchedulerGetTick(void) +{ + __disable_irq(); + g_curr_tick_p = g_curr_tick; + __enable_irq(); + return g_curr_tick_p; +} + +void ridhaOsSchedulerInit(void) +{ + /* Reset registers */ + ridhaOsSchedulerReset(); + + /* Reload the timer with number of MS */ + SysTick->LOAD = ((SystemCoreClock / TICK_RATE_HZ) + * ROUND_ROBIN_QUANTA) - 1; + + /* Clear Systick current value register */ + SysTick->VAL = 0x00; + + /* Select Internal Clock source */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; + + /* Set Systick to low priority */ + NVIC_SetPriority(SysTick_IRQn, 15); + + /* Enable SysTick interrupt */ + SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; + +} + + +void ridhaOsSchedulerLaunch(void) +{ + /* Load Address of currentPt into R0 */ + __asm("LDR R0, =currentPt"); + + /* Load R2 from address R0, i.e R2 =currentPt */ + __asm("LDR R2, [R0]"); + + /* Load Cortex M SP from address equals R2, i.e. SP = currentPt->stackPt */ + __asm("LDR SP, [R2]"); + + /* Restore r4, r5, r6, r7, r8, r9, r10, r11 */ + __asm("POP {R4-R11}"); + + /* Restore R12 */ + __asm("POP {R12}"); + + /* Restore r0, r1, r2, r3 */ + __asm("POP {R0-R3}"); + + /* Skip LR */ + __asm("ADD SP, SP, #4"); + + /* Create a new start location by poping LR */ + __asm("POP {LR}"); + + /* Skip xPSR by adding 4 to SP */ + __asm("ADD SP,SP, #4"); + + /* Enable global interrupt */ + __asm("CPSIE I"); + + /* Return from exception and restore r0 to r3, lr, pc, psr */ + __asm("BX LR"); + +} + +__attribute__((naked)) void SysTick_Handler(void){ + + /* SUSPEND CURRENT THREAD */ + /* DISABLE GLOBAL INTERRUPTS */ + __asm("CPSID I"); + /* Save Other Register not pushed by interrupt (R4->R11) */ + __asm("PUSH {R4-R11}"); + /* Load Address of currentPT int R0 */ + __asm("LDR R0, =currentPt"); + /* Load r1 from address equals r0, i.e r1 =currentPt */ + __asm("LDR R1, [R0]"); + /* Store Cortex-M SP at address equales to R1, i.e save SP into tcb */ + __asm("STR SP, [R1]"); + + /* CHOOSE NEXT THREAD */ + /* Load r1 from a location 4 bytes above address r1, i.e next r1 =currentPt->next*/ + __asm("LDR R1, [R1,#4]"); + /* Store r1 @Address equals r0, i.e currentPt = r1 */ + __asm("STR R1, [R0]"); + /* Load Cortext M SP from @ equals r1, i.e SP = current->stackPt */ + __asm("LDR SP, [R1]"); + /* Restore R4-R11 registers */ + __asm("POP {R4-R11}"); + /* Enable global interrupt */ + __asm("CPSIE I"); + /* Return from exception and restore r0 to r3, lr, pc, psr */ + __asm("BX LR"); + +} \ No newline at end of file diff --git a/RidhaOs/Src/timebase.c b/RidhaOs/Src/timebase.c deleted file mode 100644 index bd0129c..0000000 --- a/RidhaOs/Src/timebase.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "timebase.h" - - -#define CTRL_ENABLE (1U<<0) -#define CTRL_TICKINT (1U<<1) -#define CTRL_CLKSRC (1U<<2) -#define CTRL_COUNTFLAG (1U<<16) -#define MAX_DELAY 0xFFFFFFFFU - -volatile uint32_t g_curr_tick; -volatile uint32_t g_curr_tick_p; -volatile uint32_t tick_freq = 1; - -uint8_t tick_freq_div = 1; - -void tick_increment(void) -{ - g_curr_tick += tick_freq; -} - -void delay_s(uint32_t delay) -{ - delay_ms(delay * 1000); -} - -void delay_ms(uint32_t delay) -{ - uint32_t tickstart = get_tick(); - uint32_t wait = delay; - if(wait < MAX_DELAY) - { - wait += (uint32_t)(tick_freq); - } - - while((get_tick() - tickstart) < wait){} - -} - -uint32_t get_tick(void) -{ - __disable_irq(); - g_curr_tick_p = g_curr_tick; - __enable_irq(); - return g_curr_tick_p; -} - -void timebase_init(void) -{ - /* Reload the timer with number of cycles per second */ - SysTick->LOAD = (SystemCoreClock / 1000) - 1; - - /* Clear Systick current value register */ - SysTick->VAL = 0x00; - - /* Select Internal Clock source */ - SysTick->CTRL = CTRL_CLKSRC; - - /* Enable interrupt */ - SysTick->CTRL |= CTRL_TICKINT; - - /* Enable Systick */ - SysTick->CTRL |= CTRL_ENABLE; - - /* Enable Global Interrupt */ - __enable_irq(); - -} - -void SysTick_Handler(void){ - tick_increment(); -} \ No newline at end of file diff --git a/main.c b/main.c index 92aa24f..897c1c6 100644 --- a/main.c +++ b/main.c @@ -1,24 +1,62 @@ #include "led.h" #include "uart.h" #include "fsl_debug_console.h" -#include "timebase.h" #include "fsl_power.h" +#include "fsl_common.h" +#include "ridhaOs.h" -int main(){ +typedef uint32_t TaskProfiler; +TaskProfiler Task0_Profiler, Task1_Profiler, Task2_Profiler; + +void task0(void); +void task1(void); +void task2(void); +void SystemInitHook() +{ SystemCoreClockUpdate(); - uart_init(); - led_init(); - timebase_init(); + __set_MSPLIM(0x20000000); - PRINTF("LPC55S69 ..............\n\r"); +} - while (1) +int main(void){ + + SystemInitHook(); + /*Add threads */ + ridhaOsAddThreads(&task0, &task1, &task2); + ridhaOsStart(); + + /* We can't reach this point of program */ + +} + + +void task0(void) +{ + Task0_Profiler = 0; + while(1) { - delay_s(1); - PRINTF("A second just occured!!\n\r"); - - + //PRINTF("Task 0"); + Task0_Profiler++; } } +void task1(void) +{ + Task1_Profiler = 0; + while(1) + { + //PRINTF("Task 1"); + Task1_Profiler++; + } +} + +void task2(void) +{ + Task2_Profiler = 0; + while(1) + { + //PRINTF("Task 2"); + Task2_Profiler++; + } +}