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. 21
      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)
{
__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();
HAL_Delay(1000);
}
@ -70,7 +70,7 @@ void prosee2(void *data)
while(1)
{
__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();
HAL_Delay(1000);
}

2
thead/inc/thread.h

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

21
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 )
THUMB ; 使 Thumb-2
PRESERVE8 ; 8
THUMB ; 使 Thumb
AREA |.text|, CODE, READONLY ;
EXPORT PendSV_Handler ; PendSV_Handler
@ -12,8 +8,9 @@
IMPORT next_task ; C next_task
IMPORT switch_to_next_task ; C switch_to_next_task
PendSV_Handler PROC
;--------------------------------------------------
; 1.
; 1.
;--------------------------------------------------
CPSID I ; (PRIMASK=1)
CPSID F ; (FAULTMASK=1)
@ -23,19 +20,21 @@ PendSV_Handler PROC
;--------------------------------------------------
LDR R1, = current_task ; current_task R1
LDR R1, [R1] ; current_task TCB地址
CBZ R1, switch_nosave ;
CBZ R1, switch_nosave ; SP为空就不需要保存switch_nosave函数
;--------------------------------------------------
; 3. R4-R11
; : R0-R3, R12, LR, PC, PSR ( PSP)
;--------------------------------------------------
MRS R0, PSP ; PSP
MRS R0, PSP ; PSP
STMFD R0!, {R4-R11} ; R4-R11
STR R0, [R1]
STR R0, [R1] ; PSP保存进TCB的SP
switch_nosave
;--------------------------------------------------
; 4. C
;--------------------------------------------------
BL switch_to_next_task ; C current_task next_task
BL switch_to_next_task ; C witch_to_next_task TCB
;--------------------------------------------------
; 5.

30
thead/src/thread.c

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

Loading…
Cancel
Save