fix: tick 动态化计算优化,消除中断执行时间对系统总体时间的影响,保证软件定时器的响应精度。

方案描述:
    1.周期软件定时器超时添加一个startTime字段,用于记录当前软件定时器的开始计时的时间,
    在定时器响应时,开始时间修改为上一次响应的结束时间(消除了中断执行时间对软件定时器
    的影响)。
    2.在执行tick中断的过程当中,持有tick动态计算锁,保证在该过程中不会触发tick周期
    的计算,在tick中断结束时统一计算设置。 --- 提升tick中断的执行效率
    3.在设置tick周期时,减掉tick中断执行的时间,减小周期动态化带来的时间误差
    4.新增LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI配置宏,用于配置tick中断的最小响应精度
Close #I43UQJ

Signed-off-by: zhushengle <zhushengle@huawei.com>
Change-Id: Icd1159a1890046b13602b7a18dcd6234d5c61a89
This commit is contained in:
zhushengle 2021-08-06 12:48:00 +08:00
parent 9ec208a273
commit 8df3e8c965
11 changed files with 136 additions and 102 deletions

View File

@ -34,7 +34,6 @@ kernel_module(module_name) {
sources = [
"core/los_bitmap.c",
"core/los_process.c",
"core/los_sortlink.c",
"core/los_swtmr.c",
"core/los_sys.c",
"core/los_task.c",
@ -68,6 +67,7 @@ kernel_module(module_name) {
"mp/los_stat.c",
"om/los_err.c",
"sched/sched_sq/los_sched.c",
"sched/sched_sq/los_sortlink.c",
"vm/los_vm_boot.c",
"vm/los_vm_dump.c",
"vm/los_vm_fault.c",
@ -83,9 +83,7 @@ kernel_module(module_name) {
]
if (defined(LOSCFG_SHELL_CMD_DEBUG)) {
configs += [
"$HDFTOPDIR:hdf_config"
]
configs += [ "$HDFTOPDIR:hdf_config" ]
}
public_configs = [ ":public" ]

View File

@ -178,10 +178,9 @@ ERROR:
* Description: Start Software Timer
* Input : swtmr --- Need to start software timer
*/
LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
LITE_OS_SEC_TEXT VOID OsSwtmrStart(UINT64 currTime, SWTMR_CTRL_S *swtmr)
{
UINT32 ticks;
UINT64 currTime = OsGetCurrSchedTimeCycle();
if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
@ -192,10 +191,8 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
}
swtmr->ucState = OS_SWTMR_STATUS_TICKING;
OsAdd2SortLink(&swtmr->stSortList, currTime, ticks, OS_SORT_LINK_SWTMR);
if (OS_SCHEDULER_ACTIVE) {
OsSchedUpdateExpireTime(currTime);
}
OsAdd2SortLink(&swtmr->stSortList, swtmr->startTime, ticks, OS_SORT_LINK_SWTMR);
OsSchedUpdateExpireTime(currTime);
return;
}
@ -211,7 +208,7 @@ STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr)
swtmr->uwOwnerPid = 0;
}
STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, UINT64 currTime, SWTMR_CTRL_S *swtmr)
{
LOS_SpinLock(&g_swtmrSpin);
SwtmrHandlerItemPtr swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);
@ -236,7 +233,7 @@ STATIC INLINE VOID OsWakePendTimeSwtmr(Percpu *cpu, SWTMR_CTRL_S *swtmr)
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
} else {
swtmr->uwOverrun++;
OsSwtmrStart(swtmr);
OsSwtmrStart(currTime, swtmr);
}
LOS_SpinUnlock(&g_swtmrSpin);
@ -267,12 +264,12 @@ LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
UINT64 currTime = OsGetCurrSchedTimeCycle();
while (sortList->responseTime <= currTime) {
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
OsDeleteNodeSortLink(swtmrSortLink, sortList);
SWTMR_CTRL_S *swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
swtmr->startTime = GET_SORTLIST_VALUE(sortList);
OsDeleteNodeSortLink(swtmrSortLink, sortList);
LOS_SpinUnlock(&cpu->swtmrSortLinkSpin);
OsWakePendTimeSwtmr(cpu, swtmr);
OsWakePendTimeSwtmr(cpu, currTime, swtmr);
LOS_SpinLock(&cpu->swtmrSortLinkSpin);
if (LOS_ListEmpty(listObject)) {
@ -305,9 +302,7 @@ LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
swtmr->uwOverrun = 0;
if (OS_SCHEDULER_ACTIVE) {
OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
}
OsSchedUpdateExpireTime(OsGetCurrSchedTimeCycle());
}
/*
@ -403,7 +398,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsSwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
OsSwtmrStart(swtmr);
swtmr->startTime = OsGetCurrSchedTimeCycle();
OsSwtmrStart(swtmr->startTime, swtmr);
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;

View File

@ -57,6 +57,7 @@ typedef struct {
SortLinkAttribute swtmrSortLink; /* swtmr sort link */
SPIN_LOCK_S swtmrSortLinkSpin; /* swtmr sort link spin lock */
UINT64 responseTime; /* Response time for current nuclear Tick interrupts */
UINT64 tickStartTime; /* The time when the tick interrupt starts processing */
UINT32 responseID; /* The response ID of the current nuclear TICK interrupt */
UINTPTR runProcess; /* The address of the process control block pointer to which
the current kernel is running */

View File

@ -45,6 +45,10 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_SCHED_MINI_PERIOD (OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI)
#define OS_TICK_RESPONSE_PRECISION (UINT32)((OS_SCHED_MINI_PERIOD * 75) / 100)
#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(((UINT64)-1) - 1U)
extern UINT32 g_taskScheduled;
typedef BOOL (*SchedScan)(VOID);
@ -86,8 +90,9 @@ STATIC INLINE VOID OsSchedIrqStartTime(VOID)
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
typedef enum {
INT_NO_RESCH = 0, /* no needs to schedule */
INT_PEND_RESCH, /* pending schedule flag */
INT_NO_RESCH = 0x0, /* no needs to schedule */
INT_PEND_RESCH = 0x1, /* pending schedule flag */
INT_PEND_TICK = 0x2, /* pending tick */
} SchedFlag;
/* Check if preemptable with counter flag */
@ -102,7 +107,7 @@ STATIC INLINE BOOL OsPreemptable(VOID)
BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0);
if (!preemptable) {
/* Set schedule flag if preemption is disabled */
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
}
LOS_IntRestore(intSave);
return preemptable;
@ -124,7 +129,7 @@ STATIC INLINE BOOL OsPreemptableInSched(VOID)
#endif
if (!preemptable) {
/* Set schedule flag if preemption is disabled */
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
}
return preemptable;
@ -139,8 +144,8 @@ STATIC INLINE VOID OsCpuSchedUnlock(Percpu *cpu, UINT32 intSave)
{
if (cpu->taskLockCnt > 0) {
cpu->taskLockCnt--;
if ((cpu->taskLockCnt == 0) && (cpu->schedFlag == INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) {
cpu->schedFlag = INT_NO_RESCH;
if ((cpu->taskLockCnt == 0) && (cpu->schedFlag & INT_PEND_RESCH) && OS_SCHEDULER_ACTIVE) {
cpu->schedFlag &= ~INT_PEND_RESCH;
LOS_IntRestore(intSave);
LOS_Schedule();
return;

View File

@ -62,6 +62,7 @@ typedef struct {
#define OS_SORT_LINK_INVALID_TIME ((UINT64)-1)
#define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->responseTime = (value))
#define GET_SORTLIST_VALUE(sortList) (((SortLinkList *)(sortList))->responseTime)
extern UINT64 OsGetNextExpireTime(UINT64 startTime);
extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader);

View File

@ -54,6 +54,9 @@ LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = {
STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
{
UINT32 ticks = 0;
(VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks);
PRINTK("0x%08x "
"%-7s "
"%-6s "
@ -65,7 +68,7 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
g_shellSwtmrStatus[swtmr->ucState],
g_shellSwtmrMode[swtmr->ucMode],
swtmr->uwInterval,
swtmr->uwCount,
ticks,
swtmr->uwArg,
swtmr->pfnHandler);
}

View File

@ -56,7 +56,7 @@ VOID OsMpScheduleHandler(VOID)
* set schedule flag to differ from wake function,
* so that the scheduler can be triggered at the end of irq.
*/
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
}
VOID OsMpHaltHandler(VOID)

View File

@ -47,8 +47,6 @@
#include "los_stat_pri.h"
#endif
#define OS_32BIT_MAX 0xFFFFFFFFUL
#define OS_64BIT_MAX 0xFFFFFFFFFFFFFFFFULL
#define OS_SCHED_FIFO_TIMEOUT 0x7FFFFFFF
@ -59,7 +57,6 @@
#define OS_SCHED_TIME_SLICES_DIFF (OS_SCHED_TIME_SLICES_MAX - OS_SCHED_TIME_SLICES_MIN)
#define OS_SCHED_READY_MAX 30
#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
#define OS_SCHED_MAX_RESPONSE_TIME (UINT64)(OS_64BIT_MAX - 1U)
typedef struct {
LOS_DL_LIST priQueueList[OS_PRIORITY_QUEUE_NUM];
@ -120,6 +117,7 @@ UINT32 OsShellShowTickRespo(VOID)
{
UINT32 intSave;
UINT16 cpu;
UINT64 allTime;
UINT32 tickSize = sizeof(SchedTickDebug) * LOSCFG_KERNEL_CORE_NUM;
SchedTickDebug *schedDebug = (SchedTickDebug *)LOS_MemAlloc(m_aucSysMem1, tickSize);
@ -141,15 +139,18 @@ UINT32 OsShellShowTickRespo(VOID)
PRINTK("cpu : %u sched data num : %u set time count : %u SortMax : %u\n",
cpu, schedData->index, schedData->setTickCount, sortLinkNum[cpu]);
UINT32 *data = schedData->tickResporeTime;
for (UINT32 i = 0; i < schedData->index; i++) {
allTime = 0;
for (UINT32 i = 1; i < schedData->index; i++) {
allTime += data[i];
UINT32 timeUs = (data[i] * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US;
PRINTK(" %u(%u)", timeUs, timeUs / OS_US_PER_TICK);
if ((i != 0) && ((i % 5) == 0)) {
if ((i != 0) && ((i % 5) == 0)) { /* A row of 5 data */
PRINTK("\n");
}
}
PRINTK("\n");
allTime = (allTime * OS_NS_PER_CYCLE) / OS_SYS_NS_PER_US;
PRINTK("\nTick Indicates the average response period: %llu(us)\n", allTime / (schedData->index - 1));
}
(VOID)LOS_MemFree(m_aucSysMem1, schedDebug);
@ -279,41 +280,27 @@ STATIC INLINE VOID OsTimeSliceUpdate(LosTaskCB *taskCB, UINT64 currTime)
#endif
}
STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
UINT64 taskEndTime, UINT32 oldResponseID)
STATIC INLINE VOID OsSchedTickReload(Percpu *currCpu, UINT64 nextResponseTime, UINT32 responseID, BOOL isTimeSlice)
{
UINT64 nextExpireTime = OsGetNextExpireTime(startTime);
Percpu *currCpu = OsPercpuGet();
UINT64 nextResponseTime;
BOOL isTimeSlice = FALSE;
UINT64 currTime, nextExpireTime;
UINT32 usedTime;
if (currCpu->responseID == oldResponseID) {
/* This time has expired, and the next time the theory has expired is infinite */
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
}
/* The current thread's time slice has been consumed, but the current system lock task cannot
* trigger the schedule to release the CPU
*/
if (taskEndTime < nextExpireTime) {
nextExpireTime = taskEndTime;
isTimeSlice = TRUE;
}
if ((currCpu->responseTime > nextExpireTime) && ((currCpu->responseTime - nextExpireTime) >= OS_CYCLE_PER_TICK)) {
nextResponseTime = nextExpireTime - startTime;
if (nextResponseTime < OS_CYCLE_PER_TICK) {
nextResponseTime = OS_CYCLE_PER_TICK;
nextExpireTime = startTime + nextResponseTime;
if (nextExpireTime >= currCpu->responseTime) {
return;
}
} else if (nextResponseTime > g_schedTickMaxResponseTime) {
nextResponseTime = g_schedTickMaxResponseTime;
nextExpireTime = startTime + nextResponseTime;
}
currTime = OsGetCurrSchedTimeCycle();
if (currCpu->tickStartTime != 0) {
usedTime = currTime - currCpu->tickStartTime;
currCpu->tickStartTime = 0;
} else {
/* There is no point earlier than the current expiration date */
usedTime = 0;
}
if ((nextResponseTime > usedTime) && ((nextResponseTime - usedTime) > OS_TICK_RESPONSE_PRECISION)) {
nextResponseTime -= usedTime;
} else {
nextResponseTime = OS_TICK_RESPONSE_PRECISION;
}
nextExpireTime = currTime + nextResponseTime;
if (nextExpireTime >= currCpu->responseTime) {
return;
}
@ -323,7 +310,6 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
} else {
currCpu->responseID = OS_INVALID_VALUE;
}
currCpu->responseTime = nextExpireTime;
HalClockTickTimerReload(nextResponseTime);
@ -335,18 +321,61 @@ STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
#endif
}
STATIC INLINE VOID OsSchedSetNextExpireTime(UINT64 startTime, UINT32 responseID,
UINT64 taskEndTime, UINT32 oldResponseID)
{
UINT64 nextExpireTime = OsGetNextExpireTime(startTime);
Percpu *currCpu = OsPercpuGet();
UINT64 nextResponseTime;
BOOL isTimeSlice = FALSE;
currCpu->schedFlag &= ~INT_PEND_TICK;
if (currCpu->responseID == oldResponseID) {
/* This time has expired, and the next time the theory has expired is infinite */
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
}
/* The current thread's time slice has been consumed, but the current system lock task cannot
* trigger the schedule to release the CPU
*/
if ((nextExpireTime > taskEndTime) && ((nextExpireTime - taskEndTime) > OS_SCHED_MINI_PERIOD)) {
nextExpireTime = taskEndTime;
isTimeSlice = TRUE;
}
if ((currCpu->responseTime > nextExpireTime) &&
((currCpu->responseTime - nextExpireTime) >= OS_TICK_RESPONSE_PRECISION)) {
nextResponseTime = nextExpireTime - startTime;
if (nextResponseTime > g_schedTickMaxResponseTime) {
nextResponseTime = g_schedTickMaxResponseTime;
}
} else {
/* There is no point earlier than the current expiration date */
currCpu->tickStartTime = 0;
return;
}
OsSchedTickReload(currCpu, nextResponseTime, responseID, isTimeSlice);
}
VOID OsSchedUpdateExpireTime(UINT64 startTime)
{
UINT64 endTime;
Percpu *cpu = OsPercpuGet();
LosTaskCB *runTask = OsCurrTaskGet();
if (!OS_SCHEDULER_ACTIVE || OS_INT_ACTIVE) {
cpu->schedFlag |= INT_PEND_TICK;
return;
}
if (runTask->policy == LOS_SCHED_RR) {
LOS_SpinLock(&g_taskSpin);
INT32 timeSlice = (runTask->timeSlice <= OS_TIME_SLICE_MIN) ? runTask->initTimeSlice : runTask->timeSlice;
LOS_SpinUnlock(&g_taskSpin);
endTime = startTime + timeSlice;
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME;
endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
}
OsSchedSetNextExpireTime(startTime, runTask->taskID, endTime, runTask->taskID);
@ -737,20 +766,23 @@ VOID OsSchedTick(VOID)
Sched *sched = g_sched;
Percpu *currCpu = OsPercpuGet();
BOOL needSched = FALSE;
LosTaskCB *runTask = OsCurrTaskGet();
currCpu->tickStartTime = runTask->irqStartTime;
if (currCpu->responseID == OS_INVALID_VALUE) {
if (sched->swtmrScan != NULL) {
(VOID)sched->swtmrScan();
}
needSched = sched->taskScan();
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
if (needSched) {
LOS_MpSchedule(OS_MP_CPU_ALL);
currCpu->schedFlag = INT_PEND_RESCH;
currCpu->schedFlag |= INT_PEND_RESCH;
}
}
currCpu->schedFlag |= INT_PEND_TICK;
currCpu->responseTime = OS_SCHED_MAX_RESPONSE_TIME;
}
VOID OsSchedSetIdleTaskSchedParam(LosTaskCB *idleTask)
@ -996,7 +1028,7 @@ STATIC VOID OsSchedTaskSwicth(LosTaskCB *runTask, LosTaskCB *newTask)
if (newTask->policy == LOS_SCHED_RR) {
endTime = newTask->startTime + newTask->timeSlice;
} else {
endTime = OS_SCHED_MAX_RESPONSE_TIME;
endTime = OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
}
OsSchedSetNextExpireTime(newTask->startTime, newTask->taskID, endTime, runTask->taskID);
@ -1017,11 +1049,11 @@ VOID OsSchedIrqEndCheckNeedSched(VOID)
OsTimeSliceUpdate(runTask, OsGetCurrSchedTimeCycle());
if (runTask->timeSlice <= OS_TIME_SLICE_MIN) {
percpu->schedFlag = INT_PEND_RESCH;
percpu->schedFlag |= INT_PEND_RESCH;
}
if (OsPreemptable() && (percpu->schedFlag == INT_PEND_RESCH)) {
percpu->schedFlag = INT_NO_RESCH;
if (OsPreemptable() && (percpu->schedFlag & INT_PEND_RESCH)) {
percpu->schedFlag &= ~INT_PEND_RESCH;
LOS_SpinLock(&g_taskSpin);
@ -1037,7 +1069,9 @@ VOID OsSchedIrqEndCheckNeedSched(VOID)
LOS_SpinUnlock(&g_taskSpin);
}
OsSchedUpdateExpireTime(runTask->startTime);
if (percpu->schedFlag & INT_PEND_TICK) {
OsSchedUpdateExpireTime(runTask->startTime);
}
}
VOID OsSchedResched(VOID)
@ -1049,7 +1083,7 @@ VOID OsSchedResched(VOID)
LOS_ASSERT(OsPercpuGet()->taskLockCnt == 0);
#endif
OsPercpuGet()->schedFlag = INT_NO_RESCH;
OsPercpuGet()->schedFlag &= ~INT_PEND_RESCH;
LosTaskCB *runTask = OsCurrTaskGet();
LosTaskCB *newTask = OsGetTopTask();
if (runTask == newTask) {
@ -1065,7 +1099,7 @@ VOID LOS_Schedule(VOID)
LosTaskCB *runTask = OsCurrTaskGet();
if (OS_INT_ACTIVE) {
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
OsPercpuGet()->schedFlag |= INT_PEND_RESCH;
return;
}

View File

@ -36,7 +36,6 @@
#include "los_sched_pri.h"
#include "los_mp.h"
UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{
LOS_ListInit(&sortLinkHeader->sortLink);
@ -87,39 +86,19 @@ VOID OsDeleteNodeSortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortL
STATIC INLINE UINT64 OsGetSortLinkNextExpireTime(SortLinkAttribute *sortHeader, UINT64 startTime)
{
UINT64 expirTime = 0;
UINT64 nextExpirTime = 0;
LOS_DL_LIST *head = &sortHeader->sortLink;
LOS_DL_LIST *list = head->pstNext;
if (LOS_ListEmpty(head)) {
return (UINT64)-1;
return OS_SCHED_MAX_RESPONSE_TIME - OS_TICK_RESPONSE_PRECISION;
}
do {
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);
if (listSorted->responseTime <= startTime) {
expirTime = startTime;
list = list->pstNext;
} else {
nextExpirTime = listSorted->responseTime;
break;
}
} while (list != head);
if (expirTime == 0) {
return nextExpirTime;
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(list, SortLinkList, sortLinkNode);
if (listSorted->responseTime <= (startTime + OS_TICK_RESPONSE_PRECISION)) {
return startTime + OS_TICK_RESPONSE_PRECISION;
}
if (nextExpirTime == 0) {
return expirTime;
}
if ((nextExpirTime - expirTime) <= OS_US_PER_TICK) {
return nextExpirTime;
}
return expirTime;
return listSorted->responseTime;
}
STATIC Percpu *OsFindIdleCpu(UINT16 *idleCpuID)

View File

@ -276,6 +276,7 @@ typedef struct tagSwTmrCtrl {
that handles software timer timeout is called */
SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */
UINT32 uwOwnerPid; /** Owner of this software timer */
UINT64 startTime; /**< Software timer start time */
} SWTMR_CTRL_S;
/**

View File

@ -97,6 +97,22 @@ extern UINT32 __heap_end;
#define LOSCFG_BASE_CORE_TICK_PER_SECOND 1000 /* 1ms per tick */
#endif
/**
* @ingroup los_config
* Minimum response error accuracy of tick interrupts, number of ticks in one second
*/
#ifndef LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI
#define LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI 1000UL /* 1ms */
#endif
#if (LOSCFG_BASE_CORE_TICK_PER_SECOND > LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI)
#error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be greater than LOSCFG_BASE_CORE_TICK_PER_SECOND"
#endif
#if (LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI > 1000UL)
#error "LOSCFG_BASE_CORE_TICK_PER_SECOND_MINI must be less than or equal to 1000"
#endif
/**
* @ingroup los_config
* Microseconds of adjtime in one second