rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 5ca7441102daf5ab906359f8f45e3d74979b470a
parent 7e304f12d94a6d4ea5cc5518f2e093508cb746f4
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Sat, 16 Mar 2024 09:39:54 +0900

implement save_context

Diffstat:
Mex3/main.c | 74+++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mex3/proc.s | 18+-----------------
2 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/ex3/main.c b/ex3/main.c @@ -1,3 +1,5 @@ +#define NULL 0L // TODO: Should fail when dereferenced. + void init(void); int puts(char *); void printh(void *); @@ -9,11 +11,6 @@ void wfi(void); void *memcpy(void *s1, void *s2, long n); void setreg(void); -extern char proc0_start, proc0_size; -extern char proc1_start, proc1_size; -extern char msg0; -extern char msg1; - // A proc represents a process in execution. typedef struct proc { // Id is the unique identifier of the process. @@ -24,6 +21,14 @@ typedef struct proc { struct proc *next; } proc; +proc *save_context(unsigned int pid, void *r[16]); + +extern char proc0_start, proc0_size; +extern char proc1_start, proc1_size; +extern char msg0; +extern char msg1; + + // A proc_tab is the queue of waiting processes. typedef struct proc_tab { // Head is the head of the queue. @@ -32,7 +37,7 @@ typedef struct proc_tab { proc *tail; } proc_tab; -proc_tab *ptab; +proc_tab ptab; int main(void) { @@ -42,24 +47,61 @@ main(void) { memcpy((void *)0x20000000, &proc0_start, (long) &proc0_size); memcpy((void *)0x20000100, &proc1_start, (long) &proc1_size); + ptab.head = &p0; + ptab.tail = &p1; + + p0.id = 0; p0.r[13] = (void *) 0x20000100; // sp p0.r[14] = (void *) main; // lr p0.r[15] = (void *) 0x20000000; // pc + p0.next = &p1; + p1.id = 1; p1.r[13] = (void *) 0x20000200; // sp p1.r[14] = (void *) main; // lr p1.r[15] = (void *) 0x20000100; // pc + p1.next = NULL; for (;;) { setreg(); wfi(); + void *r[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; + proc *p = save_context(0, r); + if (p == NULL) { + puts("process 0 not found"); + continue; + } + for (int i = 0; i < 16; i++) { + printh(p0.r[i]); + puts(""); + } + puts(""); } return 0; } -void -save_context(proc *p) -{} +// Save_context saves registers r to the proc struct specified by pid. +// It returns the address of matching process, or NULL if no such process is found. +proc * +save_context(unsigned int pid, void *r[16]) +{ + proc *p; + int i; + + for (p = ptab.head; p; p = p->next) { + if (p->id == pid) { + break; + } + } + if (!p) { + return NULL; + } + + for (i = 0; i < 16; i++) { + p->r[i] = r[i]; + } + return p; +} void restore_context(proc *p) @@ -80,16 +122,3 @@ void isr_svcall(void) { puts("svcall"); } -/* -void -isr_alarm(void) { - int *sp = get_sp(); - for (int i = 0; i < 12; i += 1) { - printh(sp+i); - printh((void *)*(sp+i)); - puts(""); - } - scheduler(); - set_alarm(1000 * 1000); -} -*/ -\ No newline at end of file diff --git a/ex3/proc.s b/ex3/proc.s @@ -55,21 +55,6 @@ print_sr: .global isr_alarm isr_alarm: push {r4, r5, r6, lr} - bl get_sp - mov r4, r0 - mov r5, sp - add r5, #16 - mov r6, r5 - add r6, #32 // 8 words -isr_alarm_loop: - ldr r0, [r5, #0] - bl printh - mov r0, #'\n' - bl putbyte - add r5, r5, #4 - cmp r5, r6 - blt isr_alarm_loop - bl scheduler ldr r0, =(1000 * 1000) bl set_alarm - pop {r4, r5, r6, pc} -\ No newline at end of file + pop {r4, r5, r6, pc}