From 5e499bf975ee0886e515782c52b71ae8a0fec303 Mon Sep 17 00:00:00 2001 From: Liu_Weichao Date: Fri, 10 Mar 2023 17:11:53 +0800 Subject: [PATCH] add soft timer posix support in XiZi --- APP_Framework/Applications/app_test/Kconfig | 6 +- APP_Framework/Applications/app_test/Makefile | 4 + .../Applications/app_test/test_timer.c | 63 +++++ .../transform_layer/xizi/transform.c | 30 +++ .../transform_layer/xizi/transform.h | 8 + .../xizi/user_api/posix_support/Makefile | 4 + .../user_api/posix_support/include/signal.h | 151 +++++++++++ .../user_api/posix_support/include/timer.h | 53 ++++ .../xizi/user_api/posix_support/timer.c | 118 +++++++++ .../xizi/user_api/switch_api/Makefile | 4 + .../xizi/user_api/switch_api/user_api.h | 16 ++ .../xizi/user_api/switch_api/user_timer.c | 90 +++++++ .../XiZi_IIoT/kernel/include/user_api.h | 16 ++ .../XiZi_IIoT/kernel/include/xs_service.h | 6 + .../kernel/kernel_service/xs_service.c | 241 +++++++++++++----- .../XiZi_IIoT/kernel/thread/softtimer.c | 2 +- 16 files changed, 741 insertions(+), 71 deletions(-) create mode 100644 APP_Framework/Applications/app_test/test_timer.c create mode 100644 APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/signal.h create mode 100644 APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/timer.h create mode 100644 APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/timer.c create mode 100644 APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_timer.c diff --git a/APP_Framework/Applications/app_test/Kconfig b/APP_Framework/Applications/app_test/Kconfig index 271d4cde6..45df5f5d5 100644 --- a/APP_Framework/Applications/app_test/Kconfig +++ b/APP_Framework/Applications/app_test/Kconfig @@ -235,6 +235,10 @@ menu "test app" default "/dev/qspi_W25Q128" endif endif - + + menuconfig USER_TEST_TIMER + bool "Config test soft timer" + default n + endif endmenu diff --git a/APP_Framework/Applications/app_test/Makefile b/APP_Framework/Applications/app_test/Makefile index 080fbe113..1cf919846 100644 --- a/APP_Framework/Applications/app_test/Makefile +++ b/APP_Framework/Applications/app_test/Makefile @@ -97,5 +97,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_FILES += test_can.c endif + ifeq ($(CONFIG_USER_TEST_TIMER),y) + SRC_FILES += test_timer.c + endif + include $(KERNEL_ROOT)/compiler.mk endif diff --git a/APP_Framework/Applications/app_test/test_timer.c b/APP_Framework/Applications/app_test/test_timer.c new file mode 100644 index 000000000..4fbc8f310 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_timer.c @@ -0,0 +1,63 @@ +/* +* 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: test_timer.c +* @brief: a application of soft timer function +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/03/09 +*/ + +#include + +void TimerFunction(union sigval sig_val) +{ + static int cnt = 0; + printf("%s cnt %d\n", __func__, cnt++); +} + +void TestTimer(void) +{ + int ret = 0; + timer_t timer_id; + struct sigevent evp; + memset(&evp, 0, sizeof(struct sigevent)); + + evp.sigev_notify = SIGEV_THREAD; + evp.sigev_notify_function = TimerFunction; + + ret = timer_create(CLOCK_REALTIME, &evp, &timer_id); + if (ret < 0) { + printf("%s create timer failed ret %d\n", __func__, ret); + return; + } + + struct itimerspec value; + //active time interval + value.it_interval.tv_sec = 2; + value.it_interval.tv_nsec = 0; + + //first timer set time + value.it_value.tv_sec = 2; + value.it_value.tv_nsec = 0; + + ret = timer_settime(timer_id, 0, &value, NULL); + if (ret < 0) { + printf("%s set timer time failed ret %d\n", __func__, ret); + return; + } + + printf("%s success\n", __func__); +} +PRIV_SHELL_CMD_FUNCTION(TestTimer, soft timer test, PRIV_SHELL_CMD_MAIN_ATTR); + diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index 8ac037c0b..cc8aa5dd3 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -107,6 +107,36 @@ uint32_t PrivGetTickTime() return CalculateTimeMsFromTick(CurrentTicksGain()); } #endif + +/******************Soft Timer*********************/ +int PrivTimerCreate(clockid_t clockid, struct sigevent * evp, timer_t * timerid) +{ + return timer_create(clockid, evp, timerid); +} + +int PrivTimerDelete(timer_t timerid) +{ + return timer_delete(timerid); +} + +int PrivTimerStartRun(timer_t timerid) +{ + return UserTimerStartRun(timerid); +} + +int PrivTimerQuitRun(timer_t timerid) +{ + return UserTimerQuitRun(timerid); +} + +int PrivTimerModify(timer_t timerid, int flags, const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue) +{ + return timer_settime(timerid, flags, value, ovalue); +} + +/*************************************************/ + /*********************fs**************************/ #ifdef FS_VFS /************************Driver Posix Transform***********************/ diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index 68ed30a8a..597ad2e92 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -377,6 +378,13 @@ void *PrivRealloc(void *pointer, size_t size); void *PrivCalloc(size_t count, size_t size); void PrivFree(void *pointer); +/******************soft timer*********************/ +int PrivTimerCreate(clockid_t clockid, struct sigevent * evp, timer_t * timerid); +int PrivTimerDelete(timer_t timerid); +int PrivTimerStartRun(timer_t timerid); +int PrivTimerQuitRun(timer_t timerid); +int PrivTimerModify(timer_t timerid, int flags, const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); #ifdef __cplusplus } diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/Makefile b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/Makefile index abdf776a8..c6f238b2b 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/Makefile +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/Makefile @@ -11,4 +11,8 @@ ifeq ($(CONFIG_KERNEL_MESSAGEQUEUE),y) SRC_FILES += mqueue.c endif +ifeq ($(CONFIG_KERNEL_SOFTTIMER),y) + SRC_FILES += timer.c +endif + include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/signal.h b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/signal.h new file mode 100644 index 000000000..fd77b03bd --- /dev/null +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/signal.h @@ -0,0 +1,151 @@ +/* + * 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: signal.h +* @brief: the function definition of posix signal +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/9 +* +*/ + +#ifndef SIGNAL_H +#define SIGNAL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* sigev_notify values + NOTE: P1003.1c/D10, p. 34 adds SIGEV_THREAD. */ + +#define SIGEV_NONE 1 /* No asynchronous notification shall be delivered */ + /* when the event of interest occurs. */ +#define SIGEV_SIGNAL 2 /* A queued signal, with an application defined */ + /* value, shall be delivered when the event of */ + /* interest occurs. */ +#define SIGEV_THREAD 3 /* A notification function shall be called to */ + /* perform notification. */ + +/* Signal Generation and Delivery, P1003.1b-1993, p. 63 + NOTE: P1003.1c/D10, p. 34 adds sigev_notify_function and + sigev_notify_attributes to the sigevent structure. */ +union sigval +{ + int sival_int; /* Integer signal value */ + void *sival_ptr; /* Pointer signal value */ +}; + +struct sigevent +{ + int sigev_notify; /* Notification type */ + int sigev_signo; /* Signal number */ + union sigval sigev_value; /* Signal value */ + void (*sigev_notify_function)( union sigval ); + /* Notification function */ + void *sigev_notify_attributes; /* Notification Attributes, really pthread_attr_t */ +}; + +struct siginfo +{ + uint16_t si_signo; + uint16_t si_code; + + union sigval si_value; +}; +typedef struct siginfo siginfo_t; + +#define SI_USER 0x01 /* Signal sent by kill(). */ +#define SI_QUEUE 0x02 /* Signal sent by sigqueue(). */ +#define SI_TIMER 0x03 /* Signal generated by expiration of a timer set by timer_settime(). */ +#define SI_ASYNCIO 0x04 /* Signal generated by completion of an asynchronous I/O request. */ +#define SI_MESGQ 0x05 /* Signal generated by arrival of a message on an empty message queue. */ + +typedef void (*_sig_func_ptr)(int); +typedef unsigned long sigset_t; + +struct sigaction +{ + _sig_func_ptr sa_handler; + sigset_t sa_mask; + int sa_flags; +}; + +/* + * Structure used in sigaltstack call. + */ +typedef struct sigaltstack +{ + void *ss_sp; /* Stack base or pointer. */ + int ss_flags; /* Flags. */ + size_t ss_size; /* Stack size. */ +} stack_t; + +#define SIG_SETMASK 0 /* set mask with sigprocmask() */ +#define SIG_BLOCK 1 /* set of signals to block */ +#define SIG_UNBLOCK 2 /* set of signals to, well, unblock */ + +#define sigaddset(what,sig) (*(what) |= (1<<(sig)), 0) +#define sigdelset(what,sig) (*(what) &= ~(1<<(sig)), 0) +#define sigemptyset(what) (*(what) = 0, 0) +#define sigfillset(what) (*(what) = ~(0), 0) +#define sigismember(what,sig) (((*(what)) & (1<<(sig))) != 0) + +#if defined(__GNUC__) + +#define SIGHUP 1 /* hangup */ +#define SIGINT 2 /* interrupt */ +#define SIGQUIT 3 /* quit */ +#define SIGILL 4 /* illegal instruction (not reset when caught) */ +#define SIGTRAP 5 /* trace trap (not reset when caught) */ +#define SIGIOT 6 /* IOT instruction */ +#define SIGABRT 6 /* used by abort, replace SIGIOT in the future */ +#define SIGEMT 7 /* EMT instruction */ +#define SIGFPE 8 /* floating point exception */ +#define SIGKILL 9 /* kill (cannot be caught or ignored) */ +#define SIGBUS 10 /* bus error */ +#define SIGSEGV 11 /* segmentation violation */ +#define SIGSYS 12 /* bad argument to system call */ +#define SIGPIPE 13 /* write on a pipe with no one to read it */ +#define SIGALRM 14 /* alarm clock */ +#define SIGTERM 15 /* software termination signal from kill */ +#define SIGURG 16 /* urgent condition on IO channel */ +#define SIGSTOP 17 /* sendable stop signal not from tty */ +#define SIGTSTP 18 /* stop signal from tty */ +#define SIGCONT 19 /* continue a stopped process */ +#define SIGCHLD 20 /* to parent on child stop or exit */ +#define SIGCLD 20 /* System V name for SIGCHLD */ +#define SIGTTIN 21 /* to readers pgrp upon background tty read */ +#define SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ +#define SIGIO 23 /* input/output possible signal */ +#define SIGPOLL SIGIO /* System V name for SIGIO */ +#define SIGXCPU 24 /* exceeded CPU time limit */ +#define SIGXFSZ 25 /* exceeded file size limit */ +#define SIGVTALRM 26 /* virtual time alarm */ +#define SIGPROF 27 /* profiling time alarm */ +#define SIGWINCH 28 /* window changed */ +#define SIGLOST 29 /* resource lost (eg, record-lock lost) */ +#define SIGUSR1 30 /* user defined signal 1 */ +#define SIGUSR2 31 /* user defined signal 2 */ +#define NSIG 32 /* signal 0 implied */ + +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/timer.h b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/timer.h new file mode 100644 index 000000000..91bc76101 --- /dev/null +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/timer.h @@ -0,0 +1,53 @@ +/* + * 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: timer.h +* @brief: the function definition of posix soft timer +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/8 +* +*/ + +#ifndef TIMER_H +#define TIMER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "../../switch_api/user_api.h" + +#if !defined(LIB_MUSLLIB) +#include "signal.h" +#endif + +#include + +#ifndef TIMER_TRIGGER_ONCE +#define TIMER_TRIGGER_ONCE (1 << 0) +#endif +#ifndef TIMER_TRIGGER_PERIODIC +#define TIMER_TRIGGER_PERIODIC (1 << 1) +#endif + +int timer_create(clockid_t clockid, struct sigevent * evp, timer_t * timerid); +int timer_delete(timer_t timerid); +int timer_settime(timer_t timerid, int flags, const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/timer.c b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/timer.c new file mode 100644 index 000000000..ab6d27155 --- /dev/null +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/timer.c @@ -0,0 +1,118 @@ +/* + * 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: timer.c +* @brief: posix api of soft timer +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/8 +* +*/ + +#include +#include +#include "include/timer.h" +#include "include/semaphore.h" +#include "include/pthread.h" + +static sem_t timer_sem; +static pthread_t timer_task; + +struct timer_func { + union sigval value; + void (* user_timer_function)(union sigval val); +}; + +struct timer_func g_timer_func; + +static void *timer_callback(void *args) +{ + struct sigevent *evp = (struct sigevent *)args; + + while (1) { + if (g_timer_func.user_timer_function != NULL) { + if (0 == sem_timedwait(&timer_sem, NULL)) { + g_timer_func.user_timer_function(g_timer_func.value); + } + } + } +} + +int timer_create(clockid_t clockid, struct sigevent * evp, timer_t * timerid) +{ + int timer_id; + char timer_name[16]; + + if ((NULL == evp) || (NULL == timerid) || + (clockid != CLOCK_REALTIME)) { + errno = EINVAL; + return -1; + } + + /* Only support SIGEV_THREAD. */ + if (evp->sigev_notify != SIGEV_THREAD) { + errno = ENOTSUP; + return -1; + } + + memset(timer_name, 0, sizeof(timer_name)); + snprintf(timer_name, sizeof(timer_name), "timer_%d", clockid); + + sem_init(&timer_sem, 0, 0); + + g_timer_func.value = evp->sigev_value; + g_timer_func.user_timer_function = evp->sigev_notify_function; + + pthread_attr_t attr; + attr.schedparam.sched_priority = 22; + attr.stacksize = 2048; + + pthread_create(&timer_task, &attr, &timer_callback, (void *)evp); + + timer_id = UserTimerCreate(timer_name, NULL, (void *)&timer_sem, 0, TIMER_TRIGGER_PERIODIC); + *timerid = timer_id; + return timer_id; +} + +int timer_delete(timer_t timerid) +{ + pthread_kill(timer_task, 0); + + UserTimerQuitRun(timerid); + + sem_destroy(&timer_sem); + + return 0; +} + +int timer_settime(timer_t timerid, int flags, const struct itimerspec *restrict value, + struct itimerspec *restrict ovalue) +{ + if (NULL == value) { + errno = EFAULT; + return -1; + } + + //reference from RTT + /* calculate timer period(tick); To avoid lost of accuracy, because "TICK_PER_SECOND" maybe 100, 1000, 1024 and so on. + * + * tick nanosecond nanosecond * TICK_PER_SECOND + * ------------------------- = -------------------------- ---> tick = ------------------------------------- + * TICK_PER_SECOND NANOSECOND_PER_SECOND NANOSECOND_PER_SECOND + * + */ + int ticks = (value->it_interval.tv_sec * TICK_PER_SECOND) + (value->it_interval.tv_nsec * TICK_PER_SECOND) / 1000000000; + + UserTimerModify(timerid, ticks); + UserTimerStartRun(timerid); +} diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/Makefile b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/Makefile index 02b6b0c75..68a10858a 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/Makefile +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/Makefile @@ -17,6 +17,10 @@ ifeq ($(CONFIG_SEPARATE_COMPILE),y) SRC_FILES += user_msg.c endif + ifeq ($(CONFIG_KERNEL_SOFTTIMER),y) + SRC_FILES += user_timer.c + endif + ifeq ($(CONFIG_FS_VFS),y) SRC_FILES += user_fs.c endif diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_api.h b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_api.h index 660c709e7..bf3d2affb 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_api.h +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_api.h @@ -123,6 +123,14 @@ long UserMsgQueueRecv(int32_t mq, void *buffer, size_t size,int32_t wait_time); long UserMsgQueueReinit(int32_t mq); #endif +#ifdef KERNEL_SOFTTIMER +int32_t UserTimerCreate(const char *name, void (*timeout)(void *parameter), void *parameter, uint32_t time, uint8_t trigger_mode); +long UserTimerDelete(int32_t timer_id); +long UserTimerStartRun(int32_t timer_id); +long UserTimerQuitRun(int32_t timer_id); +long UserTimerModify(int32_t timer_id, uint32_t ticks); +#endif + int open(const char *path, int flags, ...); int read(int fd, void *buf, size_t len); int write(int fd, const void *buf, size_t len); @@ -240,6 +248,14 @@ uint8_t UserGetTaskPriority(int32_t id); #define UserMsgQueueReinit KMsgQueueReinit #endif +#ifdef KERNEL_SOFTTIMER +int32_t UserTimerCreate(const char *name, void (*timeout)(void *parameter), void *parameter, uint32_t time, uint8_t trigger_mode); +long UserTimerDelete(int32_t timer_id); +long UserTimerStartRun(int32_t timer_id); +long UserTimerQuitRun(int32_t timer_id); +long UserTimerModify(int32_t timer_id, uint32_t ticks); +#endif + #define UserPrintf KPrintf #endif diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_timer.c b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_timer.c new file mode 100644 index 000000000..3057bde8e --- /dev/null +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/switch_api/user_timer.c @@ -0,0 +1,90 @@ +/* + * 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: user_timer.c +* @brief: the priviate user api of soft timer for application +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/3/8 +* +*/ + +#include "user_api.h" + +/** + * This function will create a soft timer. + * + * @param name the name of the timer. + * @param timeout the callback of the timer. + * @param parameter the parameter of the callback function + * @param time the timeout time + * @param trigger_mode the trigger way of the timer + * + * @return id on success;ENOMEMORY/ERROR on failure + */ +int32_t UserTimerCreate(const char *name, + void (*timeout)(void *parameter), + void *parameter, + uint32_t time, + uint8_t trigger_mode) { + return (int32_t)KSwitch5(KS_USER_TIMER_CREATE, (uintptr_t)name, (uintptr_t)timeout, (uintptr_t)parameter, (uintptr_t)time, (uintptr_t)trigger_mode); +} + +/** + * This function will delete a timer. + * + * @param timer_id the id number of timer. + * + * @return EOK on success;EINVALED on failure + * + */ +x_err_t UserTimerDelete(int32_t timer_id) { + return (x_err_t)KSwitch1(KS_USER_TIMER_DELETE, (uintptr_t)timer_id); +} + +/** + * This function will startup a timer. + * + * @param timer_id the id number of timer. + * + * @return EOK on success;EINVALED on failure + * + */ +x_err_t UserTimerStartRun(int32_t timer_id) { + return (x_err_t)KSwitch1(KS_USER_TIMER_STARTRUN, (uintptr_t)timer_id); +} + +/** + * This function will stop a timer. + * + * @param timer_id the id number of timer. + * + * @return EOK on success;EINVALED on failure + * + */ +x_err_t UserTimerQuitRun(int32_t timer_id) { + return (x_err_t)KSwitch1(KS_USER_TIMER_QUITRUN, (uintptr_t)timer_id); +} + +/** + * This function will modify the timeout of a timer. + * + * @param timer_id the id number of timer. + * @param ticks timeout ticks + * + * @return EOK on success;EINVALED on failure + * + */ +x_err_t UserTimerModify(int32_t timer_id, uint32_t ticks) { + return (x_err_t)KSwitch2(KS_USER_TIMER_MODIFY, (uintptr_t)timer_id, (uintptr_t)ticks); +} diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/user_api.h b/Ubiquitous/XiZi_IIoT/kernel/include/user_api.h index b804f06ac..29410198f 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/user_api.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/user_api.h @@ -126,6 +126,14 @@ x_err_t UserMsgQueueRecv(int32_t mq, void *buffer, size_t size,int32_t wait_tim x_err_t UserMsgQueueReinit(int32_t mq); #endif +#ifdef KERNEL_SOFTTIMER +int32_t UserTimerCreate(const char *name, void (*timeout)(void *parameter), void *parameter, uint32_t time, uint8_t trigger_mode); +x_err_t UserTimerDelete(int32_t timer_id); +x_err_t UserTimerStartRun(int32_t timer_id); +x_err_t UserTimerQuitRun(int32_t timer_id); +x_err_t UserTimerModify(int32_t timer_id, uint32_t ticks); +#endif + int open(const char *path, int flags, ...); int read(int fd, void *buf, size_t len); int write(int fd, const void *buf, size_t len); @@ -239,6 +247,14 @@ uint8_t UserGetTaskPriority(int32_t id); #define UserMsgQueueReinit KMsgQueueReinit #endif +#ifdef KERNEL_SOFTTIMER +int32_t UserTimerCreate(const char *name, void (*timeout)(void *parameter), void *parameter, uint32_t time, uint8_t trigger_mode); +x_err_t UserTimerDelete(int32_t timer_id); +x_err_t UserTimerStartRun(int32_t timer_id); +x_err_t UserTimerQuitRun(int32_t timer_id); +x_err_t UserTimerModify(int32_t timer_id, uint32_t ticks); +#endif + #define UserPrintf KPrintf diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/xs_service.h b/Ubiquitous/XiZi_IIoT/kernel/include/xs_service.h index d213f9f9f..493fb28f7 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/xs_service.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/xs_service.h @@ -74,6 +74,12 @@ enum KernelServiceEnum KS_USER_MSGQUEUE_RECV, KS_USER_MSGQUEUE_REINIT, + KS_USER_TIMER_CREATE, + KS_USER_TIMER_DELETE, + KS_USER_TIMER_STARTRUN, + KS_USER_TIMER_QUITRUN, + KS_USER_TIMER_MODIFY, + KS_USER_OPEN, KS_USER_READ, KS_USER_WRITE, diff --git a/Ubiquitous/XiZi_IIoT/kernel/kernel_service/xs_service.c b/Ubiquitous/XiZi_IIoT/kernel/kernel_service/xs_service.c index d24a1ee34..d857f2cd5 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/kernel_service/xs_service.c +++ b/Ubiquitous/XiZi_IIoT/kernel/kernel_service/xs_service.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef FS_VFS #include @@ -401,6 +402,53 @@ uintptr_t KsMsgQueueReinit(uint32_t knum,uintptr_t *param, uint8_t num ) return (uintptr_t)ret; } #endif + +#ifdef KERNEL_SOFTTIMER +static int32 timer_sem; +static void KsTimerCallback(void *parameter) +{ + KSemaphoreAbandon(timer_sem); +} + +uintptr_t KsTimerCreate(uint32_t knum, uintptr_t *param, uint8_t num) +{ + int32 ret; + + timer_sem = *((int *)param[2]); + + ret = KCreateTimer((const char *)(param[0]), KsTimerCallback, (void *)(param[2]), (x_ticks_t)(param[3]), (uint8)(param[4])); + return (uintptr_t)ret; +} + +uintptr_t KsTimerDelete(uint32_t knum, uintptr_t *param, uint8_t num) +{ + x_err_t ret; + ret = KDeleteTimer((int32)(param[0])); + return (uintptr_t)ret; +} + +uintptr_t KsTimerStartRun(uint32_t knum, uintptr_t *param, uint8_t num) +{ + x_err_t ret; + ret = KTimerStartRun((int32)(param[0])); + return (uintptr_t)ret; +} + +uintptr_t KsTimerQuitRun(uint32_t knum, uintptr_t *param, uint8_t num) +{ + x_err_t ret; + ret = KTimerQuitRun((int32)(param[0])); + return (uintptr_t)ret; +} + +uintptr_t KsTimerModify(uint32_t knum, uintptr_t *param, uint8_t num) +{ + x_err_t ret; + ret = KTimerModify((int32)(param[0]), (x_ticks_t)(param[1])); + return (uintptr_t)ret; +} +#endif + /* fs posix*/ #ifdef FS_VFS @@ -566,87 +614,95 @@ uintptr_t KsStatfs(uint32_t knum,uintptr_t *param, uint8_t num ) struct KernelService g_service_table[256] __attribute__ ((section (".g_service_table"))) = { - [KS_USER_PRINT_INFO] = { KsPrintInfo, 1 }, + [KS_USER_PRINT_INFO] = { KsPrintInfo, 1 }, - /*************** Task ************/ - [KS_USER_TASK_CREATE] = { KsTaskCreate, 5 }, - [KS_USER_TASK_STARTUP] = { KsStartupTask, 1 }, - [KS_USER_TASK_DELETE] = { KsTaskDelete, 1 }, - [KS_USER_TASK_SEARCH] = { KsUserTaskSerach, 0 }, - [KS_USER_TASK_EXECEXIT] = { KsTaskQuit, 0 }, - [KS_USER_TASK_CORE_COMBINE] = { KsTaskCoreCombine, 2 }, - [KS_USER_TASK_CORE_UNCOMBINE] = { KsTaskCoreUnCombine, 1 }, - [KS_USER_TASK_DELAY] = { KsMdelayTask, 1 }, - [KS_USER_GET_TASK_NAME] = { KsGetTaskName, 2 }, - [KS_USER_GET_TASK_ID] = { KsGetTaskID, 0 }, - [KS_USER_GET_TASK_STAT] = { KsGetTaskStat, 1 }, - [KS_USER_GET_TASK_COMBINEED_CORE] = { KsGetTaskCombinedCore, 1 }, - [KS_USER_GET_TASK_RUNNING_CORE] = { KsGetTaskRunningCore, 1 }, - [KS_USER_GET_TASK_ERROR_STATUS] = { KsGetTaskErrorstatus, 1 }, - [KS_USER_GET_TASK_PRIORITY] = { KsGetTaskPriority, 1 }, + /*************** Task ************/ + [KS_USER_TASK_CREATE] = { KsTaskCreate, 5 }, + [KS_USER_TASK_STARTUP] = { KsStartupTask, 1 }, + [KS_USER_TASK_DELETE] = { KsTaskDelete, 1 }, + [KS_USER_TASK_SEARCH] = { KsUserTaskSerach, 0 }, + [KS_USER_TASK_EXECEXIT] = { KsTaskQuit, 0 }, + [KS_USER_TASK_CORE_COMBINE] = { KsTaskCoreCombine, 2 }, + [KS_USER_TASK_CORE_UNCOMBINE] = { KsTaskCoreUnCombine, 1 }, + [KS_USER_TASK_DELAY] = { KsMdelayTask, 1 }, + [KS_USER_GET_TASK_NAME] = { KsGetTaskName, 2 }, + [KS_USER_GET_TASK_ID] = { KsGetTaskID, 0 }, + [KS_USER_GET_TASK_STAT] = { KsGetTaskStat, 1 }, + [KS_USER_GET_TASK_COMBINEED_CORE] = { KsGetTaskCombinedCore, 1 }, + [KS_USER_GET_TASK_RUNNING_CORE] = { KsGetTaskRunningCore, 1 }, + [KS_USER_GET_TASK_ERROR_STATUS] = { KsGetTaskErrorstatus, 1 }, + [KS_USER_GET_TASK_PRIORITY] = { KsGetTaskPriority, 1 }, - /*************** Memory ************/ - [KS_USER_MALLOC] = { KsMalloc, 1 }, - [KS_USER_FREE] = { KsFree, 1 }, + /*************** Memory ************/ + [KS_USER_MALLOC] = { KsMalloc, 1 }, + [KS_USER_FREE] = { KsFree, 1 }, #ifdef KERNEL_MUTEX - /*************** Mutex ************/ - [KS_USER_MUTEX_CREATE] = { KsCreateMutex, 0 }, - [KS_USER_MUTEX_DELETE] = { KsDeleteMutex, 1 }, - [KS_USER_MUTEX_OBTAIN] = { KsMutexObtain, 2 }, - [KS_USER_MUTEX_ABANDON] = { KsMutexAbandon, 1 }, + /*************** Mutex ************/ + [KS_USER_MUTEX_CREATE] = { KsCreateMutex, 0 }, + [KS_USER_MUTEX_DELETE] = { KsDeleteMutex, 1 }, + [KS_USER_MUTEX_OBTAIN] = { KsMutexObtain, 2 }, + [KS_USER_MUTEX_ABANDON] = { KsMutexAbandon, 1 }, #endif #ifdef KERNEL_SEMAPHORE - /*************** Semaphore ************/ - [KS_USER_SEMAPHORE_CREATE] = { KsCreateSemaphore, 1 }, - [KS_USER_SEMAPHORE_DELETE] = { KsDeleteSemaphore, 1 }, - [KS_USER_SEMAPHORE_OBTAIN] = { KsSemaphoreObtain, 2 }, - [KS_USER_SEMAPHORE_ABANDON] = { KsSemaphoreAbandon, 1 }, - [KS_USER_SEMAPHORE_SETVALUE] = { KsSemaphoreSetValue, 2 }, + /*************** Semaphore ************/ + [KS_USER_SEMAPHORE_CREATE] = { KsCreateSemaphore, 1 }, + [KS_USER_SEMAPHORE_DELETE] = { KsDeleteSemaphore, 1 }, + [KS_USER_SEMAPHORE_OBTAIN] = { KsSemaphoreObtain, 2 }, + [KS_USER_SEMAPHORE_ABANDON] = { KsSemaphoreAbandon, 1 }, + [KS_USER_SEMAPHORE_SETVALUE] = { KsSemaphoreSetValue, 2 }, #endif - /*************** Event ************/ + /*************** Event ************/ #ifdef KERNEL_EVENT - [KS_USER_EVENT_CREATE] = { KsCreateEvent, 1 }, - [KS_USER_EVENT_DELETE] = { KsDeleteEvent, 1 }, - [KS_USER_EVENT_TRIGGER] = { KsEventTrigger, 2 }, - [KS_USER_EVENT_PROCESS] = { KsEventProcess, 5 }, + [KS_USER_EVENT_CREATE] = { KsCreateEvent, 1 }, + [KS_USER_EVENT_DELETE] = { KsDeleteEvent, 1 }, + [KS_USER_EVENT_TRIGGER] = { KsEventTrigger, 2 }, + [KS_USER_EVENT_PROCESS] = { KsEventProcess, 5 }, #endif #ifdef KERNEL_MESSAGEQUEUE - /*************** Msg queue ************/ - [KS_USER_MSGQUEUE_CREATE] = { KsCreateMsgQueue, 2 }, - [KS_USER_MSGQUEUE_DELETE] = { KsDeleteMsgQueue, 1 }, - [KS_USER_MSGQUEUE_SENDWAIT] = { KsMsgQueueSendwait, 4 }, - [KS_USER_MSGQUEUE_SEND] = { KsMsgQueueSend, 3 }, - [KS_USER_MSGQUEUE_URGENTSEND] = { KsMsgQueueUrgentSend, 3 }, - [KS_USER_MSGQUEUE_RECV] = { KsMsgQueueRecv, 4 }, - [KS_USER_MSGQUEUE_REINIT] = { KsMsgQueueReinit, 1 }, + /*************** Msg queue ************/ + [KS_USER_MSGQUEUE_CREATE] = { KsCreateMsgQueue, 2 }, + [KS_USER_MSGQUEUE_DELETE] = { KsDeleteMsgQueue, 1 }, + [KS_USER_MSGQUEUE_SENDWAIT] = { KsMsgQueueSendwait, 4 }, + [KS_USER_MSGQUEUE_SEND] = { KsMsgQueueSend, 3 }, + [KS_USER_MSGQUEUE_URGENTSEND] = { KsMsgQueueUrgentSend, 3 }, + [KS_USER_MSGQUEUE_RECV] = { KsMsgQueueRecv, 4 }, + [KS_USER_MSGQUEUE_REINIT] = { KsMsgQueueReinit, 1 }, +#endif +#ifdef KERNEL_SOFTTIMER + /*************** Soft Timer ************/ + [KS_USER_TIMER_CREATE] = { KsTimerCreate, 5 }, + [KS_USER_TIMER_DELETE] = { KsTimerDelete, 1 }, + [KS_USER_TIMER_STARTRUN] = { KsTimerStartRun, 1 }, + [KS_USER_TIMER_QUITRUN] = { KsTimerQuitRun, 1 }, + [KS_USER_TIMER_MODIFY] = { KsTimerModify, 2 }, #endif #ifdef FS_VFS - /*************** fs poxix ************/ - [KS_USER_OPEN] = { KsOpen , 3 }, - [KS_USER_READ] = { KsRead , 3 }, - [KS_USER_WRITE] = { KsWrite , 3 }, - [KS_USER_CLOSE] = { KsClose , 1 }, - [KS_USER_IOCTL] = { KsIoctl , 3 }, - [KS_USER_LSEEK] = { KsLseek , 3 }, - [KS_USER_RENAME] = { KsRename , 2 }, - [KS_USER_UNLINK] = { KsUnlink , 1 }, - [KS_USER_STAT] = { KsStat , 2 }, - [KS_USER_FS_STAT] = { KsFstat , 2 }, - [KS_USER_FS_SYNC] = { KsFsync , 1 }, - [KS_USER_FTRUNCATE] = { KsFtruncate , 2 }, - [KS_USER_MKDIR] = { KsMkdir , 2 }, - [KS_USER_OPENDIR] = { KsOpendir , 1 }, - [KS_USER_CLOSEDIR] = { KsClosedir , 1 }, - [KS_USER_READDIR] = { KsReaddir , 1 }, - [KS_USER_RMDIR] = { KsRmdir , 1 }, - [KS_USER_CHDIR] = { KsChdir , 1 }, - [KS_USER_GETCWD] = { KsGetcwd, 2 }, - [KS_USER_TELLDIR] = { KsTelldir, 1 }, - [KS_USER_SEEKDIR] = { KsSeekdir, 2 }, - [KS_USER_REWIND_DIR] = { KsRewinddir, 1 }, - [KS_USER_STAT_FS] = { KsStatfs, 2 }, + /*************** fs poxix ************/ + [KS_USER_OPEN] = { KsOpen , 3 }, + [KS_USER_READ] = { KsRead , 3 }, + [KS_USER_WRITE] = { KsWrite , 3 }, + [KS_USER_CLOSE] = { KsClose , 1 }, + [KS_USER_IOCTL] = { KsIoctl , 3 }, + [KS_USER_LSEEK] = { KsLseek , 3 }, + [KS_USER_RENAME] = { KsRename , 2 }, + [KS_USER_UNLINK] = { KsUnlink , 1 }, + [KS_USER_STAT] = { KsStat , 2 }, + [KS_USER_FS_STAT] = { KsFstat , 2 }, + [KS_USER_FS_SYNC] = { KsFsync , 1 }, + [KS_USER_FTRUNCATE] = { KsFtruncate , 2 }, + [KS_USER_MKDIR] = { KsMkdir , 2 }, + [KS_USER_OPENDIR] = { KsOpendir , 1 }, + [KS_USER_CLOSEDIR] = { KsClosedir , 1 }, + [KS_USER_READDIR] = { KsReaddir , 1 }, + [KS_USER_RMDIR] = { KsRmdir , 1 }, + [KS_USER_CHDIR] = { KsChdir , 1 }, + [KS_USER_GETCWD] = { KsGetcwd, 2 }, + [KS_USER_TELLDIR] = { KsTelldir, 1 }, + [KS_USER_SEEKDIR] = { KsSeekdir, 2 }, + [KS_USER_REWIND_DIR] = { KsRewinddir, 1 }, + [KS_USER_STAT_FS] = { KsStatfs, 2 }, #endif - [KS_USER_END ... 255] = {NONE, 0} + [KS_USER_END ... 255] = {NONE, 0} }; #else @@ -718,6 +774,53 @@ uint8_t UserGetTaskPriority(int32_t id) return (uintptr_t)task->task_dync_sched_member.cur_prio; } +#ifdef KERNEL_SOFTTIMER +static int32 timer_sem; +static void UserTimerCallback(void *parameter) +{ + KSemaphoreAbandon(timer_sem); +} + +int32 UserTimerCreate(const char *name, void (*timeout)(void *parameter), void *parameter, uint32_t time, uint8_t trigger_mode) +{ + int32 ret; + + timer_sem = *((int *)parameter); + + ret = KCreateTimer(name, UserTimerCallback, NONE, time, trigger_mode); + return ret; +} + +x_err_t UserTimerDelete(int32_t timer_id) +{ + x_err_t ret; + ret = KDeleteTimer(timer_id); + return ret; +} + +x_err_t UserTimerStartRun(int32_t timer_id) +{ + x_err_t ret; + ret = KTimerStartRun(timer_id); + return ret; +} + +x_err_t UserTimerQuitRun(int32_t timer_id) +{ + x_err_t ret; + ret = KTimerQuitRun(timer_id); + return ret; +} + +x_err_t UserTimerModify(int32_t timer_id, uint32_t ticks) +{ + x_err_t ret; + + ret = KTimerModify(timer_id, ticks); + return ret; +} +#endif + long occupy_g_service_table __attribute__ ((section (".g_service_table"))) = 0; #endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/softtimer.c b/Ubiquitous/XiZi_IIoT/kernel/thread/softtimer.c index 244c49cf3..f08f3d1cb 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/softtimer.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/softtimer.c @@ -147,7 +147,7 @@ static struct TimerDone Done = /** * This function will create a softtimer. * - * @param name the length of the msg queue. + * @param name the name of the timer. * @param timeout the callback of the timer. * @param parameter the parameter of the callback function * @param time the timeout time