修复多连接的问题

This commit is contained in:
2026-07-19 15:27:49 +08:00
parent 9ed4c22022
commit e06d849007
38 changed files with 2475 additions and 1953 deletions

107
App/sys_time.c Normal file
View 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;
}