1.开发背景
基于 FreeRTOS 熟悉使用其他 API 接口
2.开发需求
无
3.开发环境
window10 + MDK + STM32F429 + FreeRTOS10.3.1
4.常用功能
4.1 获取系统时间
void xPortSysTickHandler( void )
{
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already
known - therefore the slightly faster vPortRaiseBASEPRI() function is used
in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
vPortRaiseBASEPRI();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
vPortClearBASEPRIFromISR();
}
BaseType_t xTaskIncrementTick( void )
{
TCB_t * pxTCB;
TickType_t xItemValue;
BaseType_t xSwitchRequired = pdFALSE;
/* Called by the portable layer each time a tick interrupt occurs.
Increments the tick then checks to see if the new tick value will cause any
tasks to be unblocked. */
traceTASK_INCREMENT_TICK( xTickCount );
if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
{
/* Minor optimisation. The tick count cannot change in this
block. */
const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1;
/* Increment the RTOS tick, switching the delayed and overflowed
delayed lists if it wraps to 0. */
xTickCount = xConstTickCount;
if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */
{
taskSWITCH_DELAYED_LISTS();
}
else
{
mtCOVERAGE_TEST_MARKER();
}
/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick
count overflows. */
#define taskSWITCH_DELAYED_LISTS() \
{ \
List_t *pxTemp; \
\
/* The delayed tasks list should be empty when the lists are switched. */ \
configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \
\
pxTemp = pxDelayedTaskList; \
pxDelayedTaskList = pxOverflowDelayedTaskList; \
pxOverflowDelayedTaskList = pxTemp; \
xNumOfOverflows++; \
prvResetNextTaskUnblockTime(); \
}
上述是部分源码,可以看出 xPortSysTickHandler 中断调用 xTaskIncrementTick,进而实现每次中断 xTickCount 递增,并且当 xConstTickCount 递增到 0 时(计数器16位或者24位)会触发xNumOfOverflows溢出计数递增。
所以可以使用 xTaskGetTickCount 获取局部变量或者使用 vTaskSetTimeOutState 获取全部计数。
TickType_t xTaskGetTickCount( void )
{
TickType_t xTicks;
/* Critical section required if running on a 16 bit processor. */
portTICK_TYPE_ENTER_CRITICAL();
{
xTicks = xTickCount;
}
portTICK_TYPE_EXIT_CRITICAL();
return xTicks;
}
void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut )
{
configASSERT( pxTimeOut );
taskENTER_CRITICAL();
{
pxTimeOut->xOverflowCount = xNumOfOverflows;
pxTimeOut->xTimeOnEntering = xTickCount;
}
taskEXIT_CRITICAL();
}