#include <stddef.h> #include "Sys_Scheduler_Lib.h" typedef struct { uint32_t u32msRocBak; uint32_t u32Task2msCnt; uint32_t u32Task5msCnt; uint32_t u32Task10msCnt; uint32_t u32Task20msCnt; uint32_t u32Task50msCnt; uint32_t u32Task100msCnt; } Sys_Scheduler_st_t; typedef struct { uint32_t u32Pending; uint32_t u32usCounter; Sys_Timer_st_t *pstList; }Sys_Timer_Ctrl_st_t; #define SYS_TIMER_MODE_IDLE (0UL) #define SYS_TIMER_MODE_RUN (1UL) #define SYS_TIMER_MODE_LOOP (2UL) uint32_t g_u32SysIntInterval = 0UL; uint32_t g_u32SysusCounter = 0UL; volatile uint32_t g_u32SysmsRollingCounter = 0UL; Sys_Scheduler_st_t g_stSysScheduler; Sys_Timer_Ctrl_st_t g_stSysTimerCtrl; uint32_t Sys_Get_ms_Rolling_Counter(void) { uint32_t u32Counter[2]; do { u32Counter[0] = g_u32SysmsRollingCounter; u32Counter[1] = g_u32SysmsRollingCounter; }while (u32Counter[0] != u32Counter[1]); return u32Counter[0]; } int32_t Sys_Get_Running_Time(Sys_Time_st_t *pstTime) { int32_t i32Result; uint32_t u32msCounter; i32Result = -1; if (pstTime != NULL) { u32msCounter = Sys_Get_ms_Rolling_Counter(); pstTime->u32Hour = u32msCounter / 3600000UL; u32msCounter = u32msCounter % 3600000UL; pstTime->u32Min = u32msCounter / 60000UL; u32msCounter = u32msCounter % 60000UL; pstTime->u32Sec = u32msCounter / 1000UL; u32msCounter = u32msCounter % 1000UL; pstTime->u32mSec = u32msCounter; i32Result = 0; } return i32Result; } int32_t Sys_Timer_Start(Sys_Timer_st_t *pHandle, uint32_t u32Interval, uint32_t u32Loop, Sys_Timer_Cb_pfn_t pfnCallBack) { int32_t i32Result; uint32_t u32Exist; Sys_Timer_st_t *pstSearch; i32Result = -1; if (pHandle != NULL) { pHandle->u32Run = SYS_TIMER_MODE_IDLE; pHandle->u32Cnt = 0UL; pHandle->u32Dst = u32Interval; pHandle->pfnCallBack = pfnCallBack; if (g_stSysTimerCtrl.pstList == NULL) { g_stSysTimerCtrl.u32Pending = 1UL; pHandle->pstNext = NULL; g_stSysTimerCtrl.pstList = pHandle; g_stSysTimerCtrl.u32Pending = 0UL; } else if (g_stSysTimerCtrl.pstList == pHandle) { /* Nothing to do */ } else { u32Exist = 0UL; pstSearch = g_stSysTimerCtrl.pstList; while((pstSearch->pstNext != NULL) && (u32Exist == 0UL)) { pstSearch = pstSearch->pstNext; if (pstSearch == pHandle) { u32Exist = 1UL; } } if (u32Exist == 0UL) { g_stSysTimerCtrl.u32Pending = 1UL; pHandle->pstNext = NULL; pstSearch->pstNext = pHandle; g_stSysTimerCtrl.u32Pending = 0UL; } } if (u32Loop) { pHandle->u32Run = SYS_TIMER_MODE_LOOP; } else { pHandle->u32Run = SYS_TIMER_MODE_RUN; } i32Result = 0; } return i32Result; } int32_t Sys_Timer_Stop(Sys_Timer_st_t *pHandle) { int32_t i32Result; Sys_Timer_st_t *pstSearch; i32Result = -1; if (pHandle != NULL) { if (g_stSysTimerCtrl.pstList == NULL) { /* Nothing to do */ } else if (g_stSysTimerCtrl.pstList == pHandle) { g_stSysTimerCtrl.u32Pending = 1UL; pHandle->u32Run = SYS_TIMER_MODE_IDLE; g_stSysTimerCtrl.pstList = pHandle->pstNext; g_stSysTimerCtrl.u32Pending = 0UL; i32Result = 0; } else { pstSearch = g_stSysTimerCtrl.pstList; while ((pstSearch->pstNext != NULL) && (pstSearch->pstNext != pHandle)) { pstSearch = pstSearch->pstNext; } if (pstSearch->pstNext == pHandle) { g_stSysTimerCtrl.u32Pending = 1UL; pHandle->u32Run = SYS_TIMER_MODE_IDLE; pstSearch->pstNext = pHandle->pstNext; g_stSysTimerCtrl.u32Pending = 0UL; i32Result = 0; } } } return i32Result; } int32_t Sys_Timer_Get_Status(Sys_Timer_st_t *pHandle) { int32_t i32Result; i32Result = -1; if (pHandle != NULL) { if (pHandle->u32Run) { i32Result = 1; } else { i32Result = 0; } } return i32Result; } int32_t Sys_Timer_Get_Counter(Sys_Timer_st_t *pHandle, uint32_t *pu32Counter) { int32_t i32Result; volatile uint32_t *pu32Cnt; uint32_t u32Counter[2]; i32Result = -1; if ((pHandle != NULL) && (pu32Counter != NULL)) { pu32Cnt = (volatile uint32_t *)(&pHandle->u32Cnt); do { u32Counter[0] = *pu32Cnt; u32Counter[1] = *pu32Cnt; } while (u32Counter[0] != u32Counter[1]); *pu32Counter = u32Counter[0]; i32Result = 0; } return i32Result; } void Sys_Scheduler_Start(uint32_t u32SchCycle) { g_u32SysIntInterval = u32SchCycle; g_u32SysusCounter = 0UL; g_u32SysmsRollingCounter = 0UL; g_stSysTimerCtrl.u32Pending = 0UL; g_stSysTimerCtrl.u32usCounter = 0UL; g_stSysTimerCtrl.pstList = NULL; g_stSysScheduler.u32msRocBak = Sys_Get_ms_Rolling_Counter(); g_stSysScheduler.u32Task2msCnt = 0UL; g_stSysScheduler.u32Task5msCnt = 0UL; g_stSysScheduler.u32Task10msCnt = 1UL; g_stSysScheduler.u32Task20msCnt = 3UL; g_stSysScheduler.u32Task50msCnt = 5UL; g_stSysScheduler.u32Task100msCnt = 7UL; } void Sys_Scheduling_Service(void) { uint32_t u32msROC; uint32_t u32msDelta; Sys_Pseudo_Real_Time_Tasks(); u32msROC = Sys_Get_ms_Rolling_Counter(); if (u32msROC >= g_stSysScheduler.u32msRocBak) { u32msDelta = u32msROC - g_stSysScheduler.u32msRocBak; } else { u32msDelta = 0xFFFFFFFFUL - g_stSysScheduler.u32msRocBak + u32msROC + 0x00000001UL; } g_stSysScheduler.u32msRocBak = u32msROC; g_stSysScheduler.u32Task2msCnt += u32msDelta; if (g_stSysScheduler.u32Task2msCnt >= 2UL) { g_stSysScheduler.u32Task2msCnt %= 2UL; Sys_2ms_Tasks(); } g_stSysScheduler.u32Task5msCnt += u32msDelta; if (g_stSysScheduler.u32Task5msCnt >= 5UL) { g_stSysScheduler.u32Task5msCnt %= 5UL; Sys_5ms_Tasks(); } g_stSysScheduler.u32Task10msCnt += u32msDelta; if (g_stSysScheduler.u32Task10msCnt >= 10UL) { g_stSysScheduler.u32Task10msCnt %= 10UL; Sys_10ms_Tasks(); } g_stSysScheduler.u32Task20msCnt += u32msDelta; if (g_stSysScheduler.u32Task20msCnt >= 20UL) { g_stSysScheduler.u32Task20msCnt %= 20UL; Sys_20ms_Tasks(); } g_stSysScheduler.u32Task50msCnt += u32msDelta; if (g_stSysScheduler.u32Task50msCnt >= 50UL) { g_stSysScheduler.u32Task50msCnt %= 50UL; Sys_50ms_Tasks(); } g_stSysScheduler.u32Task100msCnt += u32msDelta; if (g_stSysScheduler.u32Task100msCnt >= 100UL) { g_stSysScheduler.u32Task100msCnt %= 100UL; Sys_100ms_Tasks(); } } void Sys_Scheduler_ISR(void) { uint32_t u32msInc; Sys_Timer_st_t *pstTimer; Sys_Timer_st_t *pstPrev; g_u32SysusCounter += g_u32SysIntInterval; if (g_u32SysusCounter >= 1000UL) { u32msInc = g_u32SysusCounter / 1000UL; g_u32SysusCounter = g_u32SysusCounter % 1000UL; g_u32SysmsRollingCounter += u32msInc; } g_stSysTimerCtrl.u32usCounter += g_u32SysIntInterval; if (g_stSysTimerCtrl.u32Pending == 0UL) { pstPrev = NULL; pstTimer = g_stSysTimerCtrl.pstList; while (pstTimer != NULL) { if (pstTimer->u32Run) { /* if (pstTimer->u32Cnt + u32Interval < 0xFFFFFFFFUL) */ if (pstTimer->u32Cnt < 0xFFFFFFFFUL - g_stSysTimerCtrl.u32usCounter) { pstTimer->u32Cnt += g_stSysTimerCtrl.u32usCounter; } else { pstTimer->u32Cnt = 0xFFFFFFFFUL; } if (pstTimer->u32Cnt >= pstTimer->u32Dst) { if (pstTimer->u32Run == SYS_TIMER_MODE_RUN) { pstTimer->u32Run = SYS_TIMER_MODE_IDLE; if (pstPrev == NULL) { g_stSysTimerCtrl.pstList = pstTimer->pstNext; } else { pstPrev->pstNext = pstTimer->pstNext; } } else { pstTimer->u32Cnt = 0UL; } if (pstTimer->pfnCallBack != NULL) { pstTimer->pfnCallBack(); } } } pstPrev = pstTimer; pstTimer = pstTimer->pstNext; } g_stSysTimerCtrl.u32usCounter = 0UL; } }