重试让我们错过了下一个任务
一句话总结
传输、恢复和重试共同分摊同一个时间预算。即使成功的响应来晚了,也不算这次调用成功。
为什么需要它
如果传输给 10ms,恢复给 10ms,重试再给 10ms,那就不是“10ms 内完成的读取”。控制循环还要做下一件事,一个传感器却可能拖住整个执行流程。timeout 首先是调用方对整个操作承诺的期限,其次才是单个 API 的选项。本实验中的时钟是确定性的模型时间,并不测量真实的 CPU 执行延迟。
工作原理
读取一次起始时间,求出 deadline = start + budget。始终把同一个 deadline 传给 transfer 和 recover。如果第一次传输 3ms、恢复 2ms、第二次传输 3ms,总计就是 8ms。预算为 10ms 时可以成功,但预算为 7ms 时,第二次传输就无法完成。重试时重新创建预算,就是延长了时间。
还要测试 HAL 是否遵守时间约定。对于返回迟到成功的模型,调用刚结束就要重新读取时钟,如果经过的时间达到或超过预算,就必须返回 SENSOR_TIMEOUT。恢复之后也要做同样的检查。在本任务中,恰好在期限时到达的结果也属于超时。如果不明确边界是否包含在内,测试和实现就会遵守不同的约定。
时钟是以毫秒为单位的 uint32_t,到达最大值后会回到 0。因此 now >= deadline 这种绝对比较,在回绕前后可能出错。本任务把预算限制在 1–INT32_MAX,并在观察区间内最多回绕一次的前提下,用 unsigned 减法求出经过的时间。这是在使用 uint32_t 的模运算,并不是能解决所有时钟跳变的魔法。
最后一步,参数也被视为边界。在进行 I/O 之前,要检查 bus、out 以及三个回调是否为 NULL,地址和预算是否在允许范围内。不可能先解引用无效指针,再返回错误。ctx 是由 HAL 决定的不透明值,所以驱动不能一概拒绝 NULL。输出指针的两个字段只在成功的调用中改变。
亲手计算时钟回到 0 的瞬间
如果起始值定为 0xfffffffe,预算定为 4ms,那么 32 位期限就是 2。当前时间为 1 时,已经过去 3ms;为 2 时,已经过去 4ms。后者在本约定中属于超时。下面的 Python 是不控制传感器的算术实验。为了在整数不限长的 Python 中也能重现 32 位时钟,显式地加入了掩码。在 shell 里粘贴到 Python 中运行,只有两个边界都正确时才会输出最后一句。
@```python mask = (1 << 32) - 1 start, budget = 0xfffffffe, 4 deadline = (start + budget) & mask elapsed_before = (1 - start) & mask elapsed_at = (2 - start) & mask assert deadline == 2 assert elapsed_before == 3 and elapsed_before < budget assert elapsed_at == 4 and elapsed_at >= budget print("기한 직전 성공 후보 / 기한 도착 시간 초과")
之所以写成“成功候选”,是因为只满足时间条件,并不代表数据也有效。在期限内到来的 SENSOR_SHORT 仍然是失败,保留位错误的两个字节也不是成功。成功需要同时满足传输状态、格式、时间三个条件。反过来,即使传输返回 SENSOR_OK,如果确认完成的时刻已经达到或超过期限,也不能改变公开样本。
再来比较另一份起始 100ms、预算 7ms 的记录。第一次传输在 103ms 返回 BUS,恢复在 105ms 返回 OK,重传在 108ms 返回 OK。传给三次调用的期限都是 107ms。即使最后的状态是 OK,经过的时间也是 8ms,所以属于超时,并保留最初的温度和时间。如果从恢复开始重新给予预算,或者扣除恢复时间,就会悄悄改变调用方“请在 7ms 内完成”的约定。
调用之后的时间检查,无法强行中断一个无限卡住的 HAL 函数。因为回调必须返回,驱动才能重新读取时钟。要在真实设备上保证响应时间的上限,需要 HAL 自身的有限等待、取消、硬件定时器之类的单独设计与测量。本实验中的确定性回调和执行时间限制,并不能替代这种实时保证。请区分“在模型时间中验证了约定”与“测量了真实的最坏执行时间”这两种结果。
## 在现场相遇的样子
传感器样本的 observed_ms 是主机确认传输完成的时刻,并不是 ADC 实际转换温度的时刻,所以不能仅凭“刚读取过”就说“刚测量过”。上层程序必须同时显示最后一次成功的时间和当前的错误,旧值才不会像正常的最新值那样呈现出来。失败之后下一次正常读取是否会再次更新,也需要测试。
完成之后,真实设备的验证仍然留着。上拉、布线、电源、时钟、传感器转换周期、真实的 HAL 实现,这个模型都无法验证。请在作品集中写明“主机 C + 确定性 HAL 模型”,并把验证过的输入、状态、期限与没有验证的物理项目区分开。通过模型只是为下一次真实设备测试做准备的依据,并不是现场安全保证。
## 下一项实验要做什么
在第 7–8 步中,完成共享期限、迟到的成功、回绕和参数检查。整体评分会重新确认前面的各个步骤。请确认在“正常→部分失败→正常”的采集中,最后一个正常样本得到保留,并被新样本替换。会话结束时文件会消失,所以请另行保存源代码和测试记录。