Skip to content

Commit 08cb308

Browse files
committed
04-Multitasking: Fix processor mode in first activate
As mention in issue #27, `task_init()` is added before task created. This is reference to 06-Preemptive, and also, it's not the time yet to disclose the systick interrupt so use `svc` to switch to handler mode after reset. In previous way, we call the `activate` in both thread and handler mode, and use `if(first)` to distinguish them. This always bother the newbie to mini-arm-os to figure out what `activate` is going on. This commit makes `activate` only effect in handler mode as I use `task_init()` to ""init"" reset mode from thread mode to handler mode.
1 parent 3ea03f5 commit 08cb308

File tree

3 files changed

+29
-3
lines changed

3 files changed

+29
-3
lines changed

04-Multitasking/asm.h

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define __ASM_H_
33

44
unsigned int *activate(unsigned int *stack);
5+
void task_init_env(unsigned int *stack);
56
void syscall(void);
67

78
#endif

04-Multitasking/context_switch.S

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
.syntax unified
22

3+
.macro save_kernel_state
4+
mrs ip, psr
5+
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
6+
.endm
7+
38
.type svc_handler, %function
49
.global svc_handler
510
svc_handler:
@@ -15,13 +20,23 @@ svc_handler:
1520

1621
.global activate
1722
activate:
18-
/* save kernel state */
19-
mrs ip, psr
20-
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
23+
save_kernel_state
2124

2225
/* load user state */
2326
ldmia r0!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}
2427
msr psp, r0
2528

2629
/* jump to user task */
2730
bx lr
31+
32+
.global task_init_env
33+
task_init_env:
34+
save_kernel_state
35+
36+
/* switch to process stack */
37+
msr psp, r0
38+
mov r0, #3
39+
msr control, r0
40+
isb
41+
bl syscall
42+
bx lr

04-Multitasking/os.c

+10
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ unsigned int *create_task(unsigned int *stack, void (*start)(void))
6363
return stack;
6464
}
6565

66+
/* After reset, processor is at thread and privileged mode.
67+
* Switch to handler mode to ensure an appropriate exception return.
68+
*/
69+
void task_init(void)
70+
{
71+
unsigned int empty[32];
72+
task_init_env(empty + 32);
73+
}
74+
6675
void task1_func(void)
6776
{
6877
print_str("task1: Created!\n");
@@ -95,6 +104,7 @@ int main(void)
95104
size_t current_task;
96105

97106
usart_init();
107+
task_init();
98108

99109
print_str("OS: Starting...\n");
100110
print_str("OS: First create task 1\n");

0 commit comments

Comments
 (0)