From 1161db389d09c3c633cc62a136e4326aab961fee Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 4 May 2023 17:45:13 +0800 Subject: [PATCH] add task module for XiZi_AIoT --- Ubiquitous/XiZi_AIoT/softkernel/task/Makefile | 2 +- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 310 ++++++++++++++++++ Ubiquitous/XiZi_AIoT/softkernel/task/task.h | 215 ++++++++++++ 3 files changed, 526 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/task/task.h diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile index 4ca20e597..93ec6f896 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := task.c schedule.c ipc.c +SRC_FILES := schedule.c ipc.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index e69de29bb..a053a61d5 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include +#include + +// 创建线程 +static pid_t next_pid = 0; + +/******************************************************************************* +* 函 数 名: start_thread +* 功能描述: 启动线程 +* 形 参: 无 +* 返 回 值: 栈指针 +*******************************************************************************/ +tcb_t *task_create(char *name, int pri, uint32_t stack_size, void (*entry)(void *arg), void *arg) { + tcb_t *tcb; + uint32_t stack_top; + uint32_t kstack_top; + int r; + + /* 分配任务控制块 */ + tcb = (tcb_t *)malloc(sizeof(tcb_t)); + if (tcb == NULL) { + return NULL; + } + + /* 分配任务栈 */ + tcb->stack_size = stack_size; + tcb->stack_top = (uint32_t)malloc(stack_size); + if (tcb->stack_top == 0) { + free(tcb); + return NULL; + } + + /* 分配内核栈 */ + tcb->kstack_size = K_STACK_SIZE; + tcb->kstack_top = (uint32_t)malloc(tcb->kstack_size); + if (tcb->kstack_top == 0) { + free((void *)tcb->stack_top); + free(tcb); + return NULL; + } + + /* 初始化任务控制块 */ + tcb->state.flags = 0; + tcb->state.exit_code = 0; + tcb->state.trap_type = 0; + tcb->priority = pri; + tcb->flags = 0; + tcb->message_queue.head = NULL; + tcb->message_queue.tail = NULL; + tcb->async_flags = 0; + tcb->cpu_affinity = 0; + tcb->private = NULL; + + /* 初始化任务上下文 */ + r = setup_context(&tcb->context, (void *)entry, arg, (void *)tcb->stack_top + tcb->stack_size, tcb->kstack_top + tcb->kstack_size); + if (r != 0) { + free((void *)tcb->kstack_top); + free((void *)tcb->stack_top); + free(tcb); + return NULL; + } + + /* 设置任务ID */ + tcb->pid = next_pid++; + + /* 向任务列表中添加任务 */ + r = add_task(tcb); + if (r != 0) { + free((void *)tcb->kstack_top); + free((void *)tcb->stack_top); + free(tcb); + return NULL; + } + + /* 设置任务名称 */ + strncpy(tcb->name, name, TASK_NAME_MAX_LENGTH); + + /* 返回任务控制块 */ + return tcb; +} + +void task_destroy(tcb_t *tcb) { + /* 从任务列表中移除任务 */ + remove_task(tcb); + + /* 释放任务栈和内核栈 */ + free((void *)tcb->stack_top); + free((void *)tcb->kstack_top); + + /* 释放任务控制块 */ + free(tcb); +} + +void task_suspend(tcb_t *tcb) { + /* 设置任务状态为挂起 */ + task_set_state(tcb, TASK_STATE_SUSPENDED); + + /* 将任务从调度队列中移除 */ + remove_from_schedule_queue(tcb); +} + +void task_resume(tcb_t *tcb) { + /* 设置任务状态为就绪 */ + task_set_state(tcb, TASK_STATE_READY); + + /* 将任务添加到调度队列中 */ + add_to_schedule_queue(tcb); +} + +void task_delay(uint32_t ticks) { + tcb_t *tcb; + + /* 获取当前任务的控制块 */ + tcb = get_current_task(); + + /* 设置任务的延迟计数器 */ + tcb->delay_ticks = ticks; + + /* 将任务从调度队列中移除 */ + remove_from_schedule_queue(tcb); + + /* 将任务添加到延迟队列中 */ + add_to_delay_queue(tcb); +} + +void task_notify_async(tcb_t *tcb, int flags) { + /* 设置任务的异步通知标志 */ + tcb->async_flags |= flags; + + /* 将该任务添加到等待列表中 */ + add_to_wait_queue(tcb, flags); +} + +int task_wait_async(int flags) { + tcb_t *tcb; + + /* 获取当前任务的控制块 */ + tcb = get_current_task(); + + /* 设置任务的等待标志 */ + tcb->wait_flags = flags; + + /* 将当前任务从调度队列中移除 */ + remove_from_schedule_queue(tcb); + + /* 将当前任务添加到等待列表中 */ + add_to_wait_queue(tcb, flags); + + /* 切换到下一个任务 */ + switch_to_next_task(); + + /* 被唤醒后,返回当前任务的异步通知标志 */ + return tcb->async_flags; +} + + +int task_send_msg(tcb_t *tcb, void *msg, int len) { + int ret = 0; + msg_t *new_msg; + + /* 如果目标任务的消息队列已满,则返回错误码 */ + if (is_msg_queue_full(tcb)) { + return -1; + } + + /* 分配新的消息结构体 */ + new_msg = alloc_msg(msg, len); + if (new_msg == NULL) { + return -1; + } + + /* 将新的消息添加到目标任务的消息队列中 */ + add_msg_to_queue(tcb, new_msg); + + /* 如果目标任务正在等待消息,则唤醒该任务 */ + if (is_waiting_for_msg(tcb)) { + wake_up_task(tcb); + } + + return ret; +} + + +int task_recv_msg(void *msg, int len) { + int ret = 0; + msg_t *recv_msg; + + /* 如果当前任务的消息队列为空,则挂起当前任务 */ + if (is_msg_queue_empty()) { + wait_for_msg(); + } + + /* 从消息队列中取出一条消息 */ + recv_msg = get_msg_from_queue(); + if (recv_msg == NULL) { + return -1; + } + + /* 如果消息的长度大于接收缓冲区的长度,则返回错误码 */ + if (recv_msg->len > len) { + ret = -1; + } else { + /* 复制消息的内容到接收缓冲区中 */ + memcpy(msg, recv_msg->data, recv_msg->len); + } + + /* 释放消息结构体 */ + free_msg(recv_msg); + + return ret; +} + +tcb_t *task_get_current_tcb(void) { + tcb_t *tcb; + + /* 获取当前任务的堆栈指针 */ + void *sp = get_current_sp(); + + /* 从任务列表中查找与当前堆栈指针对应的控制块 */ + for (int i = 0; i < NUM_TASKS; i++) { + tcb = &task_list[i]; + if (tcb->sp == sp) { + return tcb; + } + } + + /* 如果没有找到对应的控制块,则返回空指针 */ + return NULL; +} + +pid_t task_get_pid(tcb_t *tcb) { + return tcb->pid; +} + +int task_get_priority(tcb_t *tcb) { + return tcb->priority; +} + +void task_set_priority(tcb_t *tcb, int pri) { + /* 确保优先级的值在合法范围内 */ + if (pri < MIN_PRIORITY) { + pri = MIN_PRIORITY; + } else if (pri > MAX_PRIORITY) { + pri = MAX_PRIORITY; + } + + /* 设置任务的优先级 */ + tcb->priority = pri; +} + +int task_get_state(tcb_t *tcb) { + return tcb->state; +} + +void task_set_state(tcb_t *tcb, int state) { + /* 确保状态的值在合法范围内 */ + if (state < TASK_STATE_CREATED || state > TASK_STATE_TERMINATED) { + return; + } + + /* 设置任务的状态 */ + tcb->state = state; +} + +int task_get_async_flags(tcb_t *tcb) { + return tcb->async_flags; +} + +void task_set_async_flags(tcb_t *tcb, int flags) { + /* 设置任务的异步事件标志 */ + tcb->async_flags = flags; +} + +uint32_t task_get_time_quantum(tcb_t *tcb) { + return tcb->time_quantum; +} + +void task_set_time_quantum(tcb_t *tcb, uint32_t quantum) { + /* 确保时间片大小的值在合法范围内 */ + if (quantum < MIN_TIME_QUANTUM) { + quantum = MIN_TIME_QUANTUM; + } else if (quantum > MAX_TIME_QUANTUM) { + quantum = MAX_TIME_QUANTUM; + } + + /* 设置任务的时间片大小 */ + tcb->time_quantum = quantum; +} + +uint32_t task_get_stack_size(tcb_t *tcb) { + return tcb->stack_size; +} + +void *task_get_stack_top(tcb_t *tcb) { + return tcb->stack_top; +} + +uint32_t task_get_cpu_affinity(tcb_t *tcb) { + return tcb->cpu_affinity; +} + +void task_set_cpu_affinity(tcb_t *tcb, uint32_t affinity) { + /* 设置任务的CPU亲和性 */ + tcb->cpu_affinity = affinity; +} + diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h new file mode 100644 index 000000000..619061c78 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h @@ -0,0 +1,215 @@ + +#ifndef __TASK_H__ +#define __TASK_H__ + +#include +#include +#include + +typedef uint16_t pid_t; +#define TASK_NAME_MAX_LENGTH 256 + +#define MAX_PRIORITY 512 +#define MIN_PRIORITY 1 +#define MIN_TIME_QUANTUM 10 /* 最小时间片大小为10毫秒 */ +#define MAX_TIME_QUANTUM 100 /* 最大时间片大小为100毫秒 */ + + +// 线程状态 +typedef enum thread_state { + TASK_STATE_CREATED, // 线程已创建,但未启动 + TASK_STATE_READY, // 线程就绪 + TASK_STATE_RUNNING, // 线程正在运行 + TASK_STATE_BLOCKED, // 线程被阻塞(等待某些事件的发生) + TASK_STATE_WAITING, // 线程正在休眠(等待一段时间后被唤醒) + TASK_STATE_SUSPENDED, // 线程被挂起(暂停执行) + TASK_STATE_TERMINATED // 线程已终止 +} task_state; + +typedef struct { + /* 通用寄存器 */ + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + + /* 返回地址 */ + uint32_t eip; + + /* 特权级 */ + uint32_t cs; + uint32_t eflags; +}context; + +typedef struct { + /* 消息类型 */ + uint8_t m_type; + + /* 发送者的PID */ + pid_t m_sender; + + /* 消息数据 */ + uint8_t m_data[512]; +} message_t; + +typedef struct { + /* 消息队列长度 */ + uint16_t count; + + /* 队列头指针 */ + void* front; + + /* 队列尾指针 */ + void* rear; + + /* 消息队列缓冲区 */ + message_t *buffer; +}message_queue; + + +typedef struct { + /* 队列头指针 */ + tcb_t *head; + + /* 队列尾指针 */ + tcb_t *tail; +}task_list; + +typedef struct{ + /* 端点ID */ + uint16_t id; + + /* 端点状态 */ + uint32_t flags; + + /* 发送队列 */ + message_queue send_queue; + + /* 接收队列 */ + message_queue recv_queue; + + /* 端点等待队列 */ + task_list waiting; +}endpoint; + +typedef struct tcb { + /* 任务ID */ + pid_t pid; + + /* 任务状态 */ + task_state state; + + /* 任务优先级 */ + uint16_t priority; + + /* 任务类型 */ + uint16_t flags; + + /* 任务的延迟计数器 */ + uint16_t delay_ticks; + + /* 任务栈顶指针 */ + uint32_t stack_top; + + /* 任务栈大小 */ + uint16_t stack_size; + + /* 内核栈顶指针 */ + uint32_t kstack_top; + + /* 内核栈大小 */ + uint16_t kstack_size; + + /* 任务上下文 */ + context context; + + /* 消息队列 */ + message_queue message_queue; + + /* 关联的端点 */ + endpoint *endpoint; + + /* 异步通知标志 */ + unsigned int async_flags; + + /* 任务的CPU亲和力 */ + unsigned int cpu_affinity; + + /* 任务的私有数据 */ + void* private; +} tcb_t; + + + +/* 创建任务 */ +tcb_t *task_create(char *name, int pri, uint32_t stack_size, void (*entry)(void *arg), void *arg); + +/* 销毁任务 */ +void task_destroy(tcb_t *tcb); + +/* 暂停任务 */ +void task_suspend(tcb_t *tcb); + +/* 恢复任务 */ +void task_resume(tcb_t *tcb); + +/* 延时 */ +void task_delay(uint32_t ticks); + +/* 异步通知 */ +void task_notify_async(tcb_t *tcb, int flags); + +/* 等待异步通知 */ +int task_wait_async(int flags); + +/* 发送消息 */ +int task_send_msg(tcb_t *tcb, void *msg, int len); + +/* 接收消息 */ +int task_recv_msg(void *msg, int len); + +/* 获取当前任务的TCB */ +tcb_t *task_get_current_tcb(void); + +/* 获取任务ID */ +pid_t task_get_pid(tcb_t *tcb); + +/* 获取任务优先级 */ +int task_get_priority(tcb_t *tcb); + +/* 设置任务优先级 */ +void task_set_priority(tcb_t *tcb, int pri); + +/* 获取任务状态 */ +int task_get_state(tcb_t *tcb); + +/* 设置任务状态 */ +void task_set_state(tcb_t *tcb, int state); + +/* 获取任务的异步通知标志 */ +int task_get_async_flags(tcb_t *tcb); + +/* 设置任务的异步通知标志 */ +void task_set_async_flags(tcb_t *tcb, int flags); + +/* 获取任务的时间片大小 */ +uint32_t task_get_time_quantum(tcb_t *tcb); + +/* 设置任务的时间片大小 */ +void task_set_time_quantum(tcb_t *tcb, uint32_t quantum); + +/* 获取任务的栈大小 */ +uint32_t task_get_stack_size(tcb_t *tcb); + +/* 获取任务的栈顶指针 */ +void *task_get_stack_top(tcb_t *tcb); + +/* 获取任务的CPU亲和力 */ +uint32_t task_get_cpu_affinity(tcb_t *tcb); + +/* 设置任务的CPU亲和力 */ +void task_set_cpu_affinity(tcb_t *tcb, uint32_t affinity); + +#endif