Browse Source

Merge pull request 'Add code comments' (#2) from feature/mutil_thread into master

Reviewed-on: #2
pull/3/head
xzb 4 months ago
parent
commit
c6781c55a1
  1. 4
      Core/Src/main.c
  2. 2
      thead/inc/thread.h
  3. 19
      thead/src/context_switch.s
  4. 30
      thead/src/thread.c

4
Core/Src/main.c

@ -58,7 +58,7 @@ void prosee1(void *data)
while(1) while(1)
{ {
__disable_irq(); __disable_irq();
printf("prosee_%d\r\n", self->task_id); printf("prosee_%d, stack_ptr:%#x\r\n", self->task_id, self->stack_ptr);
__enable_irq(); __enable_irq();
HAL_Delay(1000); HAL_Delay(1000);
} }
@ -70,7 +70,7 @@ void prosee2(void *data)
while(1) while(1)
{ {
__disable_irq(); __disable_irq();
printf("prosee_%d\r\n", self->task_id); printf("prosee_%d, stack_ptr:%#x\r\n", self->task_id, self->stack_ptr);
__enable_irq(); __enable_irq();
HAL_Delay(1000); HAL_Delay(1000);
} }

2
thead/inc/thread.h

@ -9,7 +9,7 @@ typedef struct tcb
{ {
uint32_t *stack_ptr; // 任务栈指针 uint32_t *stack_ptr; // 任务栈指针
uint32_t task_id; // 任务 ID uint32_t task_id; // 任务 ID
struct tcb * next; struct tcb * next; // 需要采用链表的方式记录任务栈
} tcb_t; } tcb_t;
void init_task(tcb_t *tcb, void (*task_entry)(void *), uint8_t *start_stack, void *arg); void init_task(tcb_t *tcb, void (*task_entry)(void *), uint8_t *start_stack, void *arg);

19
thead/src/context_switch.s

@ -1,10 +1,6 @@
; : context_switch.s
; : ARM Cortex-M3/M4 (STM32)
; : ARM Compiler 6 (Keil MDK/ARMCLANG)
; : PendSV RTOS
PRESERVE8 ; 8 (Cortex-M ) PRESERVE8 ; 8
THUMB ; 使 Thumb-2 THUMB ; 使 Thumb
AREA |.text|, CODE, READONLY ; AREA |.text|, CODE, READONLY ;
EXPORT PendSV_Handler ; PendSV_Handler EXPORT PendSV_Handler ; PendSV_Handler
@ -12,8 +8,9 @@
IMPORT next_task ; C next_task IMPORT next_task ; C next_task
IMPORT switch_to_next_task ; C switch_to_next_task IMPORT switch_to_next_task ; C switch_to_next_task
PendSV_Handler PROC PendSV_Handler PROC
;-------------------------------------------------- ;--------------------------------------------------
; 1. ; 1.
;-------------------------------------------------- ;--------------------------------------------------
CPSID I ; (PRIMASK=1) CPSID I ; (PRIMASK=1)
CPSID F ; (FAULTMASK=1) CPSID F ; (FAULTMASK=1)
@ -23,19 +20,21 @@ PendSV_Handler PROC
;-------------------------------------------------- ;--------------------------------------------------
LDR R1, = current_task ; current_task R1 LDR R1, = current_task ; current_task R1
LDR R1, [R1] ; current_task TCB地址 LDR R1, [R1] ; current_task TCB地址
CBZ R1, switch_nosave ; CBZ R1, switch_nosave ; SP为空就不需要保存switch_nosave函数
;-------------------------------------------------- ;--------------------------------------------------
; 3. R4-R11 ; 3. R4-R11
; : R0-R3, R12, LR, PC, PSR ( PSP) ; : R0-R3, R12, LR, PC, PSR ( PSP)
;-------------------------------------------------- ;--------------------------------------------------
MRS R0, PSP ; PSP MRS R0, PSP ; PSP
STMFD R0!, {R4-R11} ; R4-R11 STMFD R0!, {R4-R11} ; R4-R11
STR R0, [R1] STR R0, [R1] ; PSP保存进TCB的SP
switch_nosave switch_nosave
;-------------------------------------------------- ;--------------------------------------------------
; 4. C ; 4. C
;-------------------------------------------------- ;--------------------------------------------------
BL switch_to_next_task ; C current_task next_task BL switch_to_next_task ; C witch_to_next_task TCB
;-------------------------------------------------- ;--------------------------------------------------
; 5. ; 5.

30
thead/src/thread.c

@ -5,12 +5,15 @@
#include "thread.h" #include "thread.h"
/***
// 声明任务指针(需在汇编中导入) next_task为下一个执行目标
***/
tcb_t *current_task; tcb_t *current_task;
tcb_t *next_task; tcb_t *next_task;
// 切换任务的函数 /***
***/
void switch_to_next_task(void) void switch_to_next_task(void)
{ {
tcb_t *temp = current_task; tcb_t *temp = current_task;
@ -18,6 +21,9 @@ void switch_to_next_task(void)
next_task = temp; next_task = temp;
} }
/***
main函数
***/
void start_first_task(void) void start_first_task(void)
{ {
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
@ -25,9 +31,15 @@ void start_first_task(void)
__ISB(); __ISB();
} }
/***
,
1.
2.
3.
***/
tcb_t *task[2]; tcb_t *task[2];
uint8_t tcb_cunt = 0; uint8_t tcb_cunt = 0;
static uint8_t max_tcb = 0;
void tcb_scheduler(void) void tcb_scheduler(void)
{ {
if(tcb_cunt >= 1) if(tcb_cunt >= 1)
@ -41,7 +53,9 @@ void tcb_scheduler(void)
__ISB(); __ISB();
} }
/***
***/
void init_task(tcb_t *tcb, void (*task_entry)(void *), uint8_t *start_stack, void *arg) void init_task(tcb_t *tcb, void (*task_entry)(void *), uint8_t *start_stack, void *arg)
{ {
// 栈顶对齐到 8 字节(硬件要求) // 栈顶对齐到 8 字节(硬件要求)
@ -53,14 +67,14 @@ void init_task(tcb_t *tcb, void (*task_entry)(void *), uint8_t *start_stack, voi
uint32_t *stack_top = (uint32_t*)((uint8_t*)tcb->stack_ptr + STACK_SIZE); uint32_t *stack_top = (uint32_t*)((uint8_t*)tcb->stack_ptr + STACK_SIZE);
stack_top = (uint32_t*)((uint32_t)stack_top & ~0x07); stack_top = (uint32_t*)((uint32_t)stack_top & ~0x07);
*(--stack_top) = 0x01000000; // xPSR (Thumb 模式) *(--stack_top) = 0x01000000; // xPSR
*(--stack_top) = (uint32_t)task_entry; // PC *(--stack_top) = (uint32_t)task_entry; // PC
*(--stack_top) = 0xDEADBEEF; // LR *(--stack_top) = 0xDEADBEEF; // LR
*(--stack_top) = 0x0000000C; // R12 *(--stack_top) = 0x0000000C; // R12
*(--stack_top) = 0x00000003; // R3 *(--stack_top) = 0x00000003; // R3
*(--stack_top) = 0x00000002; // R2 *(--stack_top) = 0x00000002; // R2
*(--stack_top) = 0x00000000; // R1 (参数) *(--stack_top) = 0x00000000; // R1
*(--stack_top) = (uint32_t)arg; // R0 *(--stack_top) = (uint32_t)arg; // R0 (参数)
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {

Loading…
Cancel
Save