FreeRTOS 模拟SystemTime用于定时操作
1.System Time 数据结构
定义一个 结构体存放分、秒、毫秒时间
typedef struct timesdelay{
uint16_t Time_mSec;
uint32_t Time_Sec;
uint32_t Time_Min;
}OS_TimeStruct;
2.在Port.c系统时基函数内调用vRecordOSRunTime
/*******************************************************************************
* Function Name : RecordOSRunTime
* Description : 记录系统运行时间,被时基函数xPortSysTickHandler调用
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void vRecordOSRunTime( void )
{
static uint8_t ucTickTime = (1000/configTICK_RATE_HZ); //系统时间片时间,1s = 1000ms
OS_RunTime.Time_mSec += ucTickTime;
if( OS_RunTime.Time_mSec >= 1000 )
{
OS_RunTime.Time_mSec = 0;
OS_RunTime.Time_Sec++;
if( OS_RunTime.Time_Sec >= 60 )
{
OS_RunTime.Time_Sec = 0;
OS_RunTime.Time_Min++;
}
//printf( "LINE--%d: OS run times %d:%d\r\n", __LINE__, OS_RunTime.Time_Min, OS_RunTime.Time_Sec );
}
}
void xPortSysTickHandler( void )
{
vPortRaiseBASEPRI();
{
if( xTaskIncrementTick() != pdFALSE )
{
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
vRecordOSRunTime( ); //记录时间
}
vPortClearBASEPRIFromISR();
}
3.调用单次计时或多次计时
3.1 在需要使用的函数内声明结构体并初始化
static OS_TimeStruct KeyDownTime = {0};//非阻塞时间结构体
3.2 第一次使用时获取当前时间
KeyDownTime = GetOSRunTimeNow( );//按键按下后 记录当前时间
3.3 调用单次计时
/*******************************************************************************
* Function Name : SingleTimeoutCheck
* Description : 单次超时检测
* Input : *TimeStruct:需要检测的时间变量,Min、Sec、mS分别为超时时间的分、秒、毫秒
* Output : None
* Return : 超时状态
*******************************************************************************/
SystemTimeOutState SingleTimeoutCheck( OS_TimeStruct TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS )
{
OS_TimeStruct GetTime = GetOSRunTimeNow( );
uint64_t timeSor_ms = ((uint64_t)TimeStruct.Time_Min*60+TimeStruct.Time_Sec)*1000+TimeStruct.Time_mSec;
uint64_t timeGet_ms = ((uint64_t)GetTime.Time_Min*60+GetTime.Time_Sec)*1000+GetTime.Time_mSec;
uint64_t timeSet_ms = ((uint64_t)Min*60+Sec)*1000+mS;
if(timeGet_ms - timeSor_ms > timeSet_ms)
{
return TimeOut;
}
return NotTimeOut;
}
SingleTimeoutCheck( KeyDownTime, 0, 0, 20 );//计时20ms.
3.4 调用连续超时检测
/*******************************************************************************
* Function Name : MultipleTimeoutCheck
* Description : 连续超时检测
* Input : *TimeStruct:需要检测的时间变量,Min、Sec、mS分别为超时时间的分、秒、毫秒
* Output : None
* Return : 超时状态
*******************************************************************************/
SystemTimeOutState MultipleTimeoutCheck( OS_TimeStruct *TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS )
{
OS_TimeStruct GetTime = GetOSRunTimeNow( );
uint64_t timeSor_ms = ((uint64_t)TimeStruct->Time_Min*60+TimeStruct->Time_Sec)*1000+TimeStruct->Time_mSec;
uint64_t timeGet_ms = ((uint64_t)GetTime.Time_Min*60+GetTime.Time_Sec)*1000+GetTime.Time_mSec;
uint64_t timeSet_ms = ((uint64_t)Min*60+Sec)*1000+mS;
if(timeGet_ms - timeSor_ms > timeSet_ms)
{
/*updatelast*/
TimeStruct->Time_Min = GetTime.Time_Min;
TimeStruct->Time_Sec = GetTime.Time_Sec;
TimeStruct->Time_mSec = GetTime.Time_mSec;
return TimeOut;
}
return NotTimeOut;
}
MultipleTimeoutCheck(&KeyDownTime,0,0,15);//循环计时15ms
附录–SystemTime.c
#include "SystemTime.h"
OS_TimeStruct OS_RunTime = {0}; //记录系统运行时间
/*******************************************************************************
* Function Name : RecordOSRunTime
* Description : 记录系统运行时间,被时基函数xPortSysTickHandler调用
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void vRecordOSRunTime( void )
{
static uint8_t ucTickTime = (1000/configTICK_RATE_HZ); //系统时间片时间,1s = 1000ms
OS_RunTime.Time_mSec += ucTickTime;
if( OS_RunTime.Time_mSec >= 1000 )
{
OS_RunTime.Time_mSec = 0;
OS_RunTime.Time_Sec++;
if( OS_RunTime.Time_Sec >= 60 )
{
OS_RunTime.Time_Sec = 0;
OS_RunTime.Time_Min++;
}
// printf( "LINE--%d: OS run times %d:%d\r\n", __LINE__, OS_RunTime.Time_Min, OS_RunTime.Time_Sec );
}
}
/*******************************************************************************
* Function Name : GetOSRunTimeNow
* Description : 获取系统运行时间,用于一些计时操作
* Input : None
* Output : None
* Return : 系统运行时间
*******************************************************************************/
OS_TimeStruct GetOSRunTimeNow( void )
{
return OS_RunTime;
}
/*******************************************************************************
* Function Name : SingleTimeoutCheck
* Description : Get times interval by each call
* Input : None
* Output : None
* Return : Times interval(unit:ms)
*******************************************************************************/
uint32_t GetOSTimeInterval(OS_TimeStruct *LastTime)
{
uint32_t result;
OS_TimeStruct GetTime = GetOSRunTimeNow( );
//caculate interval
result = ((int32_t)GetTime.Time_mSec - LastTime->Time_mSec) + \
((int32_t)GetTime.Time_Sec - LastTime->Time_Sec)*1000 + \
((int32_t)GetTime.Time_Min - LastTime->Time_Min)*1000*60;
//update last
*LastTime = GetTime;
return result;
}
/*******************************************************************************
* Function Name : ResetSingleTimeoutCheck
* Description : To reset single time out check sturct
* Input : *TimeStruct:
* Output : TimeStruct
* Return : None
*******************************************************************************/
void ResetSingleTimeoutCheck(OS_TimeStruct *TimeStruct)
{
*TimeStruct=GetOSRunTimeNow( );
}
/*******************************************************************************
* Function Name : SingleTimeoutCheck
* Description : 单次超时检测
* Input : *TimeStruct:需要检测的时间变量,Min、Sec、mS分别为超时时间的分、秒、毫秒
* Output : None
* Return : 超时状态
*******************************************************************************/
SystemTimeOutState SingleTimeoutCheck( OS_TimeStruct TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS )
{
OS_TimeStruct GetTime = GetOSRunTimeNow( );
uint64_t timeSor_ms = ((uint64_t)TimeStruct.Time_Min*60+TimeStruct.Time_Sec)*1000+TimeStruct.Time_mSec;
uint64_t timeGet_ms = ((uint64_t)GetTime.Time_Min*60+GetTime.Time_Sec)*1000+GetTime.Time_mSec;
uint64_t timeSet_ms = ((uint64_t)Min*60+Sec)*1000+mS;
if(timeGet_ms - timeSor_ms > timeSet_ms)
{
return TimeOut;
}
return NotTimeOut;
}
/*******************************************************************************
* Function Name : MultipleTimeoutCheck
* Description : 连续超时检测
* Input : *TimeStruct:需要检测的时间变量,Min、Sec、mS分别为超时时间的分、秒、毫秒
* Output : None
* Return : 超时状态
*******************************************************************************/
SystemTimeOutState MultipleTimeoutCheck( OS_TimeStruct *TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS )
{
OS_TimeStruct GetTime = GetOSRunTimeNow( );
uint64_t timeSor_ms = ((uint64_t)TimeStruct->Time_Min*60+TimeStruct->Time_Sec)*1000+TimeStruct->Time_mSec;
uint64_t timeGet_ms = ((uint64_t)GetTime.Time_Min*60+GetTime.Time_Sec)*1000+GetTime.Time_mSec;
uint64_t timeSet_ms = ((uint64_t)Min*60+Sec)*1000+mS;
if(timeGet_ms - timeSor_ms > timeSet_ms)
{
/*updatelast*/
TimeStruct->Time_Min = GetTime.Time_Min;
TimeStruct->Time_Sec = GetTime.Time_Sec;
TimeStruct->Time_mSec = GetTime.Time_mSec;
return TimeOut;
}
return NotTimeOut;
}
附录–SystemTime.h
#include "FreeRTOS.h"
#include <stdbool.h>
typedef enum { NotTimeOut = 0, TimeOut = !NotTimeOut } SystemTimeOutState;
typedef struct timesdelay{
uint16_t Time_mSec;
uint32_t Time_Sec;
uint32_t Time_Min;
}OS_TimeStruct;
void vRecordOSRunTime( void );
static void prvClearTimeValue( OS_TimeStruct *TimeStrct );
OS_TimeStruct GetOSRunTimeNow( void );
uint32_t GetOSTimeInterval(OS_TimeStruct *LastTime);
void ResetSingleTimeoutCheck(OS_TimeStruct *TimeStruct);
SystemTimeOutState SingleTimeoutCheck( OS_TimeStruct TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS );
SystemTimeOutState MultipleTimeoutCheck( OS_TimeStruct *TimeStruct, uint32_t Min, uint32_t Sec, uint16_t mS );