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 01/10] 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 From 9c5c6b32b189c8662030b2889b9c526842116f90 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 12 May 2023 15:39:33 +0800 Subject: [PATCH 02/10] add task module for XiZi_AIoT --- Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c | 0 .../XiZi_AIoT/softkernel/task/schedule.c | 0 Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 561 ++++++++++-------- Ubiquitous/XiZi_AIoT/softkernel/task/task.h | 244 ++------ 4 files changed, 361 insertions(+), 444 deletions(-) delete mode 100644 Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c delete mode 100644 Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c b/Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c b/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index a053a61d5..bd955c1af 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -5,306 +5,347 @@ #include #include -// 创建线程 -static pid_t next_pid = 0; +#define DEF_STACK_SIZE (128 * 1024) +// 定义全局的任务调度器 +scheduler_t *scheduler; /******************************************************************************* -* 函 数 名: start_thread -* 功能描述: 启动线程 -* 形 参: 无 -* 返 回 值: 栈指针 +* 函 数 名: scheduler_init +* 功能描述: 初始化任务调度器 +* 形 参: num_cpus:cpu个数,num_tasks_per_cpu:每个CPU的任务数量 +* 返 回 值: 任务调度器结构体指针 *******************************************************************************/ -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; +scheduler_t *scheduler_init(int num_cpus, int num_tasks_per_cpu) { + // 分配并初始化任务调度器 + scheduler = malloc(sizeof(scheduler_t)); + scheduler->num_cpus = num_cpus; + scheduler->num_tasks_per_cpu = num_tasks_per_cpu; + scheduler->ready_queue = malloc(sizeof(task_t*) * num_cpus * num_tasks_per_cpu); + scheduler->interrupt_stack_ptr = NULL; + for (int i = 0; i < num_cpus * num_tasks_per_cpu; i++) { + scheduler->ready_queue[i] = 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; + scheduler->current_task = NULL; + scheduler->current_cpu_id = 0; + return scheduler; } -int task_send_msg(tcb_t *tcb, void *msg, int len) { - int ret = 0; - msg_t *new_msg; +/******************************************************************************* +* 函 数 名: create_task +* 功能描述: 创建任务 +* 形 参: func:任务入口函数,arg:入口函数参数指针, + priority:任务优先级,stack_size:栈大小 +* 返 回 值: 任务的id +*******************************************************************************/ +int create_task(void (*func)(void *), void *arg, int priority, size_t stack_size) { + // 分配并初始化任务控制块 + tcb *task = malloc(sizeof(tcb)); + task->id = generate_task_id(); + task->priority = priority; + task->state = THREAD_READY; + task->stack_size = stack_size; + task->stack_bottom = malloc(stack_size); + task->stack_ptr = (uint32_t*)(task->stack_bottom + stack_size / sizeof(uint32_t)); + task->entry_point = func; + task->arg = arg; + task->cpu_id = get_current_cpu_id(); + // 初始化任务堆栈 + init_stack(task->stack_ptr, stack_size, func, arg,task); + // 添加任务到就绪队列 + add_task_to_ready_queue(task); + return task->id; +} - /* 如果目标任务的消息队列已满,则返回错误码 */ - if (is_msg_queue_full(tcb)) { + +/******************************************************************************* +* 函 数 名: destroy_task +* 功能描述: 销毁任务 +* 形 参: task_id:任务的id +* 返 回 值: 销毁成功返回0 +*******************************************************************************/ +int destroy_task(int task_id) { + // 获取要销毁的任务控制块 + tcb *task = get_task_by_id(task_id); + if (task == NULL) { return -1; } - - /* 分配新的消息结构体 */ - new_msg = alloc_msg(msg, len); - if (new_msg == NULL) { - return -1; + if (task->state == TASK_RUNNING) { + // 如果要销毁的任务正在运行,则直接切换到下一个任务 + switch_to_next_task(); } - - /* 将新的消息添加到目标任务的消息队列中 */ - add_msg_to_queue(tcb, new_msg); - - /* 如果目标任务正在等待消息,则唤醒该任务 */ - if (is_waiting_for_msg(tcb)) { - wake_up_task(tcb); - } - - return ret; + // 从就绪队列中移除任务 + remove_task_from_ready_queue(task); + // 释放任务堆栈 + free(task->stack_bottom); + // 释放任务控制块 + free(task); + return 0; } -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) { +/******************************************************************************* +* 函 数 名: suspend_task +* 功能描述: 挂起任务 +* 形 参: task_id:任务的id +* 返 回 值: 挂起成功返回0 +*******************************************************************************/ +int suspend_task(int task_id) { + // 获取要挂起的任务控制块 + tcb *task = get_task_by_id(task_id); + if (task == NULL) { return -1; } - - /* 如果消息的长度大于接收缓冲区的长度,则返回错误码 */ - if (recv_msg->len > len) { - ret = -1; - } else { - /* 复制消息的内容到接收缓冲区中 */ - memcpy(msg, recv_msg->data, recv_msg->len); + if (task->state == TASK_RUNNING) { + // 如果要挂起的任务正在运行,则切换到下一个任务 + switch_to_next_task(); } - - /* 释放消息结构体 */ - free_msg(recv_msg); - - return ret; + // 修改任务状态为阻塞状态 + task->state = TASK_BLOCKED; + return 0; } -tcb_t *task_get_current_tcb(void) { - tcb_t *tcb; - /* 获取当前任务的堆栈指针 */ - void *sp = get_current_sp(); +/******************************************************************************* +* 函 数 名: resume_task +* 功能描述: 恢复任务 +* 形 参: task_id:任务的id +* 返 回 值: 恢复成功返回0 +*******************************************************************************/ +int resume_task(int task_id) { + // 获取要恢复的任务控制块 + tcb *task = get_task_by_id(task_id); + if (task == NULL) { + return -1; + } + if (task->state != TASK_BLOCKED) { + // 如果要恢复的任务不是阻塞状态,则直接返回 + return -1; + } + // 修改任务状态为就绪状态 + task->state = task_READY; + // 添加任务到就绪队列 + add_task_to_ready_queue(task); + return 0; +} - /* 从任务列表中查找与当前堆栈指针对应的控制块 */ - for (int i = 0; i < NUM_TASKS; i++) { - tcb = &task_list[i]; - if (tcb->sp == sp) { - return tcb; + +/******************************************************************************* +* 函 数 名: set_task_priority +* 功能描述: 调整任务优先级 +* 形 参: task_id:任务的id,priority:要调整的优先级 +* 返 回 值: 销毁成功返回0 +*******************************************************************************/ +int set_task_priority(int task_id, int priority) { + // 获取要调整优先级的任务控制块 + tcb *task = get_task_by_id(task_id); + if (task == NULL) { + return -1; + } + // 修改任务优先级 + task->priority = priority; + return 0; +} + +/******************************************************************************* +* 函 数 名: get_current_task_id +* 功能描述: 获取当前任务的ID +* 形 参: 无 +* 返 回 值: 获取成功返回0 +*******************************************************************************/ +int get_current_task_id() { + if (scheduler->current_task == NULL) { + return -1; + } + return scheduler->current_task->id; +} + + +/******************************************************************************* +* 函 数 名: get_current_cpu_id +* 功能描述: 获取当前CPU的ID +* 形 参: 无 +* 返 回 值: 获取到的当前CPU的ID +* 说 名: 不同的处理器获取方式不同,这里以ARM-A9系列芯片为例 +*******************************************************************************/ +uint16_t get_current_cpu_id() { + uint32_t mpidr; + asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (mpidr)); + return mpidr & 0xff; +} + + +/******************************************************************************* +* 函 数 名: get_task_by_id +* 功能描述: 通过任务ID获取任务控制块 +* 形 参: task_id:任务的id +* 返 回 值: 获取到的任务控制块的指针 +*******************************************************************************/ +tcb *get_task_by_id(int task_id) { + // 遍历就绪队列和当前任务,寻找任务控制块 + for (int i = 0; i < scheduler->num_cpus * scheduler->num_tasks_per_cpu; i++) { + tcb *task = scheduler->ready_queue[i]; + if (task != NULL && task->id == task_id) { + return task; } } - - /* 如果没有找到对应的控制块,则返回空指针 */ + tcb *task = scheduler->current_task; + if (task != NULL && task->id == task_id) { + return task; + } return NULL; } -pid_t task_get_pid(tcb_t *tcb) { - return tcb->pid; + +/******************************************************************************* +* 函 数 名: generate_task_id +* 功能描述: 生成任务ID +* 形 参: 无 +* 返 回 值: 生成的任务ID +*******************************************************************************/ +int generate_task_id() { + static int next_task_id = 1; // 静态变量,记录下一个可用的任务ID + int task_id = next_task_id++; // 生成任务ID,并将next_task_id加1 + return task_id; } -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; +/******************************************************************************* +* 函 数 名: switch_to_next_task +* 功能描述: 切换到下一个任务 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void switch_to_next_task() { + // 保存当前任务的上下文 + // TODO: 保存当前任务的上下文 + // 从就绪队列中取出下一个任务 + task_t *next_task = NULL; + for (int i = scheduler->current_cpu_id * scheduler->num_tasks_per_cpu; i < (scheduler->current_cpu_id + 1) * scheduler->num_tasks_per_cpu; i++) { + task_t *task = scheduler->ready_queue[i]; + if (task != NULL && (next_task == NULL ||task->priority > next_task->priority)) { + next_task = task; + } } - - /* 设置任务的优先级 */ - 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; + if (next_task == NULL) { + // 如果就绪队列为空,则切换到空闲任务 + // TODO: 切换到空闲任务 + } else { + // 切换到下一个任务 + scheduler->current_task = next_task; + scheduler->current_task->state = TASK_RUNNING; + // TODO: 恢复下一个任务的上下文 } - - /* 设置任务的状态 */ - 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; +/******************************************************************************* +* 函 数 名: add_task_to_ready_queue +* 功能描述: 添加任务到就绪队列 +* 形 参: task:任务控制块的指针 +* 返 回 值: 无 +*******************************************************************************/ +void add_task_to_ready_queue(task_t *task) { + // 找到任务所在的CPU的就绪队列 + int cpu_id = task->cpu_id; + int start_index = cpu_id * scheduler->num_tasks_per_cpu; + int end_index = (cpu_id + 1) * scheduler->num_tasks_per_cpu; + // 找到一个空闲的位置插入任务 + for (int i = start_index; i < end_index; i++) { + if (scheduler->ready_queue[i] == NULL) { + scheduler->ready_queue[i] = task; + return; + } } - - /* 设置任务的时间片大小 */ - tcb->time_quantum = quantum; + // 如果没有空闲的位置,则替换掉优先级最低的任务 + task_t *lowest_priority_task = NULL; + int lowest_priority = 0; + for (int i = start_index; i < end_index; i++) { + task_t *t = scheduler->ready_queue[i]; + if (t != NULL && (lowest_priority_task == NULL || t->priority < lowest_priority)) { + lowest_priority_task = t; + lowest_priority = t->priority; + } + } + scheduler->ready_queue[lowest_priority_task - scheduler->ready_queue] = task; } -uint32_t task_get_stack_size(tcb_t *tcb) { - return tcb->stack_size; + +/******************************************************************************* +* 函 数 名: remove_task_from_ready_queue +* 功能描述: 从就绪队列中移除任务 +* 形 参: task:任务控制块的指针 +* 返 回 值: 无 +*******************************************************************************/ +void remove_task_from_ready_queue(task_t *task) { + // 找到任务所在的CPU的就绪队列 + int cpu_id = task->cpu_id; + int start_index = cpu_id * scheduler->num_tasks_per_cpu; + int end_index = (cpu_id + 1) * scheduler->num_tasks_per_cpu; + // 从就绪队列中移除任务 + for (int i = start_index; i < end_index; i++) { + if (scheduler->ready_queue[i] == task) { + scheduler->ready_queue[i] = NULL; + return; + } + } } -void *task_get_stack_top(tcb_t *tcb) { - return tcb->stack_top; + +/******************************************************************************* +* 函 数 名: init_stack +* 功能描述: 初始化任务堆栈 +* 形 参: stack_ptr:任务堆栈指针,stack_size:堆栈大小 + func:入口函数的指针,arg:入口函数的参数指针 + task:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void init_stack(uint32_t *stack_ptr, size_t stack_size, void (*func)(void *), void *arg,tcb* task) { + // 计算堆栈底部指针 + uint32_t *stack_bottom = stack_ptr - stack_size / sizeof(uint32_t); + // 将任务参数压入堆栈中 + *(--stack_ptr) = (uint32_t)arg; + // 将任务入口函数压入堆栈中 + *(--stack_ptr) = (uint32_t)func; + // 设置堆栈指针和堆栈底部指针 + task->stack_ptr = stack_ptr; + task->stack_bottom = stack_bottom; } -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; + +/******************************************************************************* +* 函 数 名: idle_task +* 功能描述: 空闲任务的入口函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void idle_task(void *arg) { + while (1) { + // 休眠等待,直到接收到调度器的唤醒信号 + asm volatile ("wfi"); + } } +/******************************************************************************* +* 函 数 名: init_idle_task +* 功能描述: 初始化空闲任务 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void init_idle_task() { + // 创建空闲任务的TCB + tcb *task = (tcb *)malloc(sizeof(tcb)); + memset(task, 0, sizeof(tcb)); + task->state = task_READY; + task->priority = 0; + task->cpu_id = get_current_cpu_id(); + task->task_id = generate_task_id(); + // 初始化空闲任务的堆栈 + uint32_t *stack_ptr = (uint32_t *)malloc(DEF_STACK_SIZE); + memset(stack_ptr, 0, DEF_STACK_SIZE); + init_stack(stack_ptr + DEF_STACK_SIZE / sizeof(uint32_t), DEF_STACK_SIZE, idle_task, NULL,task); + task->stack_ptr = stack_ptr + DEF_STACK_SIZE / sizeof(uint32_t) - 1; + task->stack_bottom = stack_ptr; + // 将空闲任务添加到就绪队列中 + add_tcbo_ready_queue(task); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h index 619061c78..064837652 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h @@ -6,210 +6,86 @@ #include #include -typedef uint16_t pid_t; -#define TASK_NAME_MAX_LENGTH 256 +#include +#include -#define MAX_PRIORITY 512 -#define MIN_PRIORITY 1 -#define MIN_TIME_QUANTUM 10 /* 最小时间片大小为10毫秒 */ -#define MAX_TIME_QUANTUM 100 /* 最大时间片大小为100毫秒 */ +// 定义线程状态 +typedef enum { + THREAD_READY, // 就绪状态 + THREAD_RUNNING, // 运行状态 + THREAD_BLOCKED, // 阻塞状态 + THREAD_TERMINATED // 终止状态 +} task_state_t; -// 线程状态 -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; - +// 定义线程控制块(TCB) 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; + int id; // 任务ID + int priority; // 任务优先级 + task_state_t state; // 任务状态 + uint32_t* stack_ptr; // 任务堆栈指针 + size_t stack_size; // 任务堆栈大小 + uint32_t *stack_bottom; // 任务堆栈底部 + void (*entry_point)(void); // 任务入口函数 + void *arg; // 任务参数 + uint16_t cpu_id; // 任务所在的CPU ID +} tcb; +// 定义任务调度器 typedef struct { - /* 消息类型 */ - uint8_t m_type; + int num_cpus; // CPU数量 + int num_tasks_per_cpu; // 每个CPU的任务数量 + tcb **ready_queue; // 就绪队列 + tcb *current_task; // 当前正在运行的任务 + uint16_t current_cpu_id; // 当前CPU的ID + uint32_t *interrupt_stack_ptr; // 中断堆栈指针 +} scheduler_t; - /* 发送者的PID */ - pid_t m_sender; +// 初始化任务调度器 +scheduler_t *scheduler_init(int num_cpus, int num_tasks_per_cpu); - /* 消息数据 */ - uint8_t m_data[512]; -} message_t; +// 创建任务 +int create_task(void (*func)(void *), void *arg, int priority, size_t stack_size); -typedef struct { - /* 消息队列长度 */ - uint16_t count; +// 销毁任务 +int destroy_task(int task_id); - /* 队列头指针 */ - void* front; +// 挂起任务 +int suspend_task(int task_id); - /* 队列尾指针 */ - void* rear; +// 恢复任务 +int resume_task(int task_id); - /* 消息队列缓冲区 */ - message_t *buffer; -}message_queue; +// 调整任务优先级 +int set_task_priority(int task_id, int priority); +// 获取当前任务的ID +int get_current_task_id(); -typedef struct { - /* 队列头指针 */ - tcb_t *head; +// 获取当前CPU的ID +uint16_t get_current_cpu_id; - /* 队列尾指针 */ - tcb_t *tail; -}task_list; +// 获取任务控制块 +tcb *get_task_by_id(int task_id); -typedef struct{ - /* 端点ID */ - uint16_t id; +// 生成任务ID +int generate_task_id(); - /* 端点状态 */ - uint32_t flags; +// 切换到下一个任务 +void switch_to_next_task(); - /* 发送队列 */ - message_queue send_queue; +// 添加任务到就绪队列 +void add_tcbo_ready_queue(tcb *task); - /* 接收队列 */ - message_queue recv_queue; +// 从就绪队列中移除任务 +void remove_task_from_ready_queue(tcb *task); - /* 端点等待队列 */ - task_list waiting; -}endpoint; +// 初始化任务堆栈 +void init_stack(uint32_t *stack_ptr, size_t stack_size, void (*func)(void *), void *arg,tcb* task); -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); +// 空闲任务的入口函数 +void idle_task(void *arg); +// 初始化空闲任务 +void init_idle_task(); #endif From 912f87ecc926d4109ed016f7a1d48341fe85cfb8 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 15 May 2023 10:25:32 +0800 Subject: [PATCH 03/10] support sabre-lite borad on xiuos appframework and Nuttx --- .../aiit_board/sabre-lite/include/board.h | 38 +++++++++---------- .../sabre-lite/include/board_memorymap.h | 38 +++++++++---------- .../aiit_board/sabre-lite/src/imx_appinit.c | 38 +++++++++---------- .../aiit_board/sabre-lite/src/imx_autoleds.c | 38 +++++++++---------- .../aiit_board/sabre-lite/src/imx_boardinit.c | 38 +++++++++---------- .../aiit_board/sabre-lite/src/imx_bringup.c | 38 +++++++++---------- .../aiit_board/sabre-lite/src/imx_userleds.c | 38 +++++++++---------- .../aiit_board/sabre-lite/src/sabre-lite.h | 38 +++++++++---------- 8 files changed, 152 insertions(+), 152 deletions(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h index 405566e68..3693cb79c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/include/board.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file board.h + * @brief sabre-lite board.h file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_H #define __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h index d49e77662..14fa834cf 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/include/board_memorymap.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file board_memorymap.h + * @brief sabre-lite board memorymap + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_MEMORYMAP_H #define __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_MEMORYMAP_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c index a90b2913a..26c471a34 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_appinit.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_appinit.c + * @brief sabre-lite imx_appinit.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c index ab081c440..cfd34ca69 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_autoleds.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_autoleds.c + * @brief sabre-lite imx_autoleds.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /* LEDs * diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c index df29c3b07..3f49cef5c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_boardinit.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_boardinit.c + * @brief sabre-lite imx_boardinit.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c index b26bf4582..71e55b8b2 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_bringup.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_bringup.c + * @brief sabre-lite imx_bringup.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c index f86268f1c..2261bf165 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_userleds.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_userleds.c + * @brief sabre-lite imx_userleds.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h index 76568b434..f4b310767 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/sabre-lite.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file sabre-lite.h + * @brief sabre-lite sabre-lite.h file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_SRC_SABRE_LITE_H #define __BOARDS_ARM_IMX6_SABRE_LITE_SRC_SABRE_LITE_H From 91ae4320fa1b60bc5934881757fb06c5bf97c92a Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 15 May 2023 11:01:46 +0800 Subject: [PATCH 04/10] change nuttx submodules --- .gitmodules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4db194dfe..37b0c26c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,10 +12,10 @@ url = https://gitlink.org.cn/xuos/lwext4_filesystem_support_XiUOS.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/nuttx"] path = Ubiquitous/Nuttx_Fusion_XiUOS/nuttx - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx.git + url = https://gitlink.org.cn/wgzAIIT/incubator-nuttx.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/apps"] path = Ubiquitous/Nuttx_Fusion_XiUOS/apps - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git + url = https://gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git [submodule "APP_Framework/Applications/webnet/WebNet_XiUOS"] path = APP_Framework/Applications/webnet/WebNet_XiUOS url = https://gitlink.org.cn/xuos/WebNet_XiUOS.git From 4e5e12379919dd135684dd62de798e010ac0abcf Mon Sep 17 00:00:00 2001 From: xxq250 Date: Sat, 20 May 2023 12:54:37 +0800 Subject: [PATCH 05/10] Update .gitmodules subdomain --- .gitmodules | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitmodules b/.gitmodules index 4db194dfe..5774c7030 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,27 +1,27 @@ [submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/rt-thread"] path = Ubiquitous/RT-Thread_Fusion_XiUOS/rt-thread - url = https://code.gitlink.org.cn/chunyexixiaoyu/rt-thread.git + url = https://www.gitlink.org.cn/chunyexixiaoyu/rt-thread.git [submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/kendryte-sdk/kendryte-sdk-source"] path = Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/kendryte-sdk/kendryte-sdk-source - url = https://code.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git + url = https://www.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git [submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-riscv64-board/kendryte-sdk/kendryte-sdk-source"] path = Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/aiit-riscv64-board/kendryte-sdk/kendryte-sdk-source - url = https://code.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git + url = https://www.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git [submodule "Ubiquitous/XiZi/fs/lwext4/lwext4_submodule"] path = Ubiquitous/XiZi/fs/lwext4/lwext4_submodule url = https://gitlink.org.cn/xuos/lwext4_filesystem_support_XiUOS.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/nuttx"] path = Ubiquitous/Nuttx_Fusion_XiUOS/nuttx - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx.git + url = https://www.gitlink.org.cn/wgzAIIT/incubator-nuttx.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/apps"] path = Ubiquitous/Nuttx_Fusion_XiUOS/apps - url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git + url = https://www.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git [submodule "APP_Framework/Applications/webnet/WebNet_XiUOS"] path = APP_Framework/Applications/webnet/WebNet_XiUOS url = https://gitlink.org.cn/xuos/WebNet_XiUOS.git [submodule "Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-riscv64/kendryte-sdk/kendryte-sdk-source"] path = Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/xidatong-riscv64/kendryte-sdk/kendryte-sdk-source - url = https://code.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git + url = https://www.gitlink.org.cn/chunyexixiaoyu/kendryte-sdk-source.git [submodule "APP_Framework/lib/lorawan/lora_radio_driver"] path = APP_Framework/lib/lorawan/lora_radio_driver url = https://gitlink.org.cn/IACU/lora_radio_driver.git From 7b427dd3c390ff97122a75c8d34b5caf3f2cf3cc Mon Sep 17 00:00:00 2001 From: "Wien.b" <18058767332@163.com> Date: Thu, 11 May 2023 19:55:48 -0700 Subject: [PATCH 06/10] modify edu-riscv64 compiler download link --- Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md index c65511c16..8d7ac8384 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md @@ -65,7 +65,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ From 0549dcd36393e01e600050d8e9f734351ea7b838 Mon Sep 17 00:00:00 2001 From: "Wien.b" <18058767332@163.com> Date: Sun, 14 May 2023 19:49:41 -0700 Subject: [PATCH 07/10] modify risc-v compiler download link --- Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/gapuino/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/hifive1-emulator/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/k210-emulator/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/README.md | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md index 8d7ac8384..f29654841 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md @@ -65,7 +65,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/gapuino/README.md b/Ubiquitous/XiZi_IIoT/board/gapuino/README.md index 9daf41671..b718d9e29 100755 --- a/Ubiquitous/XiZi_IIoT/board/gapuino/README.md +++ b/Ubiquitous/XiZi_IIoT/board/gapuino/README.md @@ -68,7 +68,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/README.md b/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/README.md index 4e8db0d1b..2ada64bee 100644 --- a/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/README.md +++ b/Ubiquitous/XiZi_IIoT/board/hifive1-emulator/README.md @@ -84,7 +84,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2),下载完成后,执行以下命令: +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS],下载完成后,执行以下命令: ```c sudo tar -xvjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md index 6a25be059..b4de073aa 100644 --- a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md +++ b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md @@ -19,7 +19,7 @@ $ sudo apt install build-essential pkg-config $ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev git ``` -**源码下载:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) +**源码下载:** XiUOS [下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] 新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下: diff --git a/Ubiquitous/XiZi_IIoT/board/k210-emulator/README.md b/Ubiquitous/XiZi_IIoT/board/k210-emulator/README.md index cbf4d7d49..52b314074 100644 --- a/Ubiquitous/XiZi_IIoT/board/k210-emulator/README.md +++ b/Ubiquitous/XiZi_IIoT/board/k210-emulator/README.md @@ -82,7 +82,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2),下载完成后,执行以下命令: +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS],下载完成后,执行以下命令: ```c sudo tar -xvjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md b/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md index 889b3ef43..04f1dd8c8 100755 --- a/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md +++ b/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md @@ -68,7 +68,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载并解压。[下载网址 https://open-isa.org/downloads/] +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS ![gnu](img/riscv_gnu.png) diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/README.md b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/README.md index ee278d46d..37316d895 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/README.md +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/README.md @@ -65,7 +65,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ From 8e5250f047c1d5400b9da1035bc34aa81179b973 Mon Sep 17 00:00:00 2001 From: "Wien.b" <18058767332@163.com> Date: Sun, 14 May 2023 20:07:15 -0700 Subject: [PATCH 08/10] modify risc-v compiler download link --- Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/kd233/README.md | 2 +- Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md index b4de073aa..eb5debdde 100644 --- a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md +++ b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md @@ -71,7 +71,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/kd233/README.md b/Ubiquitous/XiZi_IIoT/board/kd233/README.md index 4b86c7e56..cc6bfb67e 100644 --- a/Ubiquitous/XiZi_IIoT/board/kd233/README.md +++ b/Ubiquitous/XiZi_IIoT/board/kd233/README.md @@ -67,7 +67,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] ```shell $ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ diff --git a/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md b/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md index 04f1dd8c8..889b3ef43 100755 --- a/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md +++ b/Ubiquitous/XiZi_IIoT/board/rv32m1-vega/README.md @@ -68,7 +68,7 @@ cd kconfig-frontends ### 编译工具链: -RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载并解压。[下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载并解压。[下载网址 https://open-isa.org/downloads/] ![gnu](img/riscv_gnu.png) From d67d8e96f06ffbe01dd4fd3d00a4102b204ac8ee Mon Sep 17 00:00:00 2001 From: "Wien.b" <18058767332@163.com> Date: Sun, 14 May 2023 20:17:43 -0700 Subject: [PATCH 09/10] recover modify --- Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md index eb5debdde..7b8201710 100644 --- a/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md +++ b/Ubiquitous/XiZi_IIoT/board/hifive1-rev-B/README.md @@ -19,7 +19,7 @@ $ sudo apt install build-essential pkg-config $ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev git ``` -**源码下载:** XiUOS [下载链接:https://pan.baidu.com/s/1mWlR86FMc-xPQwDXJ_hiQg 提取码:XUOS] +**源码下载:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) 新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下: From 44810118afaa825ee297be4a4095132eb4abe06f Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 18 May 2023 17:49:04 +0800 Subject: [PATCH 10/10] change task module for XiZi_AIoT --- .gitmodules | 4 +- Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 770 ++++++++++++-------- Ubiquitous/XiZi_AIoT/softkernel/task/task.h | 198 +++-- 3 files changed, 601 insertions(+), 371 deletions(-) diff --git a/.gitmodules b/.gitmodules index 37b0c26c3..4db194dfe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,10 +12,10 @@ url = https://gitlink.org.cn/xuos/lwext4_filesystem_support_XiUOS.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/nuttx"] path = Ubiquitous/Nuttx_Fusion_XiUOS/nuttx - url = https://gitlink.org.cn/wgzAIIT/incubator-nuttx.git + url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx.git [submodule "Ubiquitous/Nuttx_Fusion_XiUOS/apps"] path = Ubiquitous/Nuttx_Fusion_XiUOS/apps - url = https://gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git + url = https://code.gitlink.org.cn/wgzAIIT/incubator-nuttx-apps.git [submodule "APP_Framework/Applications/webnet/WebNet_XiUOS"] path = APP_Framework/Applications/webnet/WebNet_XiUOS url = https://gitlink.org.cn/xuos/WebNet_XiUOS.git diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index bd955c1af..808804462 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -1,212 +1,190 @@ + +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: task.c +* @brief: file task.c +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/05/18 +* +*/ + #include -#include -#include -#include -#include -#include -#define DEF_STACK_SIZE (128 * 1024) -// 定义全局的任务调度器 -scheduler_t *scheduler; -/******************************************************************************* -* 函 数 名: scheduler_init -* 功能描述: 初始化任务调度器 -* 形 参: num_cpus:cpu个数,num_tasks_per_cpu:每个CPU的任务数量 -* 返 回 值: 任务调度器结构体指针 -*******************************************************************************/ -scheduler_t *scheduler_init(int num_cpus, int num_tasks_per_cpu) { - // 分配并初始化任务调度器 - scheduler = malloc(sizeof(scheduler_t)); - scheduler->num_cpus = num_cpus; - scheduler->num_tasks_per_cpu = num_tasks_per_cpu; - scheduler->ready_queue = malloc(sizeof(task_t*) * num_cpus * num_tasks_per_cpu); - scheduler->interrupt_stack_ptr = NULL; - for (int i = 0; i < num_cpus * num_tasks_per_cpu; i++) { - scheduler->ready_queue[i] = NULL; - } - scheduler->current_task = NULL; - scheduler->current_cpu_id = 0; - return scheduler; -} +// 全局运行队列和本地运行队列 +tcb_t *global_run_queue_head = NULL; +tcb_t *global_run_queue_tail = NULL; +tcb_t *local_run_queue_head[8] = {NULL}; +tcb_t *local_run_queue_tail[8] = {NULL}; + +// 当前任务的指针 +volatile tcb_t *current_task = NULL; /******************************************************************************* -* 函 数 名: create_task -* 功能描述: 创建任务 -* 形 参: func:任务入口函数,arg:入口函数参数指针, - priority:任务优先级,stack_size:栈大小 -* 返 回 值: 任务的id +* 函 数 名: tcb_init +* 功能描述: 初始化任务控制块 +* 形 参: tcb:任务控制块指针,priority:任务优先级,stack_size:栈大小 +* 返 回 值: 无 *******************************************************************************/ -int create_task(void (*func)(void *), void *arg, int priority, size_t stack_size) { - // 分配并初始化任务控制块 - tcb *task = malloc(sizeof(tcb)); - task->id = generate_task_id(); - task->priority = priority; - task->state = THREAD_READY; - task->stack_size = stack_size; - task->stack_bottom = malloc(stack_size); - task->stack_ptr = (uint32_t*)(task->stack_bottom + stack_size / sizeof(uint32_t)); - task->entry_point = func; - task->arg = arg; - task->cpu_id = get_current_cpu_id(); - // 初始化任务堆栈 - init_stack(task->stack_ptr, stack_size, func, arg,task); - // 添加任务到就绪队列 - add_task_to_ready_queue(task); - return task->id; -} - - -/******************************************************************************* -* 函 数 名: destroy_task -* 功能描述: 销毁任务 -* 形 参: task_id:任务的id -* 返 回 值: 销毁成功返回0 -*******************************************************************************/ -int destroy_task(int task_id) { - // 获取要销毁的任务控制块 - tcb *task = get_task_by_id(task_id); - if (task == NULL) { - return -1; - } - if (task->state == TASK_RUNNING) { - // 如果要销毁的任务正在运行,则直接切换到下一个任务 - switch_to_next_task(); - } - // 从就绪队列中移除任务 - remove_task_from_ready_queue(task); - // 释放任务堆栈 - free(task->stack_bottom); - // 释放任务控制块 - free(task); - return 0; -} - - -/******************************************************************************* -* 函 数 名: suspend_task -* 功能描述: 挂起任务 -* 形 参: task_id:任务的id -* 返 回 值: 挂起成功返回0 -*******************************************************************************/ -int suspend_task(int task_id) { - // 获取要挂起的任务控制块 - tcb *task = get_task_by_id(task_id); - if (task == NULL) { - return -1; - } - if (task->state == TASK_RUNNING) { - // 如果要挂起的任务正在运行,则切换到下一个任务 - switch_to_next_task(); - } - // 修改任务状态为阻塞状态 - task->state = TASK_BLOCKED; - return 0; -} - - -/******************************************************************************* -* 函 数 名: resume_task -* 功能描述: 恢复任务 -* 形 参: task_id:任务的id -* 返 回 值: 恢复成功返回0 -*******************************************************************************/ -int resume_task(int task_id) { - // 获取要恢复的任务控制块 - tcb *task = get_task_by_id(task_id); - if (task == NULL) { - return -1; - } - if (task->state != TASK_BLOCKED) { - // 如果要恢复的任务不是阻塞状态,则直接返回 - return -1; - } - // 修改任务状态为就绪状态 - task->state = task_READY; - // 添加任务到就绪队列 - add_task_to_ready_queue(task); - return 0; -} - - -/******************************************************************************* -* 函 数 名: set_task_priority -* 功能描述: 调整任务优先级 -* 形 参: task_id:任务的id,priority:要调整的优先级 -* 返 回 值: 销毁成功返回0 -*******************************************************************************/ -int set_task_priority(int task_id, int priority) { - // 获取要调整优先级的任务控制块 - tcb *task = get_task_by_id(task_id); - if (task == NULL) { - return -1; - } - // 修改任务优先级 - task->priority = priority; - return 0; +void tcb_init(tcb_t *tcb, int priority, int stack_size) { + tcb->priority = priority; + tcb->state = TASK_CREATED; + tcb->message_queue = NULL; + tcb->stack = (uint8_t*)malloc(stack_size); + tcb->stack_size = stack_size; + tcb->stack_ptr = tcb->stack + stack_size - sizeof(context_t); + // 将任务的上下文保存在栈中 + context_t *context = (context_t*)tcb->stack_ptr; + context_init(context, (void*)task_entry, tcb->stack_ptr); } /******************************************************************************* -* 函 数 名: get_current_task_id -* 功能描述: 获取当前任务的ID +* 函 数 名: tcb_destroy +* 功能描述: 销毁任务控制块 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void tcb_destroy(tcb_t *tcb) { + free(tcb->stack_bottom); + tcb->stack_ptr = NULL; + tcb->stack_bottom = NULL; + tcb->stack_size = 0; + tcb->state = TASK_BLOCKED; + tcb->priority = 0; + tcb->next = NULL; + if (tcb->message_queue != NULL) { + message_queue_destroy(tcb->message_queue); + tcb->message_queue = NULL; + } +} + +/******************************************************************************* +* 函 数 名: get_current_task +* 功能描述: 获取当前任务的指针 * 形 参: 无 -* 返 回 值: 获取成功返回0 +* 返 回 值: 任务控制块指针 *******************************************************************************/ -int get_current_task_id() { - if (scheduler->current_task == NULL) { - return -1; +tcb_t *get_current_task() { + return (tcb_t*)current_task; +} + + +/******************************************************************************* +* 函 数 名: get_local_run_queue_head +* 功能描述: 获取本地运行队列的头指针 +* 形 参: cpu_id:当前cpu的id +* 返 回 值: 任务控制块指针 +*******************************************************************************/ +tcb_t *get_local_run_queue_head(int cpu_id) { + return local_run_queue_head[cpu_id]; +} + + +/******************************************************************************* +* 函 数 名: add_to_global_run_queue +* 功能描述: 将任务添加到全局运行队列中 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void add_to_global_run_queue(tcb_t *tcb) { + // 将任务添加到全局运行队列的尾部 + if (global_run_queue_head == NULL) { + global_run_queue_head = tcb; + global_run_queue_tail = tcb; + } else { + global_run_queue_tail->next = tcb; + global_run_queue_tail = tcb; } - return scheduler->current_task->id; } /******************************************************************************* -* 函 数 名: get_current_cpu_id -* 功能描述: 获取当前CPU的ID +* 函 数 名: take_from_global_run_queue +* 功能描述: 从全局运行队列中取出一个任务 * 形 参: 无 -* 返 回 值: 获取到的当前CPU的ID -* 说 名: 不同的处理器获取方式不同,这里以ARM-A9系列芯片为例 +* 返 回 值: tcb:任务控制块指针 *******************************************************************************/ -uint16_t get_current_cpu_id() { - uint32_t mpidr; - asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (mpidr)); - return mpidr & 0xff; -} - - -/******************************************************************************* -* 函 数 名: get_task_by_id -* 功能描述: 通过任务ID获取任务控制块 -* 形 参: task_id:任务的id -* 返 回 值: 获取到的任务控制块的指针 -*******************************************************************************/ -tcb *get_task_by_id(int task_id) { - // 遍历就绪队列和当前任务,寻找任务控制块 - for (int i = 0; i < scheduler->num_cpus * scheduler->num_tasks_per_cpu; i++) { - tcb *task = scheduler->ready_queue[i]; - if (task != NULL && task->id == task_id) { - return task; +tcb_t *take_from_global_run_queue() { + // 从全局运行队列的头部取出一个任务 + if (global_run_queue_head == NULL) { + return NULL; + } else { + tcb_t *tcb = global_run_queue_head; + global_run_queue_head = tcb->next; + if (global_run_queue_head == NULL) { + global_run_queue_tail = NULL; } + return tcb; } - tcb *task = scheduler->current_task; - if (task != NULL && task->id == task_id) { - return task; - } - return NULL; } /******************************************************************************* -* 函 数 名: generate_task_id -* 功能描述: 生成任务ID -* 形 参: 无 -* 返 回 值: 生成的任务ID +* 函 数 名: add_to_local_run_queue +* 功能描述: 将任务添加到本地运行队列中 +* 形 参: tcb:任务控制块指针,cpu_id:任务绑定的CPU id +* 返 回 值: 无 *******************************************************************************/ -int generate_task_id() { - static int next_task_id = 1; // 静态变量,记录下一个可用的任务ID - int task_id = next_task_id++; // 生成任务ID,并将next_task_id加1 - return task_id; +void add_to_local_run_queue(tcb_t *tcb, int cpu_id) { + // 将任务添加到本地运行队列的尾部 + if (local_run_queue_head[cpu_id] == NULL) { + local_run_queue_head[cpu_id] = tcb; + local_run_queue_tail[cpu_id] = tcb; + } else { + local_run_queue_tail[cpu_id]->next = tcb; + local_run_queue_tail[cpu_id] = tcb; + } +} + + +/******************************************************************************* +* 函 数 名: take_from_local_run_queue +* 功能描述: 从本地运行队列中取出一个任务 +* 形 参: cpu_id:CPU id +* 返 回 值: 无 +*******************************************************************************/ +tcb_t *take_from_local_run_queue(int cpu_id) { + // 从本地运行队列的头部取出一个任务 + if (local_run_queue_head[cpu_id] == NULL) { + return NULL; + } else { + tcb_t *tcb = local_run_queue_head[cpu_id]; + local_run_queue_head[cpu_id] = tcb->next; + if (local_run_queue_head[cpu_id] == NULL) { + local_run_queue_tail[cpu_id] = NULL; + } + return tcb; + } +} + + +/******************************************************************************* +* 函 数 名: move_current_task_to_global_run_queue +* 功能描述: 将当前任务从本地运行队列中取出,并添加到全局运行队列中 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void move_current_task_to_global_run_queue() { + int cpu_id = get_cpu_id(); + tcb_t *tcb = (tcb_t*)current_task; + tcb->state = TASK_READY; + add_to_global_run_queue(tcb); + local_run_queue_head[cpu_id] = NULL; + local_run_queue_tail[cpu_id] = NULL; + current_task = NULL; } @@ -217,135 +195,343 @@ int generate_task_id() { * 返 回 值: 无 *******************************************************************************/ void switch_to_next_task() { + int cpu_id = get_cpu_id(); + tcb_t *current_tcb = (tcb_t*)current_task; + tcb_t *next_tcb = take_from_local_run_queue(cpu_id); + if (next_tcb == NULL) { + next_tcb = take_from_global_run_queue(); + } + if (next_tcb == NULL) { + // 如果没有可运行的任务,则将当前任务继续运行 + return; + } // 保存当前任务的上下文 - // TODO: 保存当前任务的上下文 - // 从就绪队列中取出下一个任务 - task_t *next_task = NULL; - for (int i = scheduler->current_cpu_id * scheduler->num_tasks_per_cpu; i < (scheduler->current_cpu_id + 1) * scheduler->num_tasks_per_cpu; i++) { - task_t *task = scheduler->ready_queue[i]; - if (task != NULL && (next_task == NULL ||task->priority > next_task->priority)) { - next_task = task; - } + if (current_tcb != NULL) { + current_tcb->stack_ptr = get_stack_pointer(); } - if (next_task == NULL) { - // 如果就绪队列为空,则切换到空闲任务 - // TODO: 切换到空闲任务 - } else { - // 切换到下一个任务 - scheduler->current_task = next_task; - scheduler->current_task->state = TASK_RUNNING; - // TODO: 恢复下一个任务的上下文 + // 切换到下一个任务的上下文 + current_task = next_tcb; + set_stack_pointer(next_tcb->stack_ptr); + // 如果切换到的任务是新的任务,需要执行任务初始化函数 + if (current_tcb != next_tcb) { + next_tcb->state = TASK_RUNNING; + task_init(next_tcb); } } /******************************************************************************* -* 函 数 名: add_task_to_ready_queue -* 功能描述: 添加任务到就绪队列 -* 形 参: task:任务控制块的指针 +* 函 数 名: task_init +* 功能描述: 任务初始化函数 +* 形 参: tcb:任务控制块指针 * 返 回 值: 无 *******************************************************************************/ -void add_task_to_ready_queue(task_t *task) { - // 找到任务所在的CPU的就绪队列 - int cpu_id = task->cpu_id; - int start_index = cpu_id * scheduler->num_tasks_per_cpu; - int end_index = (cpu_id + 1) * scheduler->num_tasks_per_cpu; - // 找到一个空闲的位置插入任务 - for (int i = start_index; i < end_index; i++) { - if (scheduler->ready_queue[i] == NULL) { - scheduler->ready_queue[i] = task; +void task_init(tcb_t *tcb) { + // 创建消息队列 + message_queue_t mq = (message_queue_t)malloc(sizeof(message_queue_t)); + mq->buffer = (message_t)malloc(sizeof(message_t) * 16); + mq->capacity = 16; + mq->head = 0; + mq->tail = 0; + mq->count = 0; + tcb->message_queue = mq; +} + + +/******************************************************************************* +* 函 数 名: create_task +* 功能描述: 创建任务 +* 形 参: priority:任务优先级,stack_size:栈大小 +* 返 回 值: 无 +*******************************************************************************/ +tcb_t *create_task(int priority, int stack_size) { + tcb_t *tcb = (tcb_t*)malloc(sizeof(tcb_t)); + tcb_init(tcb, priority, stack_size); + add_to_global_run_queue(tcb); + return tcb; +} + + +/******************************************************************************* +* 函 数 名: destroy_task +* 功能描述: 销毁任务 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void destroy_task(tcb_t *tcb) { + tcb_destroy(tcb); + free(tcb); +} + + +/******************************************************************************* +* 函 数 名: send_message +* 功能描述: 发送消息 +* 形 参: dest_tcb:目标任务的控制块指针,type:消息类型,data:消息的具体内容 +* 返 回 值: 无 +*******************************************************************************/ +void send_message(tcb_t *dest_tcb, int type, void *data) { + message_t message; + message.type = type; + message.data = data; + if (dest_tcb->message_queue == NULL) { + // 如果目标任务没有消息队列,则创建一个消息队列 + dest_tcb->message_queue = message_queue_create(16); + } + // 将消息添加到目标任务的消息队列中 + message_queue_push(dest_tcb->message_queue, &message); +} + + +/******************************************************************************* +* 函 数 名: receive_message +* 功能描述: 接收消息 +* 形 参: type:接收的消息类型,data:存储接收到的消息 +* 返 回 值: 无 +*******************************************************************************/ +void receive_message(int type, void *data) { + tcb_t *current_tcb = (tcb_t*)current_task; + message_t message; + // 从当前任务的消息队列中取出消息 + while (message_queue_pop(current_tcb->message_queue, &message) != 0) { + if (message.type == type) { + // 如果消息的类型匹配,则返回消息数据 + memcpy(data, message.data, sizeof(void*)); return; } } - // 如果没有空闲的位置,则替换掉优先级最低的任务 - task_t *lowest_priority_task = NULL; - int lowest_priority = 0; - for (int i = start_index; i < end_index; i++) { - task_t *t = scheduler->ready_queue[i]; - if (t != NULL && (lowest_priority_task == NULL || t->priority < lowest_priority)) { - lowest_priority_task = t; - lowest_priority = t->priority; - } - } - scheduler->ready_queue[lowest_priority_task - scheduler->ready_queue] = task; -} - - -/******************************************************************************* -* 函 数 名: remove_task_from_ready_queue -* 功能描述: 从就绪队列中移除任务 -* 形 参: task:任务控制块的指针 -* 返 回 值: 无 -*******************************************************************************/ -void remove_task_from_ready_queue(task_t *task) { - // 找到任务所在的CPU的就绪队列 - int cpu_id = task->cpu_id; - int start_index = cpu_id * scheduler->num_tasks_per_cpu; - int end_index = (cpu_id + 1) * scheduler->num_tasks_per_cpu; - // 从就绪队列中移除任务 - for (int i = start_index; i < end_index; i++) { - if (scheduler->ready_queue[i] == task) { - scheduler->ready_queue[i] = NULL; + // 如果没有匹配的消息,则当前任务被阻塞,直到有匹配的消息为止 + current_tcb->state = TASK_BLOCKED; + while (message_queue_pop(current_tcb->message_queue, &message) != 0) { + if (message.type == type) { + // 如果有匹配的消息,则返回消息数据,并将当前任务状态设置为就绪 + memcpy(data, message.data, sizeof(void*)); + current_tcb->state = TASK_READY; return; } } -} - - -/******************************************************************************* -* 函 数 名: init_stack -* 功能描述: 初始化任务堆栈 -* 形 参: stack_ptr:任务堆栈指针,stack_size:堆栈大小 - func:入口函数的指针,arg:入口函数的参数指针 - task:任务控制块指针 -* 返 回 值: 无 -*******************************************************************************/ -void init_stack(uint32_t *stack_ptr, size_t stack_size, void (*func)(void *), void *arg,tcb* task) { - // 计算堆栈底部指针 - uint32_t *stack_bottom = stack_ptr - stack_size / sizeof(uint32_t); - // 将任务参数压入堆栈中 - *(--stack_ptr) = (uint32_t)arg; - // 将任务入口函数压入堆栈中 - *(--stack_ptr) = (uint32_t)func; - // 设置堆栈指针和堆栈底部指针 - task->stack_ptr = stack_ptr; - task->stack_bottom = stack_bottom; -} - - -/******************************************************************************* -* 函 数 名: idle_task -* 功能描述: 空闲任务的入口函数 -* 形 参: 无 -* 返 回 值: 无 -*******************************************************************************/ -void idle_task(void *arg) { + // 如果还是没有匹配的消息,则当前任务一直被阻塞 while (1) { - // 休眠等待,直到接收到调度器的唤醒信号 - asm volatile ("wfi"); + wait_for_interrupt(); } } + /******************************************************************************* -* 函 数 名: init_idle_task -* 功能描述: 初始化空闲任务 +* 函 数 名: message_queue_create +* 功能描述: 创建消息队列 +* 形 参: capacity:消息队列的容量 +* 返 回 值: 生成的消息队列的指针 +*******************************************************************************/ +message_queue_t *message_queue_create(int capacity) { + message_queue_t *mq = (message_queue_t*)malloc(sizeof(message_queue_t)); + mq->buffer = (message_t*)malloc(sizeof(message_t) * capacity); + mq->capacity = capacity; + mq->head = 0; + mq->tail = 0; + mq->count = 0; + return mq; +} + + +/******************************************************************************* +* 函 数 名: message_queue_destroy +* 功能描述: 销毁消息队列 +* 形 参: mq:消息队列的指针 +* 返 回 值: 无 +*******************************************************************************/ +void message_queue_destroy(message_queue_t *mq) { + free(mq->buffer); + free(mq); +} + + +/******************************************************************************* +* 函 数 名: message_queue_push +* 功能描述: 将消息添加到消息队列中 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +int message_queue_push(message_queue_t *mq, message_t *message) { + if (mq->count >= mq->capacity) { + return -1; // 队列已满 + } + mq->buffer[mq->tail] = *message; + mq->tail = (mq->tail + 1) % mq->capacity; + mq->count++; + return 0; +} + + +/******************************************************************************* +* 函 数 名: message_queue_pop +* 功能描述: 从消息队列中取出消息 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +int message_queue_pop(message_queue_t *mq, message_t *message) { + if (mq->count <= 0) { + return -1; // 队列已空 + } + *message = mq->buffer[mq->head]; + mq->head = (mq->head + 1) % mq->capacity; + mq->count--; + return 0; +} + + +/******************************************************************************* +* 函 数 名: context_init +* 功能描述: 初始化上下文 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +void context_init(context_t *context, void (*entry)(void), void *stack_ptr) { + context->cpsr = 0x10; // 设置 CPSR 的初始值 + context->pc = (uint32_t)entry; // 设置 PC 的初始值为任务入口地址 + context->r0 = (uint32_t)stack_ptr; // 设置 R0 的初始值为栈指针 + context->r1 = 0; // 设置 R1 的初始值为 0 + context->r2 = 0; // 设置 R2 的初始值为 0 + context->r3 = 0; // 设置 R3 的初始值为 0 + context->r4 = 0; // 设置 R4 的初始值为 0 + context->r5 = 0; // 设置 R5 的初始值为 0 + context->r6 = 0; // 设置 R6 的初始值为 0 + context->r7 = 0; // 设置 R7 的初始值为 0 + context->r8 = 0; // 设置 R8 的初始值为 0 + context->r9 = 0; // 设置 R9 的初始值为 0 + context->r10 = 0; // 设置 R10 的初始值为 0 + context->r11 = 0; // 设置 R11 的初始值为 0 + context->r12 = 0; // 设置 R12 的初始值为 0 + context->sp = (uint32_t)stack_ptr; // 设置 SP 的初始值为栈指针 + context->lr = (uint32_t)task_exit; // 设置 LR 的初始值为线程退出函数的地址 +} + +/******************************************************************************* +* 函 数 名: wait_for_interrupt +* 功能描述: 等待中断 * 形 参: 无 * 返 回 值: 无 *******************************************************************************/ -void init_idle_task() { - // 创建空闲任务的TCB - tcb *task = (tcb *)malloc(sizeof(tcb)); - memset(task, 0, sizeof(tcb)); - task->state = task_READY; - task->priority = 0; - task->cpu_id = get_current_cpu_id(); - task->task_id = generate_task_id(); - // 初始化空闲任务的堆栈 - uint32_t *stack_ptr = (uint32_t *)malloc(DEF_STACK_SIZE); - memset(stack_ptr, 0, DEF_STACK_SIZE); - init_stack(stack_ptr + DEF_STACK_SIZE / sizeof(uint32_t), DEF_STACK_SIZE, idle_task, NULL,task); - task->stack_ptr = stack_ptr + DEF_STACK_SIZE / sizeof(uint32_t) - 1; - task->stack_bottom = stack_ptr; - // 将空闲任务添加到就绪队列中 - add_tcbo_ready_queue(task); -} \ No newline at end of file +void wait_for_interrupt() { + // 在实现中,可以使用 WFI 指令等待中断 + __asm__ volatile("wfi"); +} + +/******************************************************************************* +* 函 数 名: get_cpu_id +* 功能描述: 获取CPU id +* 形 参: 无 +* 返 回 值: 获取的cpu id +*******************************************************************************/ +int get_cpu_id() { + uint32_t mpidr; + __asm__ volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(mpidr)); + return mpidr & 0xff; +} + + +/******************************************************************************* +* 函 数 名: get_stack_pointer +* 功能描述: 获取栈指针 +* 形 参: 无 +* 返 回 值: 获取到的栈指针 +*******************************************************************************/ +void *get_stack_pointer() { + // 在实现中,可以使用 ARM 的 SP 寄存器获取栈指针 + void *sp; + __asm__ volatile("mov %0, sp" : "=r"(sp)); + return sp; +} + + +/******************************************************************************* +* 函 数 名: set_stack_pointer +* 功能描述: 设置栈指针 +* 形 参: 设置的栈指针 +* 返 回 值: 无 +*******************************************************************************/ +void set_stack_pointer(void *sp) { + // 在实现中,可以使用 ARM 的 SP 寄存器设置栈指针 + __asm__ volatile("mov sp, %0" : : "r"(sp)); +} + +/******************************************************************************* +* 函 数 名: add_interrupt_handler +* 功能描述: 添加中断处理函数 +* 形 参: irq:中断号,handler:中断句柄,priority:中断优先级 +* 返 回 值: 无 +*******************************************************************************/ +void add_interrupt_handler(int irq, void (*handler)(void), int priority) { + uint32_t *vector_table = (uint32_t*)0x0; + + // 将中断处理函数写入中断向量表中 + vector_table[irq + 16] = (uint32_t)handler; + + // 设置中断优先级 + uint8_t priority_shift = 8 - __NVIC_PRIO_BITS; + uint32_t priority_mask = 0xff << priority_shift; + uint32_t priority_value = (priority << priority_shift) & priority_mask; + uint32_t *priority_reg = (uint32_t*)0xE000E400; + int index = irq / 4; + int offset = irq % 4; + priority_reg[index] &= ~(0xff << (offset * 8)); + priority_reg[index] |= (priority_value << (offset * 8)); + + // 使能中断 + uint32_t *enable_reg = (uint32_t*)0xE000E100; + enable_reg[irq / 32] |= 1 << (irq % 32); +} + + +/******************************************************************************* +* 函 数 名: enter_critical +* 功能描述: 进入临界区 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void enter_critical() { + // 在实现中,可以使用 ARM 的 CPSR 寄存器进入临界区 + __asm__ volatile("cpsid i"); +} + +/******************************************************************************* +* 函 数 名: leave_critical +* 功能描述: 离开临界区 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void leave_critical() { + // 在实现中,可以使用 ARM 的 CPSR 寄存器离开临界区 + __asm__ volatile("cpsie i"); +} + + + +/******************************************************************************* +* 函 数 名: task_exit +* 功能描述: 任务退出函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void task_exit() { + // 切换到下一个任务 + switch_to_next_task(); + // 在实现中,可以使用 ARM 的 WFE 指令等待下一个中断 + __asm__ volatile("wfe"); +} + + +/******************************************************************************* +* 函 数 名: task_entry +* 功能描述: 任务入口函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void task_entry() { + tcb_t *current_tcb = (tcb_t*)current_task; + current_tcb->state = TASK_RUNNING; + task_init(current_tcb); + while (1) { + switch_to_next_task(); + } +} diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h index 064837652..fdcc38fa0 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h @@ -1,91 +1,135 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: task.h +* @brief: file task.h +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/05/18 +* +*/ #ifndef __TASK_H__ #define __TASK_H__ #include -#include #include - #include -#include +#include +#include -// 定义线程状态 +// 任务状态枚举类型 typedef enum { - THREAD_READY, // 就绪状态 - THREAD_RUNNING, // 运行状态 - THREAD_BLOCKED, // 阻塞状态 - THREAD_TERMINATED // 终止状态 -} task_state_t; + TASK_CREATED, // 初始状态 + TASK_READY, // 就绪状态 + TASK_RUNNING, // 运行状态 + TASK_BLOCKED, // 阻塞状态 +} task_state_t; -// 定义线程控制块(TCB) +// 任务控制块结构体 +typedef struct tcb { + uint32_t *stack_ptr; // 任务堆栈指针 + uint32_t *stack_bottom; // 任务堆栈底部指针 + uint32_t stack_size; // 任务堆栈大小 + task_state_t state; // 任务状态 + int priority; // 任务优先级 + struct tcb *next; // 指向下一个任务控制块的指针 + struct message_queue *message_queue; // 消息队列 +} tcb_t; + + +// 消息结构体 +typedef struct message { + int type; // 消息类型 + void *data; // 消息数据指针 +} message_t; + + +// 消息队列结构体 +typedef struct message_queue { + message_t *buffer; // 消息缓冲区 + int capacity; // 缓冲区容量 + int count; // 当前缓冲区中的消息数量 + int head; // 队头指针 + int tail; // 队尾指针 + semaphore_t *semaphore; // 信号量,用于实现消息队列的同步机制 +} message_queue_t; + + +// 信号量结构体 +typedef struct semaphore { + int count; // 计数器 + tcb_t *wait_list_head; // 指向等待信号量的任务控制块的指针 + mutex_t mutex; // 互斥锁,用于保护信号量和等待队列的访问 +} semaphore_t; + + +// 互斥锁结构体 +typedef struct mutex { + int lock; // 锁标志 +} mutex_t; + + +// 上下文结构体 typedef struct { - int id; // 任务ID - int priority; // 任务优先级 - task_state_t state; // 任务状态 - uint32_t* stack_ptr; // 任务堆栈指针 - size_t stack_size; // 任务堆栈大小 - uint32_t *stack_bottom; // 任务堆栈底部 - void (*entry_point)(void); // 任务入口函数 - void *arg; // 任务参数 - uint16_t cpu_id; // 任务所在的CPU ID -} tcb; + uint32_t cpsr; // 控制寄存器 + uint32_t pc; // 程序计数器 + uint32_t r0; // 寄存器 R0 + uint32_t r1; // 寄存器 R1 + uint32_t r2; // 寄存器 R2 + uint32_t r3; // 寄存器 R3 + uint32_t r4; // 寄存器 R4 + uint32_t r5; // 寄存器 R5 + uint32_t r6; // 寄存器 R6 + uint32_t r7; // 寄存器 R7 + uint32_t r8; // 寄存器 R8 + uint32_t r9; // 寄存器 R9 + uint32_t r10; // 寄存器 R10 + uint32_t r11; // 寄存器 R11 + uint32_t r12; // 寄存器 R12 + uint32_t sp; // 栈指针 + uint32_t lr; // 链接寄存器 +} context_t; -// 定义任务调度器 -typedef struct { - int num_cpus; // CPU数量 - int num_tasks_per_cpu; // 每个CPU的任务数量 - tcb **ready_queue; // 就绪队列 - tcb *current_task; // 当前正在运行的任务 - uint16_t current_cpu_id; // 当前CPU的ID - uint32_t *interrupt_stack_ptr; // 中断堆栈指针 -} scheduler_t; - -// 初始化任务调度器 -scheduler_t *scheduler_init(int num_cpus, int num_tasks_per_cpu); - -// 创建任务 -int create_task(void (*func)(void *), void *arg, int priority, size_t stack_size); - -// 销毁任务 -int destroy_task(int task_id); - -// 挂起任务 -int suspend_task(int task_id); - -// 恢复任务 -int resume_task(int task_id); - -// 调整任务优先级 -int set_task_priority(int task_id, int priority); - -// 获取当前任务的ID -int get_current_task_id(); - -// 获取当前CPU的ID -uint16_t get_current_cpu_id; - -// 获取任务控制块 -tcb *get_task_by_id(int task_id); - -// 生成任务ID -int generate_task_id(); - -// 切换到下一个任务 -void switch_to_next_task(); - -// 添加任务到就绪队列 -void add_tcbo_ready_queue(tcb *task); - -// 从就绪队列中移除任务 -void remove_task_from_ready_queue(tcb *task); - -// 初始化任务堆栈 -void init_stack(uint32_t *stack_ptr, size_t stack_size, void (*func)(void *), void *arg,tcb* task); - -// 空闲任务的入口函数 -void idle_task(void *arg); - -// 初始化空闲任务 -void init_idle_task(); +void tcb_init(tcb_t *tcb, int priority, int stack_size); +void tcb_destroy(tcb_t *tcb); +tcb_t *get_current_task(void); +tcb_t *get_local_run_queue_head(int cpu_id); +void add_to_global_run_queue(tcb_t *tcb); +tcb_t *take_from_global_run_queue(void); +void add_to_local_run_queue(tcb_t *tcb, int cpu_id); +tcb_t *take_from_local_run_queue(int cpu_id); +void move_current_task_to_global_run_queue(void); +void switch_to_next_task(void); +void task_init(tcb_t *tcb); +tcb_t *create_task(int priority, int stack_size); +void destroy_task(tcb_t *tcb); +void send_message(tcb_t *dest_tcb, int type, void *data); +void receive_message(int type, void *data); +message_queue_t *message_queue_create(int capacity); +void message_queue_destroy(message_queue_t *mq); +int message_queue_push(message_queue_t *mq, message_t *message); +int message_queue_pop(message_queue_t *mq, message_t *message); +int message_queue_push(message_queue_t *mq, message_t *message); +void context_init(context_t *context, void (*entry)(void), void *stack_ptr); +void wait_for_interrupt(void); +int get_cpu_id(void); +void *get_stack_pointer(void); +void set_stack_pointer(void *sp); +void add_interrupt_handler(int irq, void (*handler)(void), int priority); +void enter_critical(void); +void leave_critical(void); +void task_exit(void); +void task_entry(void); #endif