From: Robin Krens Date: Thu, 31 Oct 2019 11:25:29 +0000 (+0100) Subject: System Calls cleanup, multiple Processes and context switch X-Git-Url: https://robinkrens.nl/gitweb/?a=commitdiff_plain;h=9f7dfa3d2de5600111eb5c09dc1727b58a30be18;p=cortex-from-scratch System Calls cleanup, multiple Processes and context switch --- diff --git a/README.md b/README.md index 113cf6a..e9473b8 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,17 @@ port this code to any Cortex M0/M3/M4/M7 board. * Temperature sensor: drivers/tsensor.c [COMPLETED] * OLED display [PLANNED] * Joystick: drivers/mk450_joystick.c [COMPLETED] - * TFT Screen: drivers/st7735s.c, include/libs/fonts/wogfont.h [IN PROGRESS] + * TFT Screen: drivers/st7735s.c, include/libs/fonts/wogfont.h [COMPLETED] * Memory Management [IN PROGRESS] -- FILE: lib/pool.c -* User Mode [PLANNED] -* System Call PendV implementation [PLANNED] +* Kernel heap [COMPLETED] -- FILE: heap.c +* User Mode Switch [IN PROGRESS] +* System Calls [IN PROGRESS] -- FILE: syscall.c lib/syscall.c +* Scheduler based on PendSV system call [IN PROGRESS] * Stack trace debug [IN PROGRESS] -* Memory Protection Unit [PLANNED] +* Memory Protection Unit [SUSPENDED] (STM32F103 board has no MPU) * Loadable programs from EEPROM [PLANNED] -* Multiple processes and scheduling [PLANNED] +* Multiple processes [IN PROGRESS] -- FILES: process.h, main.c +* Driver "abstraction" [PLANNED] ## SCREENSHOTS Here are some screenshots that shows the terminal just after booting: diff --git a/lib/syscall.c b/lib/syscall.c index d844b43..34401c5 100644 --- a/lib/syscall.c +++ b/lib/syscall.c @@ -5,7 +5,7 @@ * Initial version * * $DESCRIPTION$ - * System calls for user functions + * System calls for various user functions * */ @@ -18,11 +18,11 @@ /* Arguments are placed in r0, r1, r2 by convention * And "parsed" to the the kernel * Right after the svc call, r0 contains status - * of call (ie. OK, NOTOK */ + * of call (ie. OK, SYSERR) */ int theos_uptime() { - asm volatile("svc 6"); + asm volatile("svc 7"); int ret; asm volatile("mov %0, r0" : "=r" (ret)); return ret; diff --git a/main.c b/main.c index ac01416..4eb79f9 100644 --- a/main.c +++ b/main.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -32,52 +33,18 @@ //#include #include -#include - +/* Example of multitasking */ process_t p1; process_t p2; uint32_t stackp1[500]; uint32_t stackp2[500]; -extern int count; - -void switch_usermode() { - - // user mode - //asm volatile ("mov r0, 0x1" "\n\t" - //"msr control, r0" "\n\t" - //"isb" "\n\t"); - - // system init call - -} - -void process1(void) { - - while(1) { - //uint32_t control = 0xFFFFFFFF; - printf("process 1\n"); - //asm volatile("msr control, %0" "\n\t" - // "dsb" : : "r" (control)); - //printf("control: %x", control); - //for(;;); - _block(100); - theos_switch(&p1, &p2); - } +void process1(void); +void process2(void); -} -void process2(void) { - while(1) { - printf("process 2\n"); - _block(100); - theos_switch(&p2, &p1); - } - -} -int test_data_segment = 99; void main() { @@ -116,38 +83,26 @@ void main() /* Real time clock */ rtc_init(); - -// printf("press any key to start\n"); -// asm volatile ("cpsid f"); // doesn't work in qemu - + /* Initialize SVC handler for system calls*/ syscall_init(); - //int ret; - //ret = theos_test(0x1, 0x2, 0x3); - //ret = theos_uptime(); - - //printf("ret: %d\n", ret); + /* System call test */ + int uptime = theos_uptime(); + printf("UPTIME: %d\n", uptime); - int size_stack = sizeof(stackp1); - - p1.stackptr = ((unsigned int) stackp1) + size_stack - 0x1C; - p1.stackptr[6] = (uint32_t) process1; - p1.stackptr[7] = 0x01000000; - p2.stackptr = ((unsigned int) stackp2) + size_stack - 0x1C; - p2.stackptr[6] = (uint32_t) process2; - p2.stackptr[7] = 0x01000000; - - theos_init(&p1); + /* Multi processes test */ +// int size_stack = sizeof(stackp1); +// p1.stackptr = ((unsigned int) stackp1) + size_stack - 0x1C; +// p1.stackptr[6] = (uint32_t) process1; +// p1.stackptr[7] = 0x01000000; +// p2.stackptr = ((unsigned int) stackp2) + size_stack - 0x1C; +// p2.stackptr[6] = (uint32_t) process2; +// p2.stackptr[7] = 0x01000000; +// theos_init(&p1); /* Cortex M* integrated systick, can be replaced * by the more accurate RTC. */ - -// systick_init(); - - // switch_usermode(); - - //printf("without system call"); -// theos_test(0xA1, 0xA2); + //systick_init(); /* Eeprom Driver eeprom_at24c_init(); @@ -169,7 +124,6 @@ void main() /* ADC Joystick module */ // mk450_init(); - /* Start up terminal */ terminal(); @@ -178,3 +132,21 @@ void main() } } + +void process1(void) { + + while(1) { + printf("process 1\n"); + _block(0xFFFFF); + theos_switch(&p1, &p2); + } + +} +void process2(void) { + while(1) { + printf("process 2\n"); + _block(0xFFFFF); + theos_switch(&p2, &p1); + } + +} diff --git a/syscall.c b/syscall.c index ba0dc9a..2250009 100644 --- a/syscall.c +++ b/syscall.c @@ -10,13 +10,14 @@ * | SYSTEM CALL | # | * |--------------------|-------| * | THEOS_INIT | 1 | - * | THEOS_DESTROY | 2 | - * | THEOS_RESCHED | 3 | - * | THEOS_GETC | 4 | - * | THEOS_CPUTS | 5 | - * | THEOS_UPTIME | 6 | - * | THEOS_OMNIGOD | 7 | - * | THEOS_TIME | 8 | + * | THEOS_CREATE | 2 | + * | THEOS_DESTROY | 3 | + * | THEOS_SWITCH | 4 | + * | THEOS_GETC | 5 | + * | THEOS_CPUTS | 6 | + * | THEOS_UPTIME | 7 | + * | THEOS_OMNIGOD | 8 | + * | THEOS_TIME | 9 | * | THEOS_MAGIC | 99 | * |----------------------------| * @@ -70,10 +71,9 @@ int sys_switch(process_t * currp, process_t * newp) { uint32_t chk_stackptr; asm volatile("mrs %0, psp" : "=r" (chk_stackptr)); //asm volatile("isb"); - printf("OLD: %x\n", currp->stackptr); - printf("NEW: %x\n", newp->stackptr); - printf("CHK: %x\n", chk_stackptr); - //for(;;); + //printf("OLD: %x\n", currp->stackptr); + //printf("NEW: %x\n", newp->stackptr); + //printf("CHK: %x\n", chk_stackptr); return 0; diff --git a/systick.c b/systick.c index 2c49820..f459512 100644 --- a/systick.c +++ b/systick.c @@ -21,31 +21,6 @@ #include #include -#define NUMB_TASKS 3 - -int count; -int next_task; -int curr_task; -uint32_t currentp; -uint32_t nextp; - -//struct proces { -// int32_t nr; -// uint32_t *stack_ptr; -// uint32_t mask; -//}; -// -//struct proces p1, p2, p3; -// -// -// uint32_t oldpsp; -// uint32_t newpsp; -// -//uint32_t task0_stack[50]; -//uint32_t task1_stack[50]; -//uint32_t task2_stack[50]; -//uint32_t PSP_array[3]; - struct interrupt_frame { uint32_t r0; // N-32 @@ -61,25 +36,7 @@ struct interrupt_frame { //__attribute__ ((interrupt)) void * systick_handler(/* struct interrupt_frame * frame */) { - //printf("Ticking...\n"); - //printf("Current task: %d", curr_task); - //count++; - - - - - //switch(curr_task) { - // case(0): next_task = 1; break; - // case(1): next_task = 2; break; - // case(2): next_task = 0; break; - // default: next_task = 0; break; - //} - - //if (curr_task != next_task) { - - - - //} + printf("Ticking...\n"); } @@ -114,10 +71,6 @@ uint32_t set_psp(uint32_t stackie) { void systick_init() { -// count = 0; -// curr_task = 0; -// next_task = 1; - /* Every time the counter counts down to zero * a systick exception is invoked. Systick has * exception number 15. in the vector table */ @@ -137,56 +90,4 @@ void systick_init() { rsetbit(STK_CTRL, 0); rsetbit(STK_CTRL, 1); -// extern void task0(void), task1(void), task2(void); -// -// int size_stack = sizeof(task0_stack); -// -// p1.stack_ptr = ((unsigned int) task0_stack) + size_stack - 0x1C; -// p1.stack_ptr[6] = (uint32_t) task0; -// p1.stack_ptr[7] = 0x01000000; -// p2.stack_ptr = ((unsigned int) task0_stack) + size_stack - 0x1C; -// p2.stack_ptr[6] = (uint32_t) task1; -// p2.stack_ptr[7] = 0x01000000; -// p3.stack_ptr = ((unsigned int) task0_stack) + size_stack - 0x1C; -// p3.stack_ptr[6] = (uint32_t) task2; -// p3.stack_ptr[7] = 0x01000000; -// -// set_psp(p1.stack_ptr[-7]); -// -// for(;;); - - /* Initialize processes */ - //PSP_array[0] = ((unsigned int) task0_stack) + sizeof(task0_stack) - 32*4; - //HW_ADDR(PSP_array[0] + 0x18) = (unsigned long) task0; - //HW_ADDR(PSP_array[0] + 0x1C) = 0x01000000; - //PSP_array[1] = ((unsigned int) task1_stack) + sizeof(task1_stack) - 32*4; - //HW_ADDR(PSP_array[1] + 0x18) = (unsigned long) task1; - //HW_ADDR(PSP_array[1] + 0x1C) = 0x01000000; - //PSP_array[2] = ((unsigned int) task2_stack) + sizeof(task2_stack) - 32*4; - //HW_ADDR(PSP_array[2] + 0x18) = (unsigned long) task2; - //HW_ADDR(PSP_array[2] + 0x1C) = 0x01000000; - - //extern void pendsv_handler; - - ivt_set_gate(14, pendsv_handler_c, 0); - - //set_psp((PSP_array[curr_task] + 32*4 )); - - //int startpsp = PSP_array[curr_task] + 16*4; - - //asm volatile ("msr psp, %0" : : "r" (startpsp)); - - - //asm volatile ("mov r0, 0x3" "\n\t" - //"msr control, r0" "\n\t" - //"isb" "\n\t"); - - //for(;;); - - //set current PSP - //printf("0: %x\n", PSP_array[0]); - //printf("1: %x", PSP_array[0]); - - //task0(); - }