ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RIOT 中 POSIX sleep()/usleep() 的自动化计时验证测试指南

RIOT 中 POSIX sleep()/usleep() 的自动化计时验证测试指南 RIOT 中 POSIX sleep()/usleep() 的自动化计时验证测试指南【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT本篇技术指南围绕 tests/sys/posix_sleep/README.md 展开讲解 RIOT 操作系统如何通过一个最小化的测试应用验证 POSIXsleep()与usleep()两个接口的正确性并借助 testrunner 脚本用主机侧时钟对设备侧休眠时长做整机计时校验允许 15% 的外部抖动。读完本文你将掌握该测试的用例设计、底层ztimer实现原理、构建运行方式以及 CI 上的约束条件可直接照搬这套接口功能 计时校验的测试模式到自己的驱动或系统服务测试中。测试目标与整体设计该测试应用位于tests/sys/posix_sleep目录其 README 明确了核心目标本测试用于验证 POSIX 的sleep()和usleep()函数测试脚本同时通过对比测试整体运行时间与宿主机计时来校验定时的正确性期望的抖动阈值为 15%。这意味着测试包含两个层次功能正确性设备端确实输出了预期顺序的wake up标记与最终的DONE输出证明sleep()/usleep()在阻塞指定时长后能正常返回并继续执行时间准确性从宿主机视角测量整个测试过程的总耗时与理论上限各次休眠时长的总和比对偏差落在 ±15% 之内才算通过从而确认休眠时长没有被提前返回或过度延长。整个目录结构非常精简由四部分构成测试源码 main.c、自动化脚本 tests/01-run.py、构建文件 Makefile 以及 CI 板卡约束 Makefile.ci。被测功能与底层实现ztimer 包装的 sleep/usleepRIOT 的 POSIX 兼容层中sleep()与usleep()的实现位于 sys/posix/sleep/posix_sleep.c两者都只是对ztimer睡眠接口的轻量包装unsigned int sleep(unsigned int seconds) { ztimer_sleep(ZTIMER_MSEC, seconds * MS_PER_SEC); return 0; } int usleep(useconds_t usec) { ztimer_sleep(ZTIMER_USEC, usec); return 0; }从源码可以看到两个值得注意的细节时钟选择sleep()基于毫秒时钟ZTIMER_MSEC秒数乘以MS_PER_SEC换算usleep()基于微秒时钟ZTIMER_USEC。二者在 sys/Makefile.dep 中由依赖解析自动引入只要USEMODULE中包含posix_sleep构建系统就会自动追加ztimer_msec、ztimer_usec与posix_headers无需手动声明。返回值语义sleep()返回 0表示全部秒数均已睡满无被信号打断的剩余秒数usleep()返回 0表示成功。真正的阻塞机制在ztimer_sleep()sys/ztimer/util.c中实现它先通过assert(!irq_is_in())断言不能在中断上下文中调用然后初始化一个已锁定的mutex注册一个以解锁该 mutex为回调的ztimer定时器调用ztimer_set()后阻塞在mutex_lock()上定时器到期时回调函数_callback_unlock_mutex()解锁 mutex休眠随即返回。此外ztimer_sleep()还会用时钟的adjust_sleep字段扣减板级/MCU 特定的定时器设置开销以提升短时休眠的精度。测试用例设计main.c 中的休眠序列测试主体 main.c 是一个无框架依赖的裸main()依次执行两轮循环/* needed for posix usleep */ #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE 600 #endif #include stdio.h #include unistd.h int main(void) { puts(5 x usleep(i * 500000)); for (unsigned i 0; i 5; i) { useconds_t us i * 500000u; usleep(us); puts(wake up); } puts(5 x sleep(i)); for (unsigned i 0; i 5; i) { sleep(i); puts(wake up); } puts(DONE); return 0; }用例设计上覆盖了典型的边界与递增场景usleep()阶段i从 0 到 4分别休眠 0、0.5、1.0、1.5、2.0 秒共 5 秒。其中i 0覆盖了 0 时长边界应立刻返回其余覆盖毫秒级到秒级混合的微秒休眠sleep()阶段i从 0 到 4分别休眠 0、1、2、3、4 秒共 10 秒覆盖 0 边界与多秒级休眠输出协议每次唤醒后打印wake up两个阶段分别以标题行5 x usleep(i * 500000)/5 x sleep(i)开头最后打印DONE为自动化脚本提供了明确的匹配锚点。整段测试理论总时长为 15 秒。另外文件顶部定义了_XOPEN_SOURCE 600这是 glibc 风格头文件中暴露usleep()声明所必需的预处理宏直接使用 POSIX 接口的应用程序通常都需要类似处理。自动化校验tests/01-run.py 的 15% 抖动判定自动化脚本 tests/01-run.py 基于 RIOT 的 testrunner 框架from testrunner import run编写其校验逻辑分两步第一步顺序匹配输出。通过child.expect_exact()依次等待标题行5 x usleep(i * 500000)5 次wake up标题行5 x sleep(i)5 次wake up结束标记DONE。第二步整机计时校验。用宿主机time.time()记录从首个标题行出现到DONE出现之间的墙钟时间换算为微秒与理论期望值比对US_PER_SEC 1000000 EXTERNAL_JITTER 0.15 testtime (time.time() - start_test) * US_PER_SEC exp sum(i * 500000 for i in range(5)) \ sum(i * US_PER_SEC for i in range(5)) lower_bound exp - (exp * EXTERNAL_JITTER) upper_bound exp (exp * EXTERNAL_JITTER) if not (lower_bound testtime upper_bound): raise InvalidTimeout(...)其中期望值exp等于usleep阶段总时长5 秒与sleep阶段总时长10 秒之和即 15,000,000 微秒允许 ±15% 的EXTERNAL_JITTER因此宿主机实测总耗时必须落在约 12.75 秒到 17.25 秒之间。脚本对越界情况抛出自定义的InvalidTimeout异常并打印Host timer measured %d us (client measured %d us)的诊断信息后以退出码 1 结束实现失败可观测。需要说明的是15% 的阈值是刻意放宽的容差它吸收了串口传输、testrunner 轮询、宿主机调度抖动等外部因素因此该测试验证的是休眠总量级正确而非微秒级的单次定时精度——后者应由ztimer自身的单元测试来保证。构建与运行按照 README 的说明在tests/sys/posix_sleep目录下执行标准的两步即可make flash testmake flash负责编译并烧录目标板卡make test则调用 testrunner 执行 tests/01-run.py 完成上述自动校验。在 Makefile 中可以看到两个关键配置USEMODULE posix_sleep USEMODULE test_utils_interactive_syncposix_sleep引入被测模块并自动带入ztimer_msec、ztimer_usec、posix_headerstest_utils_interactive_sync提供交互式同步使设备在测试脚本就绪后再开始输出。Makefile 注释说明了其必要性——交互同步能提高对输出打时间戳的精度并且在native平台上自动测试必须依赖它才能稳定通过否则测试脚本可能错过设备启动阶段的输出。测试在 CI 与资源受限板卡上的约束为了在持续集成环境中稳定运行该测试还带了两类板卡约束CI 黑名单microbit被加入TEST_ON_CI_BLACKLIST原因是该板卡在 QEMU 模拟下当前存在失败属于模拟器层面的已知问题而非测试本身缺陷内存不足板卡Makefile.ci 将atmega8、nucleo-l011k4列入BOARD_INSUFFICIENT_MEMORY——这两款板卡片上 RAM/Flash 不足以容纳posix_sleepztimertest_utils_interactive_sync的组合因此在 CI 中会被跳过构建。这两份文件共同说明了 RIOT 测试体系的做法功能测试本身是平台无关的但通过黑名单与资源清单精确声明其可运行边界避免在无法满足内存或模拟环境的板卡上误报失败。小结tests/sys/posix_sleep是一个麻雀虽小五脏俱全的 RIOT 系统级测试样例它用最精简的用例覆盖了 POSIXsleep()/usleep()的功能正确性与时间正确性两个维度通过 testrunner 脚本 宿主机墙钟计时 15% 抖动容差实现了对ztimer底层实现的端到端验证。读者既可以将其作为在 RIOT 上验证 POSIX 兼容层的入口也可以把顺序输出匹配 整体耗时校验的模式复用到其他需要计时语义验证的测试中。【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表