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:
zhushengle
2021-12-27 14:19:39 +08:00
parent 900f183260
commit f635450d7c
51 changed files with 716 additions and 585 deletions

View File

@@ -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
}

View File

@@ -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;

View File

@@ -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");