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/20] 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/20] 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/20] 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 12c24ddc73492c045f1761d62acf8fa60ad52a1b Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 15 May 2023 10:58:47 +0800 Subject: [PATCH 04/20] fix complie bug for hc32f4a0 --- Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk index c52aca76a..ef43289d2 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk @@ -1,11 +1,11 @@ export CROSS_COMPILE ?=/usr/bin/arm-none-eabi- -export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror -export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2 -export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_hc32f4a0.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds -export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror +export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror +export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2 +export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_hc32f4a0.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds +export CXXFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -Werror -export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds +export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds export DEFINES := -DHAVE_CCONFIG_H -DHC32F4A0 -DUSE_DDL_DRIVER -DHAVE_SIGINFO 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 05/20] 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 7aac1926f3286fdbba23379b4544e3a438b9382b Mon Sep 17 00:00:00 2001 From: Jeremy Date: Mon, 15 May 2023 11:02:00 +0800 Subject: [PATCH 06/20] add iperf for w5500 --- .../third_party_driver/ethernet/wiz_iperf.c | 465 ++++++++++++++++++ 1 file changed, 465 insertions(+) create mode 100644 Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c new file mode 100644 index 000000000..3c4daa75f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c @@ -0,0 +1,465 @@ +#include "socket.h" +#include "w5500.h" +#include "connect_w5500.h" + +#ifdef BSP_WIZ_USE_IPERF + +#define IPERF_PORT 5001 +#define IPERF_BUFSZ (4 * 1024) + +#define IPERF_MODE_STOP 0 +#define IPERF_MODE_SERVER 1 +#define IPERF_MODE_CLIENT 2 + +typedef struct{ + int mode; + uint8 host[4]; + uint16 port; +} IPERF_PARAM; +static IPERF_PARAM param = {IPERF_MODE_STOP, {0, 0, 0, 0}, IPERF_PORT}; + +static void iperf_udp_client(void *thread_param) +{ + int sock; + uint8 *buffer; + uint16 local_port = 4840; + uint32 packet_count = 0; + uint32 tick; + int send_size; + + send_size = IPERF_BUFSZ > 1470 ? 1470 : IPERF_BUFSZ; + + sock = 0; // w5500支持8个socket独立工作,todo socket端口管理 + // setSn_TXBUF_SIZE(sock, 16); + // setSn_RXBUF_SIZE(sock, 16); + + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + printf("[%s:%d] malloc failed\n", __FILE__, __LINE__); + return; + } + for(int i = 0; i < IPERF_BUFSZ; i++) + buffer[i] = i % 10; + + KPrintf("iperf udp mode run...\n"); + while (param.mode != IPERF_MODE_STOP){ + switch(getSn_SR(sock)){ + case SOCK_CLOSED: + wiz_socket(sock, Sn_MR_UDP, local_port, 0x00); + break; + case SOCK_UDP: + packet_count++; + tick = CurrentTicksGain(); + buffer[0] = (uint8)(packet_count >> 24); + buffer[1] = (uint8)(packet_count >> 16); + buffer[2] = (uint8)(packet_count >> 8); + buffer[3] = (uint8)(packet_count); + + buffer[4] = (uint8)((tick / TICK_PER_SECOND) >> 24); + buffer[5] = (uint8)((tick / TICK_PER_SECOND) >> 16); + buffer[6] = (uint8)((tick / TICK_PER_SECOND) >> 8); + buffer[7] = (uint8)((tick / TICK_PER_SECOND)); + + buffer[8] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 24); + buffer[9] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 16); + buffer[10] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 8); + buffer[11] = (uint8)(((tick % TICK_PER_SECOND) * 1000)); + wiz_sock_sendto(sock, buffer, send_size, param.host, param.port); + break; + } + } + if(getSn_SR(sock) != SOCK_CLOSED) wiz_sock_close(sock); + free(buffer); + KPrintf("iperf udp mode exit...\n"); +} + +static void iperf_udp_server(void *thread_param) +{ + int sock, sender_len, r_size; + uint8 *buffer, client_addr[4]; + uint16 client_port; + uint32 pcount = 0, last_pcount = 0; + uint32 lost, total; + uint64 recvlen; + x_ticks_t tick1, tick2; + struct timeval timeout; + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + return; + } + + sock = 0; //todo + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + KPrintf("iperf udp server run...\n"); + while (param.mode != IPERF_MODE_STOP){ + tick1 = CurrentTicksGain(); + tick2 = tick1; + lost = 0; + total = 0; + recvlen = 0; + while ((tick2 - tick1) < (TICK_PER_SECOND * 5)){ + switch(getSn_SR(sock)){ + case SOCK_UDP: + if ((r_size = getSn_RX_RSR(sock)) > 0){ + if (r_size > IPERF_BUFSZ) r_size = IPERF_BUFSZ; + memset(buffer, 0, IPERF_BUFSZ); + wiz_sock_recvfrom(sock, buffer, r_size, client_addr, &client_port); + recvlen += r_size; + last_pcount = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; + if(last_pcount > pcount){ + total += last_pcount - pcount; + lost += last_pcount - pcount - 1; + pcount = last_pcount; + } + else if(last_pcount < 10){ + pcount = last_pcount; + total = 1; + lost = 0; + } + } + tick2 = CurrentTicksGain(); + break; + case SOCK_CLOSED: + wiz_socket(sock, Sn_MR_UDP, param.port, 0x00); + break; + } + } + if (recvlen > 0){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = recvlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps! recv:%d lost:%d total:%d\n", tid->task_base_info.name, integer, decimal, total - lost, lost, total); + } + } + free(buffer); + if(getSn_SR(sock) != SOCK_CLOSED) wiz_sock_close(sock); +} + +static void iperf_client(void *thread_param) +{ + int i; + int sock = 0; + int ret; + uint8_t *send_buf, connected = 0; + uint64 sentlen; + x_ticks_t tick1, tick2; + + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + send_buf = (uint8_t *) malloc(IPERF_BUFSZ); + if (!send_buf) return ; + + for (i = 0; i < IPERF_BUFSZ; i ++) + send_buf[i] = i & 0xff; + + while (param.mode != IPERF_MODE_STOP) + { + while((getSn_SR(sock) != SOCK_ESTABLISHED || !connected) && param.mode != IPERF_MODE_STOP){ + switch (getSn_SR(sock)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sock) & Sn_IR_CON) { + KPrintf("Connected\n", sock); + setSn_IR(sock, Sn_IR_CON); + } + connected = 1; + break; + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sock); + break; + case SOCK_INIT: + KPrintf("Socket %d:try to connect to [%d.%d.%d.%d:%d]...", + sock, param.host[0], param.host[1], param.host[2], param.host[3], param.port); + ret = wiz_sock_connect(sock, param.host, param.port); + if (ret != SOCK_OK){ + printf("failed, wait 1s to try again\n"); + MdelayKTask(1000); + } + break; + case SOCK_CLOSED: + if(connected) KPrintf("Socket %d:closed\n", sock); + wiz_socket(sock, Sn_MR_TCP, param.port, 0x00); + connected = 0; + break; + default: + break; + } + } + + sentlen = 0; + + tick1 = CurrentTicksGain(); + while (param.mode != IPERF_MODE_STOP){ + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = sentlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps!\n", tid->task_base_info.name, integer, decimal); + tick1 = tick2; + sentlen = 0; + } + + ret = wiz_sock_send(sock, send_buf, IPERF_BUFSZ); + if (ret > 0){ + sentlen += ret; + } + + if (ret < 0) break; + } + + if(getSn_SR(sock) != SOCK_CLOSED)wiz_sock_close(sock); + + KPrintf("Disconnected, iperf client exit!"); + } + free(send_buf); +} + +static void iperf_server(void *thread_param) +{ + uint8_t *recv_data; + x_ticks_t tick1, tick2; + int sock = -1, connected = 0, bytes_received; + uint64 recvlen; + + sock = 0; //todo + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + recv_data = (uint8_t *)malloc(IPERF_BUFSZ); + if (recv_data == NULL){ + KPrintf("No memory!\n"); + goto __exit; + } + + while (param.mode != IPERF_MODE_STOP){ + while((getSn_SR(sock) != SOCK_ESTABLISHED || !connected)){ + switch (getSn_SR(sock)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sock) & Sn_IR_CON) { + KPrintf("Socket %d:Connected\n", sock); + setSn_IR(sock, Sn_IR_CON); + } + recvlen = 0; + tick1 = CurrentTicksGain(); + connected = 1; + break; + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sock); + break; + case SOCK_INIT: + KPrintf("Socket %d:Listen, port [%d]\n", sock, param.port); + wiz_sock_listen(sock); + break; + case SOCK_CLOSED: + if(connected) KPrintf("Socket %d:closed\n", sock); + wiz_socket(sock, Sn_MR_TCP, param.port, 0x00); + connected = 0; + break; + default: + break; + } + if(param.mode == IPERF_MODE_STOP) goto __exit; + } + + if ((bytes_received = getSn_RX_RSR(sock)) > 0) { + if (bytes_received > IPERF_BUFSZ) bytes_received = IPERF_BUFSZ; + memset(recv_data, 0, IPERF_BUFSZ); + wiz_sock_recv(sock, recv_data, bytes_received); + recvlen += bytes_received; + } + + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = recvlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps!\n", tid->task_base_info.name, integer, decimal); + tick1 = tick2; + recvlen = 0; + } + } + +__exit: + if(getSn_SR(sock) != SOCK_CLOSED)wiz_sock_close(sock); + if (recv_data) free(recv_data); +} + +void iperf_usage(void) +{ + KPrintf("Usage: iperf [-s|-c host] [options] [multi-threaded]\n"); + KPrintf(" iperf [-h|--stop]\n"); + KPrintf("\n"); + KPrintf("Client/Server:\n"); + KPrintf(" -p # server port to listen on/connect to\n"); + KPrintf("\n"); + KPrintf("Server specific:\n"); + KPrintf(" -s run in server mode\n"); + KPrintf("\n"); + KPrintf("Client specific:\n"); + KPrintf(" -c run in client mode, connecting to \n"); + KPrintf("\n"); + KPrintf("Miscellaneous:\n"); + KPrintf(" -h print this message and quit\n"); + KPrintf(" --stop stop iperf program\n"); + KPrintf(" -u testing UDP protocol\n"); + KPrintf(" -m