修复多连接的问题
This commit is contained in:
107
App/sys_time.c
Normal file
107
App/sys_time.c
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 模块名称:System Timer
|
||||
* 模块功能:DWT CYCCNT 实现 64-bit 微秒级时间戳
|
||||
* 在 SysTick 中断中检测 CYCCNT 溢出以扩展至 64-bit
|
||||
* 适用平台:STM32F407ZGTx (168MHz)
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-07-19
|
||||
*
|
||||
* 限定条件:
|
||||
* - CPU 主频 168MHz(若更改须同步 SYS_TIME_CYCLE_PER_US 宏)
|
||||
* - 须在 FreeRTOS 启动前调用 sys_time_init()
|
||||
* - sys_time_systick_hook() 须在 SysTick 中断中调用
|
||||
*
|
||||
* 修改记录:
|
||||
* v1.0 2026-07-19 王建锋 创建初始版本
|
||||
*/
|
||||
|
||||
#include "sys_time.h"
|
||||
#include "app_cfg.h"
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
/*
|
||||
* 每微秒 CPU 周期数(168MHz → 168 cycles/µs)
|
||||
*/
|
||||
#define SYS_TIME_CYCLE_PER_US 168UL
|
||||
|
||||
/*
|
||||
* CYCCNT 每溢出一次代表的微秒数(2^32 / 168 ≈ 25,564,904 µs ≈ 25.56s)
|
||||
*/
|
||||
#define SYS_TIME_OVERFLOW_US (uint64_t)(((uint64_t)1 << 32) / SYS_TIME_CYCLE_PER_US)
|
||||
|
||||
static volatile uint32_t s_overflow_cnt;
|
||||
|
||||
/*
|
||||
* 函数功能:初始化 DWT CYCCNT
|
||||
* 入口参数:无
|
||||
* 返 回 值:0 - 成功
|
||||
* 限定条件:须在 FreeRTOS 启动前调用
|
||||
* 函数说明:启用 DWT 和 CYCCNT 计数器,计数器从 0 开始
|
||||
*/
|
||||
int sys_time_init(void)
|
||||
{
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
DWT->CYCCNT = 0;
|
||||
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
|
||||
|
||||
s_overflow_cnt = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:获取微秒级时间戳
|
||||
* 入口参数:无
|
||||
* 返 回 值:64 位微秒时间戳
|
||||
* 函数说明:由当前 CYCCNT 值与溢出计数合成 64-bit 周期数再转换
|
||||
*/
|
||||
uint64_t sys_time_us(void)
|
||||
{
|
||||
uint32_t cyccnt = 0;
|
||||
uint64_t ticks = 0;
|
||||
uint32_t ov = 0;
|
||||
uint32_t ov2 = 0;
|
||||
|
||||
/*
|
||||
* 原子读取溢出计数与 CYCCNT,处理潜在的读取竞争
|
||||
* 若两次读取溢出计数不一致则重读 CYCCNT
|
||||
*/
|
||||
do {
|
||||
ov = s_overflow_cnt;
|
||||
cyccnt = DWT->CYCCNT;
|
||||
ov2 = s_overflow_cnt;
|
||||
} while (ov != ov2);
|
||||
|
||||
ticks = ((uint64_t)ov << 32) | cyccnt;
|
||||
return ticks / SYS_TIME_CYCLE_PER_US;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:获取毫秒级时间戳
|
||||
* 入口参数:无
|
||||
* 返 回 值:64 位毫秒时间戳
|
||||
* 限定条件:sys_time_init() 已成功调用
|
||||
* 函数说明:通过对 sys_time_us() 取整实现
|
||||
*/
|
||||
uint64_t sys_time_ms(void)
|
||||
{
|
||||
return sys_time_us() / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:SysTick 中断钩子,检测 CYCCNT 溢出
|
||||
* 入口参数:无
|
||||
* 返 回 值:无
|
||||
* 函数说明:必须在 SysTick_Handler() 中调用
|
||||
* 每 1ms 检查一次 CYCCNT 是否已回绕
|
||||
*/
|
||||
void sys_time_systick_hook(void)
|
||||
{
|
||||
static uint32_t s_last_cyccnt = 0;
|
||||
uint32_t cyccnt = DWT->CYCCNT;
|
||||
|
||||
if (cyccnt < s_last_cyccnt) {
|
||||
s_overflow_cnt++;
|
||||
}
|
||||
s_last_cyccnt = cyccnt;
|
||||
}
|
||||
Reference in New Issue
Block a user