From 968d66e5a93516021a425f54bf0ced991377ceea Mon Sep 17 00:00:00 2001 From: tuyuyang <1163589503@qq.com> Date: Sun, 25 Aug 2024 23:29:34 +0800 Subject: [PATCH] Support sleep --- .../arch/arm/armv7-a/cortex-a9/core.h | 2 +- Ubiquitous/XiZi_AIoT/services/app/Makefile | 8 +++- .../XiZi_AIoT/services/app/test_sleep.c | 24 ++++++++++ .../services/lib/usyscall/usyscall.c | 5 +++ .../services/lib/usyscall/usyscall.h | 5 ++- .../XiZi_AIoT/softkernel/include/syscall.h | 2 + .../XiZi_AIoT/softkernel/include/task.h | 8 ++++ .../XiZi_AIoT/softkernel/syscall/Makefile | 1 + .../XiZi_AIoT/softkernel/syscall/sys_sleep.c | 45 +++++++++++++++++++ .../XiZi_AIoT/softkernel/syscall/sys_state.c | 6 +++ .../XiZi_AIoT/softkernel/syscall/syscall.c | 3 ++ Ubiquitous/XiZi_AIoT/softkernel/task/task.c | 5 ++- .../softkernel/trap/clock_irq_handler.c | 14 ++++++ 13 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 Ubiquitous/XiZi_AIoT/services/app/test_sleep.c create mode 100644 Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h index 01c5623bf..2115c3633 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv7-a/cortex-a9/core.h @@ -74,7 +74,7 @@ Modification: #include "cortex_a9.h" -#define NR_CPU 4 +#define NR_CPU 1 __attribute__((always_inline, optimize("O0"))) static inline uint32_t user_mode() { diff --git a/Ubiquitous/XiZi_AIoT/services/app/Makefile b/Ubiquitous/XiZi_AIoT/services/app/Makefile index 2b5808fe6..fb0d3838d 100644 --- a/Ubiquitous/XiZi_AIoT/services/app/Makefile +++ b/Ubiquitous/XiZi_AIoT/services/app/Makefile @@ -43,9 +43,9 @@ INC_DIR = -I$(KERNEL_ROOT)/services/shell/letter-shell \ -I$(KERNEL_ROOT)/services/app ifeq ($(BOARD), imx6q-sabrelite) -all: test_fault simple_client simple_server shell fs_server semaphore_server test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin +all: test_fault simple_client simple_server shell fs_server semaphore_server test_sleep test_semaphore test_ipc_null test_thread test_irq_hdlr test_irq_block test_irq_send eth_driver epit_server test_net lwip readme.txt | bin else -all: test_fault simple_client simple_server shell fs_server semaphore_server test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal | bin +all: test_fault simple_client simple_server shell fs_server semaphore_server test_sleep test_ipc_null test_thread test_semaphore test_net lwip readme.txt eth_hal | bin endif ../tools/mkfs/mkfs ./fs.img $^ @mv $(filter-out readme.txt, $^) bin @@ -69,6 +69,10 @@ epit_server: timer.o epit.o ccm_pll.o usyscall.o arch_usyscall.o libserial.o pri @${objdump} -S $@ > $@.asm endif +test_sleep: test_sleep.o libserial.o printf.o usyscall.o arch_usyscall.o + @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} + @${objdump} -S $@ > $@.asm + test_semaphore: test_semaphore.o libserial.o printf.o usyscall.o arch_usyscall.o @${ld} ${user_ldflags} -e main -o $@ $^ ${board_specs} @${objdump} -S $@ > $@.asm diff --git a/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c b/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c new file mode 100644 index 000000000..16c02dd01 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/services/app/test_sleep.c @@ -0,0 +1,24 @@ +/* + * 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. + */ + +#include "libserial.h" +#include "usyscall.h" + +int main(int argc, char* argv[]) +{ + while (true) { + printf("sleep for 2 seconds\n"); + sleep(2000); + } + + exit(0); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c index 8bdf03709..403d16e61 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c +++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.c @@ -153,4 +153,9 @@ bool semaphore_wait(int sem_id) bool semaphore_signal(int sem_id) { return syscall(SYSCALL_SEMAPHORE, (intptr_t)SYS_SEM_SIGNAL, (intptr_t)sem_id, 0, 0); +} + +int sleep(intptr_t ms) +{ + return syscall(SYSCALL_SLEEP, (intptr_t)ms, 0, 0, 0); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h index e76f684a1..de683f9cd 100644 --- a/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h +++ b/Ubiquitous/XiZi_AIoT/services/lib/usyscall/usyscall.h @@ -34,6 +34,7 @@ #define SYSCALL_KILL 12 // kill the task by id #define SYSCALL_SEMAPHORE 13 // semaphore related operations +#define SYSCALL_SLEEP 14 // sleep // clang-format on typedef enum { @@ -105,4 +106,6 @@ uintptr_t get_tick(); int semaphore_new(int val); bool semaphore_free(int sem_id); bool semaphore_wait(int sem_id); -bool semaphore_signal(int sem_id); \ No newline at end of file +bool semaphore_signal(int sem_id); + +int sleep(intptr_t ms); \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h index 14e2ddc7e..f2c0265d4 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/syscall.h @@ -48,6 +48,7 @@ Modification: #define SYSCALL_KILL 12 // kill the task by id #define SYSCALL_SEMAPHORE 13 // semaphore related operations +#define SYSCALL_SLEEP 14 // sleep // clang-format on #ifndef __ASSEMBLER__ @@ -113,4 +114,5 @@ int sys_unbind_irq_all(struct Thread* task); int sys_unbind_irq(struct Thread* task, int irq_num); int sys_semaphore(sys_sem_option op, int sem_id); +int sys_sleep(intptr_t ms); #endif diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index accfb513a..096a0613e 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -44,6 +44,7 @@ Modification: #define TASK_MAX_PRIORITY 32 #define TASK_DEFAULT_PRIORITY 2 #define TASK_NAME_MAX_LEN 16 +#define SLEEP_MONITOR_CORE 0 enum ProcState { INIT = 0, @@ -51,6 +52,7 @@ enum ProcState { RUNNING, DEAD, BLOCKED, + SLEEPING, NEVER_RUN, }; @@ -72,6 +74,10 @@ struct ThreadContext { struct trapframe* trapframe; }; +struct TaskSleepContext { + int64_t remain_ms; +}; + /* Process Control Block */ struct Thread { /* task name */ @@ -97,6 +103,7 @@ struct Thread { /* task schedule attributes */ struct double_list_node node; + struct TaskSleepContext sleep_context; enum ProcState state; int priority; // priority int remain_tick; @@ -114,6 +121,7 @@ struct XiziTaskManager { struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */ struct double_list_node task_running_list_head; struct double_list_node task_blocked_list_head; + struct double_list_node task_sleep_list_head; struct XiziSemaphorePool semaphore_pool; /* mem allocator */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile index 4adbb947d..6a144502d 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/Makefile @@ -1,6 +1,7 @@ SRC_FILES := syscall.c \ sys_spawn.c \ sys_thread.c \ + sys_sleep.c \ sys_yield.c \ sys_register_as_server.c \ sys_connect_session.c \ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c new file mode 100644 index 000000000..bce382597 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_sleep.c @@ -0,0 +1,45 @@ +/* + * 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 sys_sleep.c + * @brief task sleep + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2023.08.25 + */ + +/************************************************* +File name: sys_sleep.c +Description: +Others: +History: +1. Date: 2023-08-28 +Author: AIIT XUOS Lab +Modification: +1. first version +*************************************************/ +#include "multicores.h" +#include "syscall.h" +#include "task.h" + +#include "assert.h" + +int sys_sleep(intptr_t ms) +{ + struct Thread* cur_task = cur_cpu()->task; + xizi_task_manager.task_yield_noschedule(cur_task, false); + xizi_task_manager.task_block(&xizi_task_manager.task_sleep_list_head, cur_task); + cur_task->state = SLEEPING; + cur_task->sleep_context.remain_ms = ms; + + return 0; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c index 67aea6b05..53406e3e2 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/sys_state.c @@ -91,6 +91,12 @@ void show_tasks(void) SHOWTASK_TASK_BASE_INFO(task); } + DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_sleep_list_head, node) + { + LOG_PRINTF("%-8s", "SLEEP"); + SHOWTASK_TASK_BASE_INFO(task); + } + struct ksemaphore* sem = NULL; DOUBLE_LIST_FOR_EACH_ENTRY(sem, &xizi_task_manager.semaphore_pool.sem_list_guard, sem_list_node) { diff --git a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c index d3ae51f67..c6985c194 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/syscall/syscall.c @@ -80,6 +80,9 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u case SYSCALL_SEMAPHORE: ret = sys_semaphore((sys_sem_option)param1, (int)param2); break; + case SYSCALL_SLEEP: + ret = sys_sleep((intptr_t)param1); + break; default: ERROR("Unsurport syscall(%d) right now\n", sys_num); ret = -1; diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 27df0e16e..b0d80b581 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -38,6 +38,7 @@ Modification: #include "scheduler.h" #include "syscall.h" #include "task.h" +#include "trap_common.h" struct CPU global_cpus[NR_CPU]; uint32_t ready_task_priority; @@ -70,6 +71,7 @@ static void _task_manager_init() } doubleListNodeInit(&xizi_task_manager.task_blocked_list_head); doubleListNodeInit(&xizi_task_manager.task_running_list_head); + doubleListNodeInit(&xizi_task_manager.task_sleep_list_head); // init task (slab) allocator slab_init(&xizi_task_manager.memspace_allocator, sizeof(struct MemSpace)); slab_init(&xizi_task_manager.task_allocator, sizeof(struct Thread)); @@ -286,6 +288,7 @@ extern void context_switch(struct context**, struct context*); static void _scheduler(struct SchedulerRightGroup right_group) { struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); + struct XiziTrapDriver* p_intr_driver = AchieveResource(&right_group.intr_driver_tag); struct Thread* next_task; struct CPU* cpu = cur_cpu(); @@ -347,7 +350,7 @@ static void _task_block(struct double_list_node* head, struct Thread* task) static void _task_unblock(struct Thread* task) { assert(task != NULL); - assert(task->state == BLOCKED); + assert(task->state == BLOCKED || task->state == SLEEPING); task_node_leave_list(task); task->state = READY; task_node_add_to_ready_list_back(task); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c index eba875e07..937e4b219 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/trap/clock_irq_handler.c @@ -69,6 +69,8 @@ int xizi_clock_handler(int irq, void* tf, void* arg) if (p_clock_driver->is_timer_expired()) { p_clock_driver->clear_clock_intr(); global_tick++; + + // handle current thread struct Thread* current_task = cur_cpu()->task; if (current_task) { current_task->remain_tick--; @@ -77,6 +79,18 @@ int xizi_clock_handler(int irq, void* tf, void* arg) xizi_task_manager.task_yield_noschedule(current_task, false); } } + + // todo: cpu 0 will handle sleeping thread + struct Thread* thread = NULL; + DOUBLE_LIST_FOR_EACH_ENTRY(thread, &xizi_task_manager.task_sleep_list_head, node) + { + assert(thread->state == SLEEPING); + thread->sleep_context.remain_ms--; + if (thread->sleep_context.remain_ms <= 0) { + xizi_task_manager.task_unblock(thread); + break; + } + } } return 0; } \ No newline at end of file