mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-05-16 11:38:11 +08:00
[time]时钟框架重构 (#7794)
This commit is contained in:
@@ -204,7 +204,7 @@ CONFIG_RT_USING_FDTLIB=y
|
||||
# CONFIG_FDT_USING_DEBUG is not set
|
||||
CONFIG_RT_USING_RTC=y
|
||||
# CONFIG_RT_USING_ALARM is not set
|
||||
# CONFIG_RT_USING_SOFT_RTC is not set
|
||||
CONFIG_RT_USING_SOFT_RTC=y
|
||||
# CONFIG_RT_USING_SDIO is not set
|
||||
# CONFIG_RT_USING_SPI is not set
|
||||
# CONFIG_RT_USING_WDT is not set
|
||||
|
||||
@@ -22,6 +22,17 @@ int mnt_init(void)
|
||||
{
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dfs_mount("virtio-blk0", "/", "ext", 0, RT_NULL) == 0)
|
||||
{
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("file system initialization fail!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <mmu.h>
|
||||
#include <gtimer.h>
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include <lwp_arch.h>
|
||||
@@ -98,6 +99,8 @@ void rt_hw_board_init(void)
|
||||
/* initialize hardware interrupt */
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
rt_hw_gtimer_init();
|
||||
|
||||
/* support debug feature before components init */
|
||||
rt_hw_uart_init();
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
|
||||
@@ -115,8 +115,8 @@ int rt_hw_rtc_init(void)
|
||||
rtc_device.device.user_data = RT_NULL;
|
||||
|
||||
/* register a rtc device */
|
||||
rt_device_register(&rtc_device.device, "rtc", RT_DEVICE_FLAG_RDWR);
|
||||
|
||||
rt_device_register(&rtc_device.device, "rtc0", RT_DEVICE_FLAG_RDWR);
|
||||
rt_soft_rtc_set_source("rtc0");
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_hw_rtc_init);
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-22 Jesven first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <stdint.h>
|
||||
#include "cp15.h"
|
||||
#include "board.h"
|
||||
#include "gtimer.h"
|
||||
|
||||
#define TIMER_IRQ 30
|
||||
|
||||
static rt_uint64_t timerStep = 0;
|
||||
|
||||
static void rt_hw_timer_isr(int vector, void *param)
|
||||
{
|
||||
rt_hw_set_gtimer_val(timerStep);
|
||||
rt_tick_increase();
|
||||
}
|
||||
|
||||
void rt_hw_timer_enable(void)
|
||||
{
|
||||
rt_hw_set_gtimer_val(timerStep);
|
||||
rt_hw_interrupt_umask(TIMER_IRQ);
|
||||
rt_hw_gtimer_enable();
|
||||
}
|
||||
|
||||
int rt_hw_timer_init(void)
|
||||
{
|
||||
rt_hw_interrupt_install(TIMER_IRQ, rt_hw_timer_isr, RT_NULL, "tick");
|
||||
__ISB();
|
||||
timerStep = rt_hw_get_gtimer_frq();
|
||||
__DSB();
|
||||
timerStep /= RT_TICK_PER_SECOND;
|
||||
rt_hw_timer_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_hw_timer_init);
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-22 Jesven first version
|
||||
*/
|
||||
|
||||
#ifndef DRV_TIMER_H__
|
||||
#define DRV_TIMER_H__
|
||||
|
||||
void timer_init(int timer, unsigned int preload);
|
||||
|
||||
#endif
|
||||
@@ -133,6 +133,7 @@
|
||||
#define RT_USING_FDT
|
||||
#define RT_USING_FDTLIB
|
||||
#define RT_USING_RTC
|
||||
#define RT_USING_SOFT_RTC
|
||||
#define RT_USING_DEV_BUS
|
||||
#define RT_USING_VIRTIO
|
||||
#define RT_USING_VIRTIO10
|
||||
|
||||
@@ -84,7 +84,7 @@ CONFIG_RT_USING_DEVICE_OPS=y
|
||||
CONFIG_RT_USING_CONSOLE=y
|
||||
CONFIG_RT_CONSOLEBUF_SIZE=256
|
||||
CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
|
||||
CONFIG_RT_VER_NUM=0x50000
|
||||
CONFIG_RT_VER_NUM=0x50001
|
||||
# CONFIG_RT_USING_STDC_ATOMIC is not set
|
||||
CONFIG_ARCH_CPU_64BIT=y
|
||||
CONFIG_RT_USING_CACHE=y
|
||||
@@ -122,10 +122,12 @@ CONFIG_FINSH_ARG_MAX=10
|
||||
CONFIG_RT_USING_DFS=y
|
||||
CONFIG_DFS_USING_POSIX=y
|
||||
CONFIG_DFS_USING_WORKDIR=y
|
||||
# CONFIG_RT_USING_DFS_MNTTABLE is not set
|
||||
CONFIG_DFS_FD_MAX=32
|
||||
CONFIG_RT_USING_DFS_V1=y
|
||||
# CONFIG_RT_USING_DFS_V2 is not set
|
||||
CONFIG_DFS_FILESYSTEMS_MAX=4
|
||||
CONFIG_DFS_FILESYSTEM_TYPES_MAX=4
|
||||
CONFIG_DFS_FD_MAX=32
|
||||
# CONFIG_RT_USING_DFS_MNTTABLE is not set
|
||||
CONFIG_RT_USING_DFS_ELMFAT=y
|
||||
|
||||
#
|
||||
@@ -174,7 +176,7 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64
|
||||
# CONFIG_RT_USING_HWTIMER is not set
|
||||
CONFIG_RT_USING_CPUTIME=y
|
||||
CONFIG_RT_USING_CPUTIME_RISCV=y
|
||||
CONFIG_CPUTIME_TIMER_FREQ=300000000
|
||||
CONFIG_CPUTIME_TIMER_FREQ=10000000
|
||||
# CONFIG_RT_USING_I2C is not set
|
||||
# CONFIG_RT_USING_PHY is not set
|
||||
CONFIG_RT_USING_PIN=y
|
||||
@@ -190,7 +192,7 @@ CONFIG_RT_USING_RANDOM=y
|
||||
# CONFIG_RT_USING_FDT is not set
|
||||
CONFIG_RT_USING_RTC=y
|
||||
# CONFIG_RT_USING_ALARM is not set
|
||||
# CONFIG_RT_USING_SOFT_RTC is not set
|
||||
CONFIG_RT_USING_SOFT_RTC=y
|
||||
# CONFIG_RT_USING_SDIO is not set
|
||||
# CONFIG_RT_USING_SPI is not set
|
||||
# CONFIG_RT_USING_WDT is not set
|
||||
|
||||
@@ -19,9 +19,20 @@ int mnt_init(void)
|
||||
if (rt_device_find("virtio-blk0"))
|
||||
{
|
||||
/* mount virtio-blk as root directory */
|
||||
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) != 0)
|
||||
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
|
||||
{
|
||||
LOG_E("virtio-blk0 mount failed\n");
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dfs_mount("virtio-blk0", "/", "ext", 0, RT_NULL) == 0)
|
||||
{
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("file system initialization fail!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
#define RT_USING_CONSOLE
|
||||
#define RT_CONSOLEBUF_SIZE 256
|
||||
#define RT_CONSOLE_DEVICE_NAME "uart0"
|
||||
#define RT_VER_NUM 0x50000
|
||||
#define RT_VER_NUM 0x50001
|
||||
#define ARCH_CPU_64BIT
|
||||
#define RT_USING_CACHE
|
||||
#define RT_USING_HW_ATOMIC
|
||||
@@ -83,9 +83,10 @@
|
||||
#define RT_USING_DFS
|
||||
#define DFS_USING_POSIX
|
||||
#define DFS_USING_WORKDIR
|
||||
#define DFS_FD_MAX 32
|
||||
#define RT_USING_DFS_V1
|
||||
#define DFS_FILESYSTEMS_MAX 4
|
||||
#define DFS_FILESYSTEM_TYPES_MAX 4
|
||||
#define DFS_FD_MAX 32
|
||||
#define RT_USING_DFS_ELMFAT
|
||||
|
||||
/* elm-chan's FatFs, Generic FAT Filesystem Module */
|
||||
@@ -117,12 +118,13 @@
|
||||
#define RT_SERIAL_RB_BUFSZ 64
|
||||
#define RT_USING_CPUTIME
|
||||
#define RT_USING_CPUTIME_RISCV
|
||||
#define CPUTIME_TIMER_FREQ 300000000
|
||||
#define CPUTIME_TIMER_FREQ 10000000
|
||||
#define RT_USING_PIN
|
||||
#define RT_USING_NULL
|
||||
#define RT_USING_ZERO
|
||||
#define RT_USING_RANDOM
|
||||
#define RT_USING_RTC
|
||||
#define RT_USING_SOFT_RTC
|
||||
#define RT_USING_VIRTIO
|
||||
#define RT_USING_VIRTIO10
|
||||
#define RT_USING_VIRTIO_BLK
|
||||
|
||||
@@ -27,6 +27,9 @@ extern "C" {
|
||||
#define RT_DEVICE_CTRL_RTC_SET_TIMEVAL (RT_DEVICE_CTRL_BASE(RTC) + 0x04) /**< set timeval for gettimeofday */
|
||||
#define RT_DEVICE_CTRL_RTC_GET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x05) /**< get alarm */
|
||||
#define RT_DEVICE_CTRL_RTC_SET_ALARM (RT_DEVICE_CTRL_BASE(RTC) + 0x06) /**< set alarm */
|
||||
#define RT_DEVICE_CTRL_RTC_GET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x07) /**< get timespec for clock_gettime */
|
||||
#define RT_DEVICE_CTRL_RTC_SET_TIMESPEC (RT_DEVICE_CTRL_BASE(RTC) + 0x08) /**< set timespec for clock_settime */
|
||||
#define RT_DEVICE_CTRL_RTC_GET_TIMERES (RT_DEVICE_CTRL_BASE(RTC) + 0x09) /**< get resolution for clock_getres */
|
||||
|
||||
/* used for alarm function */
|
||||
struct rt_rtc_wkalarm
|
||||
@@ -64,6 +67,11 @@ rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second);
|
||||
rt_err_t set_timestamp(time_t timestamp);
|
||||
rt_err_t get_timestamp(time_t *timestamp);
|
||||
|
||||
#ifdef RT_USING_SYSTEM_WORKQUEUE
|
||||
rt_err_t rt_soft_rtc_sync();
|
||||
rt_err_t rt_soft_rtc_set_source(const char *name);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include <ktime.h>
|
||||
|
||||
#ifdef RT_USING_SOFT_RTC
|
||||
|
||||
/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50) */
|
||||
@@ -23,9 +25,21 @@
|
||||
#define SOFT_RTC_TIME_DEFAULT RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0)
|
||||
#endif
|
||||
|
||||
#ifndef RTC_AUTO_SYNC_FIRST_DELAY
|
||||
#define RTC_AUTO_SYNC_FIRST_DELAY 25
|
||||
#endif
|
||||
#ifndef RTC_AUTO_SYNC_PERIOD
|
||||
#define RTC_AUTO_SYNC_PERIOD 3600
|
||||
#endif
|
||||
|
||||
static struct rt_work rtc_sync_work;
|
||||
static rt_device_t source_device = RT_NULL;
|
||||
|
||||
static struct rt_device soft_rtc_dev;
|
||||
static rt_tick_t init_tick;
|
||||
static time_t init_time;
|
||||
static struct timeval init_tv = {0};
|
||||
static struct timespec init_ts = {0};
|
||||
|
||||
#ifdef RT_USING_ALARM
|
||||
|
||||
@@ -55,9 +69,33 @@ static void soft_rtc_alarm_update(struct rt_rtc_wkalarm *palarm)
|
||||
|
||||
#endif
|
||||
|
||||
static void set_rtc_time(time_t t)
|
||||
{
|
||||
init_time = t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
|
||||
#ifdef RT_USING_ALARM
|
||||
soft_rtc_alarm_update(&wkalarm);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _source_device_control(int cmd, void *args)
|
||||
{
|
||||
if (source_device == RT_NULL)
|
||||
return;
|
||||
|
||||
if (rt_device_open(source_device, 0) == RT_EOK)
|
||||
{
|
||||
rt_device_control(source_device, cmd, args);
|
||||
rt_device_close(source_device);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
|
||||
{
|
||||
time_t *t;
|
||||
struct timeval *tv;
|
||||
struct timespec *ts;
|
||||
struct timeval _tv;
|
||||
struct timespec _ts;
|
||||
struct tm time_temp;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
@@ -72,10 +110,8 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
|
||||
case RT_DEVICE_CTRL_RTC_SET_TIME:
|
||||
{
|
||||
t = (time_t *) args;
|
||||
init_time = *t - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
|
||||
#ifdef RT_USING_ALARM
|
||||
soft_rtc_alarm_update(&wkalarm);
|
||||
#endif
|
||||
set_rtc_time(*t);
|
||||
_source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, t);
|
||||
break;
|
||||
}
|
||||
#ifdef RT_USING_ALARM
|
||||
@@ -87,6 +123,37 @@ static rt_err_t soft_rtc_control(rt_device_t dev, int cmd, void *args)
|
||||
soft_rtc_alarm_update(&wkalarm);
|
||||
break;
|
||||
#endif
|
||||
case RT_DEVICE_CTRL_RTC_GET_TIMEVAL:
|
||||
tv = (struct timeval *)args;
|
||||
rt_ktime_boottime_get_us(&_tv);
|
||||
tv->tv_sec = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
|
||||
tv->tv_usec = init_tv.tv_usec + _tv.tv_usec;
|
||||
break;
|
||||
case RT_DEVICE_CTRL_RTC_SET_TIMEVAL:
|
||||
tv = (struct timeval *)args;
|
||||
rt_ktime_boottime_get_us(&_tv);
|
||||
set_rtc_time(tv->tv_sec);
|
||||
init_tv.tv_usec = tv->tv_usec - _tv.tv_usec;
|
||||
_source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, &(tv->tv_sec));
|
||||
break;
|
||||
case RT_DEVICE_CTRL_RTC_GET_TIMESPEC:
|
||||
ts = (struct timespec *)args;
|
||||
rt_ktime_boottime_get_ns(&_ts);
|
||||
ts->tv_sec = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
|
||||
ts->tv_nsec = init_ts.tv_nsec + _ts.tv_nsec;
|
||||
break;
|
||||
case RT_DEVICE_CTRL_RTC_SET_TIMESPEC:
|
||||
ts = (struct timespec *)args;
|
||||
rt_ktime_boottime_get_ns(&_ts);
|
||||
set_rtc_time(ts->tv_sec);
|
||||
init_ts.tv_nsec = ts->tv_nsec - _ts.tv_nsec;
|
||||
_source_device_control(RT_DEVICE_CTRL_RTC_SET_TIME, &(ts->tv_sec));
|
||||
break;
|
||||
case RT_DEVICE_CTRL_RTC_GET_TIMERES:
|
||||
ts = (struct timespec *)args;
|
||||
ts->tv_sec = 0;
|
||||
ts->tv_nsec = (rt_ktime_cputimer_getres() / RT_KTIME_RESMUL);
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
@@ -153,4 +220,60 @@ static int rt_soft_rtc_init(void)
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_soft_rtc_init);
|
||||
|
||||
#ifdef RT_USING_SYSTEM_WORKQUEUE
|
||||
|
||||
rt_err_t rt_soft_rtc_sync()
|
||||
{
|
||||
time_t time = 0;
|
||||
|
||||
if (source_device == RT_NULL)
|
||||
{
|
||||
rt_kprintf("error: rtc source not found, please set it!!!\n");
|
||||
return RT_ENOSYS;
|
||||
}
|
||||
|
||||
_source_device_control(RT_DEVICE_CTRL_RTC_GET_TIME, &time);
|
||||
set_rtc_time(time);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static void rtc_sync_work_func(struct rt_work *work, void *work_data)
|
||||
{
|
||||
rt_soft_rtc_sync();
|
||||
rt_work_submit(work, rt_tick_from_millisecond(RTC_AUTO_SYNC_PERIOD * 1000));
|
||||
}
|
||||
|
||||
rt_err_t rt_soft_rtc_set_source(const char *name)
|
||||
{
|
||||
RT_ASSERT(name != RT_NULL);
|
||||
RT_ASSERT(rt_device_find(name)); // make sure source is exist
|
||||
|
||||
source_device = rt_device_find(name);
|
||||
rt_work_init(&rtc_sync_work, rtc_sync_work_func, RT_NULL);
|
||||
rt_work_submit(&rtc_sync_work, rt_tick_from_millisecond(RTC_AUTO_SYNC_FIRST_DELAY * 1000));
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
#ifdef FINSH_USING_MSH
|
||||
#include <finsh.h>
|
||||
static void cmd_rtc_sync(int argc, char **argv)
|
||||
{
|
||||
struct timeval tv = {0};
|
||||
struct timezone tz = {0};
|
||||
time_t now = (time_t)0;
|
||||
|
||||
rt_soft_rtc_sync();
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
now = tv.tv_sec;
|
||||
/* output current time */
|
||||
rt_kprintf("local time: %.*s", 25, ctime(&now));
|
||||
rt_kprintf("timestamps: %ld\n", (long)tv.tv_sec);
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(cmd_rtc_sync, rtc_sync, Update time by real rtc);
|
||||
#endif
|
||||
|
||||
#endif /* RT_USING_SYSTEM_WORKQUEUE */
|
||||
|
||||
#endif /* RT_USING_SOFT_RTC */
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import os
|
||||
from building import *
|
||||
|
||||
Import('rtconfig')
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
|
||||
src = Glob('src/*.c')
|
||||
list = os.listdir(cwd + "/src")
|
||||
if rtconfig.ARCH in list:
|
||||
if os.path.exists(cwd + "/src/" + rtconfig.ARCH + "/" + rtconfig.CPU):
|
||||
src += Glob("src/" + rtconfig.ARCH + "/" + rtconfig.CPU + "/*.c")
|
||||
else:
|
||||
src += Glob("src/" + rtconfig.ARCH + "/*.c")
|
||||
CPPPATH = [cwd, cwd + "/inc"]
|
||||
|
||||
group = DefineGroup('ktime', src, depend=[''], CPPPATH=CPPPATH)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#ifndef __KTIME_H__
|
||||
#define __KTIME_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "rtthread.h"
|
||||
|
||||
#define RT_KTIME_RESMUL (1000000UL)
|
||||
|
||||
struct rt_ktime_hrtimer
|
||||
{
|
||||
struct rt_object parent; /**< inherit from rt_object */
|
||||
rt_list_t row;
|
||||
void *parameter;
|
||||
unsigned long init_cnt;
|
||||
unsigned long timeout_cnt;
|
||||
struct rt_semaphore sem;
|
||||
void (*timeout_func)(void *parameter);
|
||||
};
|
||||
typedef struct rt_ktime_hrtimer *rt_ktime_hrtimer_t;
|
||||
|
||||
/**
|
||||
* @brief Get boottime with us precision
|
||||
*
|
||||
* @param tv: timeval
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_boottime_get_us(struct timeval *tv);
|
||||
|
||||
/**
|
||||
* @brief Get boottime with s precision
|
||||
*
|
||||
* @param t: time_t
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_boottime_get_s(time_t *t);
|
||||
|
||||
/**
|
||||
* @brief Get boottime with ns precision
|
||||
*
|
||||
* @param ts: timespec
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts);
|
||||
|
||||
/**
|
||||
* @brief Get cputimer resolution
|
||||
*
|
||||
* @return (resolution * RT_KTIME_RESMUL)
|
||||
*/
|
||||
unsigned long rt_ktime_cputimer_getres(void);
|
||||
|
||||
/**
|
||||
* @brief Get cputimer frequency
|
||||
*
|
||||
* @return frequency
|
||||
*/
|
||||
unsigned long rt_ktime_cputimer_getfrq(void);
|
||||
|
||||
/**
|
||||
* @brief Get cputimer the value of the cnt counter
|
||||
*
|
||||
* @return cnt
|
||||
*/
|
||||
unsigned long rt_ktime_cputimer_getcnt(void);
|
||||
|
||||
/**
|
||||
* @brief Get cputimer the cnt value corresponding to 1 os tick
|
||||
*
|
||||
* @return step
|
||||
*/
|
||||
unsigned long rt_ktime_cputimer_getstep(void);
|
||||
|
||||
/**
|
||||
* @brief Get hrtimer resolution
|
||||
*
|
||||
* @return (resolution * RT_KTIME_RESMUL)
|
||||
*/
|
||||
unsigned long rt_ktime_hrtimer_getres(void);
|
||||
|
||||
/**
|
||||
* @brief Get hrtimer frequency
|
||||
*
|
||||
* @return frequency
|
||||
*/
|
||||
unsigned long rt_ktime_hrtimer_getfrq(void);
|
||||
|
||||
/**
|
||||
* @brief Get hrtimer the value of the cnt counter
|
||||
*
|
||||
* @return cnt
|
||||
*/
|
||||
unsigned long rt_ktime_hrtimer_getcnt(void);
|
||||
|
||||
/**
|
||||
* @brief set hrtimer timeout, when timeout, the timer callback will call timeout
|
||||
*
|
||||
* @param cnt: hrtimer requires a timing cnt value
|
||||
* @param timeout: timeout callback
|
||||
* @param param: parameter
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)(void *param), void *param);
|
||||
|
||||
void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
|
||||
const char *name,
|
||||
unsigned long cnt,
|
||||
rt_uint8_t flag,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter);
|
||||
rt_err_t rt_ktime_hrtimer_delete(rt_ktime_hrtimer_t timer);
|
||||
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer);
|
||||
rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer);
|
||||
rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg);
|
||||
rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer);
|
||||
|
||||
/**
|
||||
* @brief sleep by the cputimer cnt value
|
||||
*
|
||||
* @param cnt: the cputimer cnt value
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt);
|
||||
|
||||
/**
|
||||
* @brief sleep by ns
|
||||
*
|
||||
* @param ns: ns
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns);
|
||||
|
||||
/**
|
||||
* @brief sleep by us
|
||||
*
|
||||
* @param us: us
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_hrtimer_udelay(unsigned long us);
|
||||
|
||||
/**
|
||||
* @brief sleep by ms
|
||||
*
|
||||
* @param ms: ms
|
||||
* @return rt_err_t
|
||||
*/
|
||||
rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#include "gtimer.h"
|
||||
#include "ktime.h"
|
||||
|
||||
unsigned long rt_ktime_cputimer_getres(void)
|
||||
{
|
||||
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / rt_hw_get_gtimer_frq();
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getfrq(void)
|
||||
{
|
||||
return rt_hw_get_gtimer_frq();
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getcnt(void)
|
||||
{
|
||||
return rt_hw_get_cntpct_val();
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getstep(void)
|
||||
{
|
||||
return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#include "ktime.h"
|
||||
|
||||
#define __KTIME_MUL ((1000UL * 1000 * 1000) / RT_TICK_PER_SECOND)
|
||||
|
||||
rt_err_t rt_ktime_boottime_get_us(struct timeval *tv)
|
||||
{
|
||||
RT_ASSERT(tv != RT_NULL);
|
||||
|
||||
rt_tick_t ms = rt_tick_get();
|
||||
unsigned long ns =
|
||||
((rt_ktime_cputimer_getcnt() % rt_ktime_cputimer_getstep()) * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
|
||||
ns = ((ms % RT_TICK_PER_SECOND) * __KTIME_MUL) + ns;
|
||||
|
||||
tv->tv_sec = ms / RT_TICK_PER_SECOND;
|
||||
tv->tv_usec = ns / 1000;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_boottime_get_s(time_t *t)
|
||||
{
|
||||
RT_ASSERT(t != RT_NULL);
|
||||
|
||||
*t = rt_tick_get() / RT_TICK_PER_SECOND;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_boottime_get_ns(struct timespec *ts)
|
||||
{
|
||||
RT_ASSERT(ts != RT_NULL);
|
||||
|
||||
rt_tick_t ms = rt_tick_get();
|
||||
unsigned long ns =
|
||||
((rt_ktime_cputimer_getcnt() % rt_ktime_cputimer_getstep()) * rt_ktime_cputimer_getres()) / RT_KTIME_RESMUL;
|
||||
|
||||
ts->tv_sec = ms / RT_TICK_PER_SECOND;
|
||||
ts->tv_nsec = ((ms % RT_TICK_PER_SECOND) * __KTIME_MUL) + ns;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#include "ktime.h"
|
||||
|
||||
rt_weak unsigned long rt_ktime_cputimer_getres(void)
|
||||
{
|
||||
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / RT_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
rt_weak unsigned long rt_ktime_cputimer_getfrq(void)
|
||||
{
|
||||
return RT_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
rt_weak unsigned long rt_ktime_cputimer_getcnt(void)
|
||||
{
|
||||
return rt_tick_get();
|
||||
}
|
||||
|
||||
rt_weak unsigned long rt_ktime_cputimer_getstep(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#include <rtdevice.h>
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "ktime.h"
|
||||
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
#define _HRTIMER_MAX_CNT UINT64_MAX
|
||||
#else
|
||||
#define _HRTIMER_MAX_CNT UINT32_MAX
|
||||
#endif
|
||||
|
||||
static rt_list_t _timer_list = RT_LIST_OBJECT_INIT(_timer_list);
|
||||
static rt_ktime_hrtimer_t _nowtimer = RT_NULL;
|
||||
static struct rt_spinlock _spinlock;
|
||||
|
||||
rt_weak unsigned long rt_ktime_hrtimer_getres(void)
|
||||
{
|
||||
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / RT_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
rt_weak unsigned long rt_ktime_hrtimer_getfrq(void)
|
||||
{
|
||||
return RT_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
rt_weak unsigned long rt_ktime_hrtimer_getcnt(void)
|
||||
{
|
||||
return rt_tick_get();
|
||||
}
|
||||
|
||||
static void (*_outcb)(void *param) = RT_NULL;
|
||||
|
||||
static void _hrtimer_timeout(void *parameter)
|
||||
{
|
||||
if (_outcb)
|
||||
_outcb(parameter);
|
||||
}
|
||||
|
||||
rt_weak rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt, void (*timeout)(void *param), void *param)
|
||||
{
|
||||
static rt_timer_t timer = RT_NULL;
|
||||
|
||||
if (timer == RT_NULL)
|
||||
{
|
||||
timer = rt_timer_create("shrtimer", _hrtimer_timeout, param, cnt, RT_TIMER_FLAG_ONE_SHOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_tick_t tick = cnt;
|
||||
rt_timer_control(timer, RT_TIMER_CTRL_SET_TIME, &tick);
|
||||
rt_timer_control(timer, RT_TIMER_CTRL_SET_PARM, param);
|
||||
}
|
||||
|
||||
_outcb = timeout;
|
||||
if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
|
||||
{
|
||||
rt_timer_stop(timer);
|
||||
}
|
||||
rt_timer_start(timer);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief convert cnt from cputimer cnt to hrtimer cnt
|
||||
*
|
||||
* @param cnt
|
||||
* @return unsigned long
|
||||
*/
|
||||
static unsigned long _cnt_convert(unsigned long cnt)
|
||||
{
|
||||
int64_t count = cnt - rt_ktime_cputimer_getcnt();
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
return (count * rt_ktime_cputimer_getres()) / rt_ktime_hrtimer_getres();
|
||||
}
|
||||
|
||||
static void _sleep_timeout(void *parameter)
|
||||
{
|
||||
struct rt_semaphore *sem;
|
||||
sem = (struct rt_semaphore *)parameter;
|
||||
rt_sem_release(sem);
|
||||
}
|
||||
|
||||
static void _set_next_timeout(void);
|
||||
static void _timeout_callback(void *parameter)
|
||||
{
|
||||
rt_ktime_hrtimer_t timer;
|
||||
timer = (rt_ktime_hrtimer_t)parameter;
|
||||
rt_base_t level;
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
_nowtimer = RT_NULL;
|
||||
rt_list_remove(&(timer->row));
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
|
||||
{
|
||||
timer->timeout_func(timer->parameter);
|
||||
}
|
||||
|
||||
_set_next_timeout();
|
||||
}
|
||||
|
||||
static void _set_next_timeout(void)
|
||||
{
|
||||
rt_ktime_hrtimer_t t;
|
||||
rt_base_t level;
|
||||
|
||||
if (&_timer_list != _timer_list.prev)
|
||||
{
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
t = rt_list_entry((&_timer_list)->next, struct rt_ktime_hrtimer, row);
|
||||
if (_nowtimer != RT_NULL)
|
||||
{
|
||||
if (t != _nowtimer && t->timeout_cnt < _nowtimer->timeout_cnt)
|
||||
{
|
||||
_nowtimer = t;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_ktime_hrtimer_settimeout(_cnt_convert(t->timeout_cnt), _timeout_callback, t);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_nowtimer = t;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
rt_ktime_hrtimer_settimeout(_cnt_convert(t->timeout_cnt), _timeout_callback, t);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_nowtimer = RT_NULL;
|
||||
rt_ktime_hrtimer_settimeout(RT_NULL, RT_NULL, RT_NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void rt_ktime_hrtimer_init(rt_ktime_hrtimer_t timer,
|
||||
const char *name,
|
||||
unsigned long cnt,
|
||||
rt_uint8_t flag,
|
||||
void (*timeout)(void *parameter),
|
||||
void *parameter)
|
||||
{
|
||||
/* parameter check */
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
RT_ASSERT(timeout != RT_NULL);
|
||||
RT_ASSERT(cnt < (_HRTIMER_MAX_CNT / 2));
|
||||
|
||||
/* set flag */
|
||||
timer->parent.flag = flag;
|
||||
|
||||
/* set deactivated */
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
|
||||
timer->timeout_func = timeout;
|
||||
timer->parameter = parameter;
|
||||
timer->timeout_cnt = cnt + rt_ktime_cputimer_getcnt();
|
||||
timer->init_cnt = cnt;
|
||||
|
||||
rt_list_init(&(timer->row));
|
||||
rt_sem_init(&(timer->sem), "hrtimer", 0, RT_IPC_FLAG_PRIO);
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_delete(rt_ktime_hrtimer_t timer)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_list_remove(&timer->row);
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* stop timer */
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
_set_next_timeout();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_start(rt_ktime_hrtimer_t timer)
|
||||
{
|
||||
rt_list_t *timer_list;
|
||||
rt_base_t level;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_list_remove(&timer->row); /* remove timer from list */
|
||||
/* change status of timer */
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
|
||||
timer_list = &_timer_list;
|
||||
for (; timer_list != _timer_list.prev; timer_list = timer_list->next)
|
||||
{
|
||||
rt_ktime_hrtimer_t t;
|
||||
rt_list_t *p = timer_list->next;
|
||||
|
||||
t = rt_list_entry(p, struct rt_ktime_hrtimer, row);
|
||||
|
||||
if ((t->timeout_cnt - timer->timeout_cnt) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if ((t->timeout_cnt - timer->timeout_cnt) < (_HRTIMER_MAX_CNT / 2))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
rt_list_insert_after(timer_list, &(timer->row));
|
||||
timer->parent.flag |= RT_TIMER_FLAG_ACTIVATED;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
_set_next_timeout();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_stop(rt_ktime_hrtimer_t timer)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
RT_ASSERT(timer != RT_NULL); /* timer check */
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
|
||||
{
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
return -RT_ERROR;
|
||||
}
|
||||
rt_list_remove(&timer->row);
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* change status */
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
_set_next_timeout();
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_control(rt_ktime_hrtimer_t timer, int cmd, void *arg)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_TIMER_CTRL_GET_TIME:
|
||||
*(unsigned long *)arg = timer->init_cnt;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_TIME:
|
||||
RT_ASSERT((*(unsigned long *)arg) < (_HRTIMER_MAX_CNT / 2));
|
||||
timer->init_cnt = *(unsigned long *)arg;
|
||||
timer->timeout_cnt = *(unsigned long *)arg + rt_ktime_cputimer_getcnt();
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_ONESHOT:
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_PERIODIC:
|
||||
timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_GET_STATE:
|
||||
if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
|
||||
{
|
||||
/*timer is start and run*/
|
||||
*(rt_uint32_t *)arg = RT_TIMER_FLAG_ACTIVATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*timer is stop*/
|
||||
*(rt_uint32_t *)arg = RT_TIMER_FLAG_DEACTIVATED;
|
||||
}
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_GET_REMAIN_TIME:
|
||||
*(unsigned long *)arg = timer->timeout_cnt;
|
||||
break;
|
||||
case RT_TIMER_CTRL_GET_FUNC:
|
||||
arg = (void *)timer->timeout_func;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_FUNC:
|
||||
timer->timeout_func = (void (*)(void *))arg;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_GET_PARM:
|
||||
*(void **)arg = timer->parameter;
|
||||
break;
|
||||
|
||||
case RT_TIMER_CTRL_SET_PARM:
|
||||
timer->parameter = arg;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_detach(rt_ktime_hrtimer_t timer)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
/* parameter check */
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
rt_list_remove(&timer->row);
|
||||
/* stop timer */
|
||||
timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
_set_next_timeout();
|
||||
|
||||
rt_sem_detach(&(timer->sem));
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/************************** delay ***************************/
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_sleep(unsigned long cnt)
|
||||
{
|
||||
struct rt_ktime_hrtimer timer;
|
||||
|
||||
if (cnt == 0)
|
||||
return -RT_EINVAL;
|
||||
|
||||
rt_ktime_hrtimer_init(&timer, "hrtimer_sleep", cnt, RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
|
||||
_sleep_timeout, &(timer.sem));
|
||||
|
||||
rt_ktime_hrtimer_start(&timer); /* reset the timeout of thread timer and start it */
|
||||
rt_sem_take_interruptible(&(timer.sem), RT_WAITING_FOREVER);
|
||||
|
||||
rt_ktime_hrtimer_detach(&timer);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_ndelay(unsigned long ns)
|
||||
{
|
||||
unsigned long res = rt_ktime_cputimer_getres();
|
||||
return rt_ktime_hrtimer_sleep((ns * RT_KTIME_RESMUL) / res);
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_udelay(unsigned long us)
|
||||
{
|
||||
return rt_ktime_hrtimer_ndelay(us * 1000);
|
||||
}
|
||||
|
||||
rt_err_t rt_ktime_hrtimer_mdelay(unsigned long ms)
|
||||
{
|
||||
return rt_ktime_hrtimer_ndelay(ms * 1000000);
|
||||
}
|
||||
|
||||
static int rt_ktime_hrtimer_lock_init(void)
|
||||
{
|
||||
RT_UNUSED(_spinlock);
|
||||
rt_spin_lock_init(&_spinlock);
|
||||
return 0;
|
||||
}
|
||||
INIT_BOARD_EXPORT(rt_ktime_hrtimer_lock_init);
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-10 xqyjlj The first version.
|
||||
*/
|
||||
|
||||
#include "ktime.h"
|
||||
|
||||
unsigned long rt_ktime_cputimer_getres(void)
|
||||
{
|
||||
return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / CPUTIME_TIMER_FREQ;
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getfrq(void)
|
||||
{
|
||||
return CPUTIME_TIMER_FREQ;
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getcnt(void)
|
||||
{
|
||||
unsigned long time_elapsed;
|
||||
__asm__ __volatile__("rdtime %0" : "=r"(time_elapsed));
|
||||
return time_elapsed;
|
||||
}
|
||||
|
||||
unsigned long rt_ktime_cputimer_getstep(void)
|
||||
{
|
||||
return rt_ktime_cputimer_getfrq() / RT_TICK_PER_SECOND;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -139,8 +139,12 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
#if defined(RT_USING_POSIX_CLOCK) || defined (RT_USING_POSIX_TIMER)
|
||||
/* POSIX clock and timer */
|
||||
|
||||
#ifndef CLOCK_REALTIME_COARSE
|
||||
#define CLOCK_REALTIME_COARSE 0
|
||||
#endif /* CLOCK_REALTIME_COARSE */
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 1
|
||||
#define CLOCK_REALTIME 1
|
||||
#endif /* CLOCK_REALTIME */
|
||||
|
||||
#define CLOCK_CPUTIME_ID 2
|
||||
@@ -150,13 +154,37 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
#endif /* CLOCK_PROCESS_CPUTIME_ID */
|
||||
|
||||
#ifndef CLOCK_THREAD_CPUTIME_ID
|
||||
#define CLOCK_THREAD_CPUTIME_ID CLOCK_CPUTIME_ID
|
||||
#define CLOCK_THREAD_CPUTIME_ID 3
|
||||
#endif /* CLOCK_THREAD_CPUTIME_ID */
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 4
|
||||
#endif /* CLOCK_MONOTONIC */
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW 5
|
||||
#endif /* CLOCK_MONOTONIC_RAW */
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_COARSE
|
||||
#define CLOCK_MONOTONIC_COARSE 6
|
||||
#endif /* CLOCK_MONOTONIC_COARSE */
|
||||
|
||||
#ifndef CLOCK_BOOTTIME
|
||||
#define CLOCK_BOOTTIME 7
|
||||
#endif /* CLOCK_BOOTTIME */
|
||||
|
||||
#ifndef CLOCK_REALTIME_ALARM
|
||||
#define CLOCK_REALTIME_ALARM 8
|
||||
#endif /* CLOCK_REALTIME_ALARM */
|
||||
|
||||
#ifndef CLOCK_BOOTTIME_ALARM
|
||||
#define CLOCK_BOOTTIME_ALARM 9
|
||||
#endif /* CLOCK_BOOTTIME_ALARM */
|
||||
|
||||
#ifndef CLOCK_SGI_CYCLE
|
||||
#define CLOCK_SGI_CYCLE 10 // newlib says they don't have this definition, make the compiler happy
|
||||
#endif /* CLOCK_SGI_CYCLE */
|
||||
|
||||
#ifndef TIMER_ABSTIME
|
||||
#define TIMER_ABSTIME 4
|
||||
#endif /* TIMER_ABSTIME */
|
||||
@@ -166,6 +194,11 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
|
||||
#else
|
||||
#define CLOCK_ID_MAX CLOCK_MONOTONIC
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_TAI
|
||||
#define CLOCK_TAI 11 // newlib says they don't have this definition, make the compiler happy
|
||||
#endif /* CLOCK_TAI */
|
||||
|
||||
#endif /* defined(RT_USING_POSIX_CLOCK) || defined (RT_USING_POSIX_TIMER) */
|
||||
|
||||
#ifdef RT_USING_POSIX_CLOCK
|
||||
|
||||
@@ -172,7 +172,7 @@ int sigtimedwait(const sigset_t *set, siginfo_t *info, const struct timespec *ti
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
tick = rt_timespec_to_tick(timeout);
|
||||
tick = timeout->tv_sec * RT_TICK_PER_SECOND + timeout->tv_nsec * RT_TICK_PER_SECOND / NANOSECOND_PER_SECOND;
|
||||
}
|
||||
|
||||
ret = rt_signal_wait(set, info, tick);
|
||||
|
||||
@@ -28,7 +28,6 @@ static uint64_t get_ticks()
|
||||
int tick_isr(void)
|
||||
{
|
||||
// uint64_t core_id = current_coreid();
|
||||
int tick_cycles = 40000;
|
||||
// clint->mtimecmp[core_id] += tick_cycles;
|
||||
rt_tick_increase();
|
||||
sbi_set_timer(get_ticks() + tick_cycles);
|
||||
@@ -41,14 +40,12 @@ int rt_hw_tick_init(void)
|
||||
{
|
||||
/* Read core id */
|
||||
// unsigned long core_id = current_coreid();
|
||||
unsigned long interval = 1000/RT_TICK_PER_SECOND;
|
||||
|
||||
/* Clear the Supervisor-Timer bit in SIE */
|
||||
clear_csr(sie, SIP_STIP);
|
||||
|
||||
/* calculate the tick cycles */
|
||||
// tick_cycles = interval * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
|
||||
tick_cycles = 40000;
|
||||
tick_cycles = CPUTIME_TIMER_FREQ / RT_TICK_PER_SECOND;
|
||||
/* Set timer */
|
||||
sbi_set_timer(get_ticks() + tick_cycles);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user