# Utils 模块迁移总结

## 已完成的工作

### 1. 创建了 C 版本的 utils 模块

**文件**：
- `src/utils.h` - 工具函数头文件
- `src/utils.c` - 工具函数实现

### 2. 主要功能迁移

#### 时间工具函数（从 `timer.hpp` 转换）
- `utils_time_current_tick()` - 获取当前 Tick（原 `time::currentTick()`）
- `utils_time_elapsed_since()` - 计算从指定 Tick 到现在的经过时间（原 `time::elapsedTicksSince()`）
- `utils_time_elapsed_between()` - 计算两个 Tick 之间的时间差（原 `time::elapsedTicksBetween()`）
- `utils_time_tick_to_ms()` - 将 Tick 转换为毫秒（原 `RtcTick::toMs()`）
- `utils_time_ms_to_ticks_safe()` - 将毫秒转换为 Tick（原 `time::msToTicksSafe()`）

#### 数学工具函数
- `utils_math_isnan()` - 检查是否为 NaN
- `utils_math_isinf()` - 检查是否为无穷大
- `utils_math_clamp()` - 限制值在指定范围内
- `utils_math_lerp()` - 线性插值

#### 字节操作工具函数
- `utils_bytes_from_data()` - 将数据转换为字节数组视图
- `utils_bytes_compare()` - 字节数组比较
- `utils_bytes_copy()` - 字节数组复制

### 3. 与原 C++ 版本的对比

| C++ 版本 | C 版本 | 说明 |
|---------|--------|------|
| `time::currentTick()` | `utils_time_current_tick()` | 函数调用 |
| `time::elapsedTicksSince()` | `utils_time_elapsed_since()` | 函数调用 |
| `time::elapsedTicksBetween()` | `utils_time_elapsed_between()` | 函数调用 |
| `RtcTick::toMs()` | `utils_time_tick_to_ms()` | 成员函数 -> 函数调用 |
| `time::msToTicksSafe()` | `utils_time_ms_to_ticks_safe()` | 函数调用 |
| `std::isnan()` | `utils_math_isnan()` | 封装标准库函数 |
| `std::isinf()` | `utils_math_isinf()` | 封装标准库函数 |

### 4. 主要变化

#### 时间系统
- **C++ 版本**：使用 `app_timer`（nRF5 SDK）
- **C 版本**：使用 Zephyr 的 `k_uptime_ticks()` 和 `CONFIG_SYS_CLOCK_TICKS_PER_SEC`

#### RtcTick 结构
- **C++ 版本**：结构体 + 成员函数 `toMs()`
- **C 版本**：结构体 + 独立函数 `utils_time_tick_to_ms()`

#### 命名空间
- **C++ 版本**：`fsa::time` 命名空间
- **C 版本**：函数前缀 `utils_time_*` 和 `utils_math_*`

### 5. 已更新的文件

- `CMakeLists.txt` - 添加了 `src/utils.c`
- `main.c` - 添加了 utils 模块测试代码
- `prj.conf` - 添加了数学库支持配置

## 注意事项

1. **系统时钟频率**：使用 `CONFIG_SYS_CLOCK_TICKS_PER_SEC` 定义系统 Tick 频率
2. **Tick 溢出处理**：实现了 32 位 Tick 的溢出处理
3. **数学库**：需要启用 `CONFIG_NEWLIB_LIBC` 和 `CONFIG_NEWLIB_LIBC_FLOAT_PRINTF`
4. **时间精度**：Zephyr 的系统 Tick 频率可能与原 `app_timer` 不同，需要根据实际需求调整

## 待完成的工作

### 1. 编译测试
- [ ] 编译项目，检查是否有编译错误
- [ ] 修复可能的编译错误

### 2. 功能验证
- [ ] 测试时间工具函数
- [ ] 验证 Tick 到毫秒的转换精度
- [ ] 测试数学工具函数
- [ ] 测试字节操作工具函数

### 3. 后续优化
- [ ] 如果需要，可以添加更多工具函数
- [ ] 可以添加性能测试
- [ ] 可以添加单元测试

## 下一步

1. 编译项目，检查是否有错误
2. 如果编译成功，测试 utils 模块功能
3. 如果一切正常，可以继续迁移下一个模块（如驱动模块或数据采集模块）

