* 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:
* Initial version
*
* $DESCRIPTION$
- * System calls for user functions
+ * System calls for various user functions
*
*/
/* 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;
#include <lib/stdio.h>
#include <lib/string.h>
#include <lib/tinyprintf.h>
+#include <lib/syscall.h>
#include <drivers/uart.h>
#include <drivers/led.h>
//#include <drivers/mk450_joystick.h>
#include <drivers/st7735s.h>
-#include <lib/syscall.h>
-
+/* 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()
{
/* 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();
/* ADC Joystick module */
// mk450_init();
-
/* Start up terminal */
terminal();
}
}
+
+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);
+ }
+
+}
* | 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 |
* |----------------------------|
*
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;
#include <lib/regfunc.h>
#include <lib/tinyprintf.h>
-#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
//__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");
}
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 */
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();
-
}