rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 59737698a76411d4fd1d407846b70c03309d4125
parent f6681f83ad1eadc2f66a1ec907436afc33486fc9
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Tue, 12 Mar 2024 12:37:27 +0900

try to implement context switch.
find some weird error.

Diffstat:
Mex3/main.c | 50+++++++++++++++++++++++++++++++++++++++-----------
Mex3/memmap.ld | 3+++
Mex3/proc.s | 28++++++++++++++++++++++++++++
Mex3/start.s | 5+++++
4 files changed, 75 insertions(+), 11 deletions(-)

diff --git a/ex3/main.c b/ex3/main.c @@ -4,9 +4,13 @@ void printh(void *); void set_alarm(unsigned int); void proc0(void); void halt(void); +void *get_sp(void); +void wfi(void); extern void proc0_start, proc0_size; +extern void proc1_start, proc1_size; extern char msg0; +extern char msg1; // A proc represents a process in execution. typedef struct proc { @@ -14,14 +18,14 @@ typedef struct proc { unsigned int id; // R is the registers of the process with r[13] be sp, r[14] lr, r[15] pc. void *r[16]; + // Next is the next process to execute. + struct proc *next; } proc; // A proc_tab is the queue of waiting processes. typedef struct proc_tab { // Head is the head of the queue. proc *head; - // Next is the next process to execute. - proc *next; // Tail is the tail of the queue. proc *tail; } proc_tab; @@ -31,24 +35,48 @@ proc_tab *ptab; int main(void) { init(); - puts("reset"); - proc *p0 = (proc *) 0x20041000, *p1 = (proc *) 0x20041100; // sram5 + proc p0, p1; memcpy((void *)0x20000000, (void *)&proc0_start, (long) &proc0_size); - puts(&msg0); - p0->r[13] = (void *) 0x20000100; // sp - p0->r[14] = (void *) 0xdeadbeef; // lr - p0->r[15] = (void *) 0x20000000; // pc + memcpy((void *)0x20000100, (void *)&proc1_start, (long) &proc1_size); + + p0.r[13] = (void *) 0x20000100; // sp + p0.r[14] = (void *) 0xdeadbeef; // lr + p0.r[15] = (void *) 0x20000000; // pc - p1->r[13] = (void *) 0x20000200; // sp - p1->r[14] = (void *) 0xdeadbeef; // lr - p1->r[15] = (void *) 0x20000100; // pc + p1.r[13] = (void *) 0x20000200; // sp + p1.r[14] = (void *) 0xdeadbeef; // lr + p1.r[15] = (void *) 0x20000100; // pc + + for (;;) { + wfi(); + setreg(); + } return 0; } void +save_context(proc *p) +{} + +void +restore_context(proc *p) +{ + +} + +void scheduler(void) { + int *sp1, *sp0; + sp1 = (int *)get_sp(); + sp0 = sp1 + 16; + for (; sp1 <= sp0; sp1++) { + printh(sp1); + printh(*sp1); + puts(""); + } + puts(""); puts("scheduler called"); } diff --git a/ex3/memmap.ld b/ex3/memmap.ld @@ -34,4 +34,7 @@ SECTIONS .proc1 0x20000100 : { *(.proc1) } > SRAM AT > FLASH + proc1_start = LOADADDR(.proc1); + proc1_size = SIZEOF(.proc1); + } diff --git a/ex3/proc.s b/ex3/proc.s @@ -19,5 +19,33 @@ proc1: bl puts b proc1 .align 2 + .global msg1 msg1: .asciz "proc1" + + .align 1 + .section .text + // void *get_sp(void); + // Get_sp returns the current stack pointer. + .global get_sp +get_sp: + mov r0, sp + bx lr + + .align 1 + // Set_reg sets registers for debugging. + // Modified registers are: + // ReturnAddress(), LR, R12, R3, R2, R1 and R0. + .global setreg +setreg: + push {lr} + mov r0, #0x12 + mov r12, r0 + mov r0, #0x14 + mov lr, r0 + mov r0, #0 + mov r1, #1 + mov r2, #2 + mov r3, #3 + bl printh // BUG: some alignment fault? + pop {pc} diff --git a/ex3/start.s b/ex3/start.s @@ -284,6 +284,11 @@ halt: wfe b halt + .global wfi +wfi: + wfi + bx lr + // The following functions make no side effects and // can be used anywhare without pushing and popping // registers.