main.c (2432B)
1 #define NULL 0L // TODO: Should fail when dereferenced. 2 3 void init(void); 4 int puts(char *); 5 void printh(unsigned int); 6 void set_alarm(unsigned int); 7 void halt(void); 8 void wfi(void); 9 void print_sp(void); 10 void *memcpy(void *s1, void *s2, long n); 11 void restore_context(unsigned int [17]); 12 void set_psp(void); 13 14 // A proc represents a process in execution. 15 typedef struct proc { 16 // Id is the unique identifier of the process. 17 unsigned int id; 18 // R is the registers of the process with 19 // r[13] be sp, r[14] lr, r[15] pc, r16 xspr. 20 unsigned int r[17]; 21 // Next is the next process to execute. 22 struct proc *next; 23 } proc; 24 25 void save_context(unsigned int r[17]); 26 27 extern char proc0_start, proc0_size; 28 extern char proc1_start, proc1_size; 29 extern void proc0(void), proc1(void); 30 extern char msg0, msg1; 31 32 33 // A proc_tab is the queue of waiting processes. 34 typedef struct proc_tab { 35 // Head is the head of the queue. 36 proc *head; 37 // Tail is the tail of the queue. 38 proc *tail; 39 } proc_tab; 40 41 proc_tab ptab; 42 proc p0, p1; 43 44 int 45 main(void) { 46 init(); 47 48 memcpy((void *)0x20000000, &proc0_start, (long) &proc0_size); 49 memcpy((void *)0x20000100, &proc1_start, (long) &proc1_size); 50 51 ptab.head = &p0; 52 ptab.tail = &p1; 53 54 p0.id = 0; 55 p0.r[13] = 0x20000100; // sp 56 p0.r[14] = (unsigned int) halt; // lr 57 p0.r[15] = (unsigned int) proc0; // pc 58 p0.r[16] = 0x01000000; // EPSR's thumb bit 59 p0.next = &p1; 60 61 p1.id = 1; 62 p1.r[13] = 0x20000200; // sp 63 p1.r[14] = (unsigned int) halt; // lr 64 p1.r[15] = (unsigned int) proc1; // pc 65 p1.r[16] = 0x01000000; // EPSR's thumb bit 66 p1.next = NULL; 67 68 set_psp(); 69 70 proc0(); 71 72 return 0; 73 } 74 75 void 76 scheduler(void) { 77 puts("scheduler called"); 78 } 79 80 // Switch_context saves registers r to the currently executing proc struct 81 // and then move it to the tail of task queue. 82 // It returns the next PC of the next task in the queue 83 unsigned int * 84 switch_context(unsigned int r[17]) { 85 proc *p; 86 87 puts("switch_context:"); 88 for (int i = 0; i < 17; i++) { 89 printh(r[i]); 90 puts(""); 91 } 92 93 // save context 94 int i; 95 for (i = 0; i < 17; i++) { 96 ptab.head->r[i] = r[i]; 97 } 98 // update task queue 99 p = ptab.head; 100 ptab.head = ptab.head->next; 101 ptab.tail->next = p; 102 ptab.tail = p; 103 ptab.tail->next = NULL; 104 105 puts("next context:"); 106 for (int i = 0; i < 17; i++) { 107 printh(ptab.head->r[i]); 108 puts(""); 109 } 110 111 return ptab.head->r; 112 } 113 114 void 115 isr_hard_fault(void) { 116 puts("hard fault"); 117 halt(); 118 } 119 120 void 121 isr_svcall(void) { 122 puts("svcall"); 123 }