feat: 内核提供tick timer框架,支持多架构多平台通用化
背景:
当前Arch下tick timer的实现依赖于弱函数机制,三方适配时出错及限制较大,且tick
timer作为内核必须模块,未模块化,当前散落在tick和调度等模块中,且当前存在arch依赖
内核,内核也依赖arch的情况,为了解决上述问题,将tick timer模块化,通过提供tick
timer框架实现内核依赖Arch而Arch不依赖内核,并且可以减少对外暴漏的接口,使得三方
适配时更加明确需要实现的接口。
方案描述:
1.tick timer结构
在kernel_liteos_m/arch/include/los_timer.h,中定义结构:
typedef struct {
UINT32 freq;
INT32 irqNum;
UINT32 (*init)(HWI_PROC_FUNC tickHandler);
UINT64 (*getCycle)(UINT32 *period);
VOID (*reload)(UINT64 time);
VOID (*lock)(VOID);
VOID (*unlock)(VOID);
HWI_PROC_FUNC tickHandler;
} ArchTickTimer;
并声明对外获取tick timer的接口:
ArchTickTimer *ArchSysTickTimerGet(VOID)
define LOS_SysTickTimerGet ArchSysTickTimerGet
2.在每个架构下提供默认的tick timer操作:
STATIC ArchTickTimer g_archTickTimer = {
.freq = xxx, 必填
.irqNum = xxx, 必填
.init = xxx, 必填
.getCycle = xxx, 必填
.reload = xxx, 必填
.lock = xxx, 必填
.unlock = xxx, 必填
.tickHandler = NULL, 可选
}
并实现:ArchTickTimer *ArchSysTickTimerGet(VOID) 接口
3.内核los_tick.c中提供对外(其它模块)和公共的tick timer初始化操作函数,
如果用户不想启用系统默认的tick timer,则需要在 "内核初始化之前" 调用接口:
LOS_TickTimerRegister(const ArchTickTimer *timer, const HWI_PROC_FUNC tickHandler)
将用户自己的tick timer或中断处理函数 注册进去。
用户也可以注册自己的中断处理函数(用户不提供,默认使用系统提供的)。
BREAKING CHANGE:
原来版本中每个架构下提供的tick timer相关操作函数为弱函数:
WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler);
WEAK VOID HalSysTickReload(UINT64 nextResponseTime);
WEAK UINT64 HalGetTickCycle(UINT32 *period);
WEAK VOID HalTickLock(VOID);
WEAK VOID HalTickUnlock(VOID);
用户如果需要启用自己的tick timer需要自己实现相关接口(强属性),在 "内核初始化之前" 通过调用:
LOS_TickTimerRegister 接口替换系统默认提供的tick timer相关接口。
无论用户提供的tick timer 还是系统默认提供的,均在内核初始化时启动。
Close #I4N7XV:arch 重构
Signed-off-by: zhushengle <zhushengle@huawei.com>
Change-Id: I83ad0bdf303904f0e73f808b57b60183619fddcd
This commit is contained in:
@@ -43,7 +43,6 @@ extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
VOID SysTick_Handler(VOID);
|
||||
UINT32 HalTickStart(OS_TICK_HANDLER handler);
|
||||
|
||||
#define TIM0_GROUP0 0x3FF5F000
|
||||
#define TIM0_GROUP1 0x3FF60000
|
||||
@@ -64,6 +63,30 @@ typedef struct {
|
||||
UINT32 LOAD_TRI;
|
||||
} Systick_t;
|
||||
|
||||
STATIC INLINE UINT32 GetCcount(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
__asm__ __volatile__("rsr %0, ccount" : "=a"(intSave) :);
|
||||
return intSave;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID ResetCcount(VOID)
|
||||
{
|
||||
__asm__ __volatile__("wsr %0, ccount; rsync" : :"a"(0));
|
||||
}
|
||||
|
||||
STATIC INLINE UINT32 GetCcompare(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
__asm__ __volatile__("rsr %0, ccompare0" : "=a"(intSave) :);
|
||||
return intSave;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID SetCcompare(UINT32 newCompareVal)
|
||||
{
|
||||
__asm__ __volatile__("wsr %0, ccompare0; rsync" : : "a"(newCompareVal));
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
@@ -143,15 +143,7 @@ VOID HalStartToRun(VOID)
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 ArchStartSchedule(VOID)
|
||||
{
|
||||
UINT32 ret;
|
||||
|
||||
(VOID)LOS_IntLock();
|
||||
|
||||
ret = HalTickStart(OsTickHandler);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Tick start failed!\n");
|
||||
}
|
||||
|
||||
OsSchedStart();
|
||||
HalStartToRun();
|
||||
return LOS_OK;
|
||||
|
||||
@@ -34,75 +34,48 @@
|
||||
#include "los_tick.h"
|
||||
#include "los_arch_interrupt.h"
|
||||
#include "los_arch_timer.h"
|
||||
#include "los_context.h"
|
||||
#include "los_sched.h"
|
||||
#include "los_debug.h"
|
||||
|
||||
UINT32 GetCcount(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
__asm__ __volatile__("rsr %0, ccount" : "=a"(intSave) :);
|
||||
return intSave;
|
||||
}
|
||||
STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler);
|
||||
STATIC VOID SysTickReload(UINT64 nextResponseTime);
|
||||
STATIC UINT64 SysTickCycleGet(UINT32 *period);
|
||||
STATIC VOID SysTickLock(VOID);
|
||||
STATIC VOID SysTickUnlock(VOID);
|
||||
|
||||
VOID ResetCcount(VOID)
|
||||
{
|
||||
__asm__ __volatile__("wsr %0, ccount; rsync" : :"a"(0));
|
||||
}
|
||||
STATIC ArchTickTimer g_archTickTimer = {
|
||||
.freq = OS_SYS_CLOCK,
|
||||
.irqNum = OS_TICK_INT_NUM,
|
||||
.init = SysTickStart,
|
||||
.getCycle = SysTickCycleGet,
|
||||
.reload = SysTickReload,
|
||||
.lock = SysTickLock,
|
||||
.unlock = SysTickUnlock,
|
||||
.tickHandler = NULL,
|
||||
};
|
||||
|
||||
UINT32 GetCcompare(VOID)
|
||||
STATIC UINT32 SysTickStart(HWI_PROC_FUNC handler)
|
||||
{
|
||||
UINT32 intSave;
|
||||
__asm__ __volatile__("rsr %0, ccompare0" : "=a"(intSave) :);
|
||||
return intSave;
|
||||
}
|
||||
|
||||
VOID SetCcompare(UINT32 newCompareVal)
|
||||
{
|
||||
__asm__ __volatile__("wsr %0, ccompare0; rsync" : : "a"(newCompareVal));
|
||||
}
|
||||
|
||||
/* ****************************************************************************
|
||||
Function : HalTickStart
|
||||
Description : Configure Tick Interrupt Start
|
||||
Input : none
|
||||
output : none
|
||||
return : LOS_OK - Success , or LOS_ERRNO_TICK_CFG_INVALID - failed
|
||||
**************************************************************************** */
|
||||
WEAK UINT32 HalTickStart(OS_TICK_HANDLER handler)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 ccount;
|
||||
UINT32 nextTickCycles;
|
||||
|
||||
if ((OS_SYS_CLOCK == 0) ||
|
||||
(LOSCFG_BASE_CORE_TICK_PER_SECOND == 0) ||
|
||||
(LOSCFG_BASE_CORE_TICK_PER_SECOND > OS_SYS_CLOCK)) {
|
||||
return LOS_ERRNO_TICK_CFG_INVALID;
|
||||
}
|
||||
ArchTickTimer *tick = &g_archTickTimer;
|
||||
|
||||
#if (LOSCFG_USE_SYSTEM_DEFINED_INTERRUPT == 1)
|
||||
#if (LOSCFG_PLATFORM_HWI_WITH_ARG == 1)
|
||||
OsSetVector(OS_TICK_INT_NUM, (HWI_PROC_FUNC)handler, NULL);
|
||||
OsSetVector(tick->irqNum, handler, NULL);
|
||||
#else
|
||||
OsSetVector(OS_TICK_INT_NUM, (HWI_PROC_FUNC)handler);
|
||||
OsSetVector(tick->irqNum, handler);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
g_sysClock = OS_SYS_CLOCK;
|
||||
g_cyclesPerTick = OS_SYS_CLOCK / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
|
||||
ResetCcount();
|
||||
SetCcompare(LOSCFG_BASE_CORE_TICK_RESPONSE_MAX);
|
||||
|
||||
__asm__ __volatile__("wsr %0, ccompare1; rsync" : : "a"(0));
|
||||
__asm__ __volatile__("wsr %0, ccompare2; rsync" : : "a"(0));
|
||||
|
||||
HalIrqUnmask(OS_TICK_INT_NUM);
|
||||
HalIrqUnmask(tick->irqNum);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
WEAK VOID ArchSysTickReload(UINT64 nextResponseTime)
|
||||
STATIC VOID SysTickReload(UINT64 nextResponseTime)
|
||||
{
|
||||
UINT32 timerL;
|
||||
timerL = GetCcount();
|
||||
@@ -110,7 +83,7 @@ WEAK VOID ArchSysTickReload(UINT64 nextResponseTime)
|
||||
SetCcompare(timerL);
|
||||
}
|
||||
|
||||
WEAK UINT64 ArchGetTickCycle(UINT32 *period)
|
||||
STATIC UINT64 SysTickCycleGet(UINT32 *period)
|
||||
{
|
||||
UINT32 tickCycleH;
|
||||
UINT32 tickCycleL;
|
||||
@@ -132,16 +105,21 @@ WEAK UINT64 ArchGetTickCycle(UINT32 *period)
|
||||
return tickCycle;
|
||||
}
|
||||
|
||||
WEAK VOID ArchTickLock(VOID)
|
||||
STATIC VOID SysTickLock(VOID)
|
||||
{
|
||||
HalIrqMask(OS_TICK_INT_NUM);
|
||||
}
|
||||
|
||||
WEAK VOID ArchTickUnlock(VOID)
|
||||
STATIC VOID SysTickUnlock(VOID)
|
||||
{
|
||||
HalIrqUnmask(OS_TICK_INT_NUM);
|
||||
}
|
||||
|
||||
ArchTickTimer *ArchSysTickTimerGet(VOID)
|
||||
{
|
||||
return &g_archTickTimer;
|
||||
}
|
||||
|
||||
VOID Wfi(VOID)
|
||||
{
|
||||
__asm__ volatile("waiti 0" : : : "memory");
|
||||
|
||||
Reference in New Issue
Block a user