add soft timer posix support in XiZi
This commit is contained in:
parent
779444f998
commit
5e499bf975
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <transform.h>
|
||||
|
||||
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);
|
||||
|
|
@ -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***********************/
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <semaphore.h>
|
||||
#include <timer.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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 <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* 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
|
|
@ -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 <time.h>
|
||||
|
||||
#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
|
|
@ -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 <string.h>
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <xs_mutex.h>
|
||||
#include <xs_event.h>
|
||||
#include <xs_msg.h>
|
||||
#include <xs_timer.h>
|
||||
|
||||
#ifdef FS_VFS
|
||||
#include <iot-vfs_posix.h>
|
||||
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue