- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
本篇技术指南以 tests/pkg/wolfssl/README.md 为核心骨架,系统讲解 RIOT 中用于验证 wolfcrypt/wolfSSL 移植可用性与性能的测试套件:如何通过USEMODULE裁剪/启用加密算法模块、如何通过BOARD_INSUFFICIENT_MEMORY判断目标板资源是否充足、如何运行功能测试与完整基准测试。读完你将掌握在指定 RIOT 目标板上构建、运行并评估 wolfSSL 加密库移植的正确姿势,并能依据模块—资源权衡对内存受限平台进行针对性裁剪。
测试套件的定位:不只是跑通,还要测性能
tests/pkg/wolfssl是 RIOT 中针对 wolfSSL 包(包含其底层加密库 wolfCrypt)的集成测试应用。它的目的正如其 README 开篇所述:验证一个 wolfcrypt/wolfSSL 移植到特定目标平台后的可用性(correctness)与性能(performance)。
这意味着它承担着双重职责:
- 功能验证:通过
wolfcrypt-test伪模块调用 wolfCrypt 自带的wolfcrypt_test(),对编译进固件的各加密算法做完整自检; - 性能基准:通过
wolfcrypt-benchmark伪模块调用benchmark_test(),测量各算法的吞吐量(如 MB/s、ops/sec)。
整个测试应用由 4 个文件组成,分布在 tests/pkg/wolfssl 目录下:
| 文件 | 职责 |
|---|---|
| main.c | 测试应用入口,依次执行功能测试与基准测试 |
| Makefile | 编译选项、模块选择、平台约束声明 |
| Makefile.ci | BOARD_INSUFFICIENT_MEMORY列表,声明无法跑完整测试的板卡 |
| tests/01-run.py | 自动化测试脚本,用 testrunner 解析串口输出并判定通过 |
编译选项:用 USEMODULE 精确控制算法模块
测试套件的核心设计理念是按需裁剪:wolfSSL 包被拆分成了大量"伪模块"(pseudo-modules),每一个对应一类算法或功能。通过 tests/pkg/wolfssl/Makefile 中的USEMODULE变量即可启用或禁用:
USEPKG += wolfssl USEMODULE += wolfcrypt wolfcrypt-test wolfcrypt_sha512 \ wolfcrypt_curve25519 wolfcrypt_ed25519 wolfcrypt_chacha \ wolfcrypt_poly1305 wolfcrypt_aes wolfcrypt_ecc \ wolfcrypt_asn wolfcrypt_random # 取消下面一行的注释可启用 RSA 测试 #(例如当目标平台资源充足时) #USEMODULE += wolfcrypt_rsa wolfcrypt_dh # 注释下面一行即可禁用完整基准测试 USEMODULE += wolfcrypt-benchmark USEMODULE += xtimer上述默认配置默认启用了以下算法模块:
- wolfcrypt:wolfCrypt 核心(错误处理、KDF、哈希基础设施、数学库等基础源文件);
- wolfcrypt-test:wolfCrypt 自带的功能自检入口;
- wolfcrypt_sha512:SHA-384/SHA-512 哈希;
- wolfcrypt_curve25519 / wolfcrypt_ed25519:Curve25519 密钥交换与 Ed25519 签名(现代后量子时代前的主流轻量级椭圆曲线算法);
- wolfcrypt_chacha / wolfcrypt_poly1305:ChaCha20 流密码与 Poly1305 消息认证码;
- wolfcrypt_aes:AES 对称加密(启用后经 pkg/wolfssl/Makefile.dep 自动拉入
wolfcrypt_cmac与wolfcrypt_coding); - wolfcrypt_ecc:椭圆曲线密码(ECC)及 SP 加速;
- wolfcrypt_asn:ASN.1/DER 编解码(配合
wolfcrypt_coding); - wolfcrypt_random:随机数生成(经依赖自动加入
random模块,用于填充 RIOT 的随机数子系统); - xtimer:RIOT 的高精度定时器,用于主线程启动延时。
注意:README 与 Makefile 的命名差异
README 中写的是"注释掉USEMODULE += wolfssl-benchmarks行来禁用完整基准测试",但仓库中实际生效的模块名是wolfcrypt-benchmark(见 Makefile 第 18 行)。以实际 Makefile 为准,禁用基准测试的正确做法是注释该行:
#USEMODULE += wolfcrypt-benchmark同样地,默认不启用RSA 与 DH 测试,需要手动取消注释:
USEMODULE += wolfcrypt_rsa wolfcrypt_dhRSA/DH 属于重量级公钥算法(涉及大数模幂运算与 SP 数学库),在内存与算力有限的目标板上会显著增加固件体积与运行时间,因此默认保持关闭,正如 Makefile 注释所提示的:"e.g. when enough resources are available on platform"。
模块裁剪的底层实现:user_settings.h
每个wolfcrypt_*伪模块最终如何映射为 wolfSSL 的编译宏?答案在 pkg/wolfssl/include/user_settings.h。该文件是 wolfSSL 自定义配置头文件,其中几乎每个模块都用#ifdef MODULE_WOLFCRYPT_XXX的守卫模式做条件编译,例如:
#undef HAVE_CURVE25519 #ifdef MODULE_WOLFCRYPT_CURVE25519 #define HAVE_CURVE25519 #define CURVE25519_SMALL #endif #undef HAVE_ED25519 #ifdef MODULE_WOLFCRYPT_ED25519 #define HAVE_ED25519 #define ED25519_SMALL #endif #undef NO_AES #ifndef MODULE_WOLFCRYPT_AES #define NO_AES #endif #undef HAVE_SHA512 #undef HAVE_SHA384 #undef WOLFSSL_SHA384 #undef WOLFSSL_SHA512 #ifdef MODULE_WOLFCRYPT_SHA512 #define HAVE_SHA384 #define HAVE_SHA512 #define WOLFSSL_SHA384 #define WOLFSSL_SHA512 #define USE_SLOW_SHA512 #endif #ifdef MODULE_WOLFCRYPT_RSA #define HAVE_RSA #define RSA_LOW_MEM #define WC_RSA_BLINDING #define WOLFSSL_STATIC_RSA #define WOLFSSL_HAVE_SP_DH #define WOLFSSL_HAVE_SP_RSA #else #define NO_RSA #endif可见,RIOT 通过MODULE_WOLFCRYPT_*宏与 wolfSSL 的HAVE_*/NO_*宏建立了一一映射:启用模块 → 编译进对应算法;未启用 → 通过NO_*宏显式剔除。这正是"裁剪单个伪模块"在源码层面的真正含义,也是"模块 vs 资源"权衡的根基——未启用的算法不会进入固件,直接节省 Flash 与 RAM。
user_settings.h还针对嵌入式环境做了一系列系统级适配,例如:
WOLFSSL_RIOT_OS 1:声明运行在 RIOT 之上;CUSTOM_RAND_GENERATE random_uint32与CUSTOM_RAND_TYPE uint32_t:将 wolfSSL 的随机数生成器挂接到 RIOT 的random子系统;NO_DEV_RANDOM、NO_FILESYSTEM、NO_MAIN_DRIVER:裁剪桌面端依赖;WOLFSSL_SP_MATH、WOLFSSL_SP_SMALL、SP_WORD_SIZE 32、WOLFSSL_SP:启用单精度(SP)数学库并限制为 32 位字长,兼顾资源受限平台;SINGLE_THREADED:声明单线程使用,简化内部锁逻辑;- 对 SAML21/SAMD51/SAME5x 等平台,末尾还通过
_SAML21_AES_COMPONENT_等宏规避与厂商 SDK 头文件中Aes结构体的命名冲突。
模块间的自动依赖:开启一个,自动带上配套
在 pkg/wolfssl/Makefile.dep 中,RIOT 定义了各 wolfCrypt 模块之间的依赖关系,这决定了你开启某个模块后还会隐式带入哪些模块:
ifneq (,$(filter wolfcrypt-test,$(USEMODULE))) USEMODULE += wolfcrypt USEMODULE += wolfcrypt_coding endif ifneq (,$(filter wolfcrypt-benchmark,$(USEMODULE))) USEMODULE += wolfcrypt USEMODULE += wolfcrypt_coding USEMODULE += printf_float endif ifneq (,$(filter wolfcrypt_ed25519,$(USEMODULE))) USEMODULE += wolfcrypt_sha512 endif ifneq (,$(filter wolfcrypt_aes,$(USEMODULE))) USEMODULE += wolfcrypt_cmac USEMODULE += wolfcrypt_coding endif ifneq (,$(filter wolfcrypt_random,$(USEMODULE))) USEMODULE += random endif几个值得注意的细节:
wolfcrypt-benchmark会额外拉入printf_float——因为基准测试需要打印浮点吞吐量(MB/s),这在默认不带浮点 printf 的嵌入式环境中必须显式引入;wolfcrypt_ed25519自动依赖wolfcrypt_sha512——因为 Ed25519 签名内部依赖 SHA-512;wolfcrypt_poly1305只有在同时启用wolfcrypt_chacha时才会拉入组合模块wolfcrypt_chacha20_poly1305(AEAD 组合);- 当使用
sock_tls/wolfssl_socket等上层 TLS 模块时,会自动拉入 AES、ASN、HMAC、MD5、SHA、random 等一整套基础密码组件。
此外,文件末尾声明了硬性架构约束:
# wolfssl is only supported by 32 bit architectures FEATURES_REQUIRED_ANY += arch_32bit|arch_64bit即该包仅支持 32/64 位架构(这也解释了为何 wolfSSL 包在 8/16 位 MCU 上不可用)。
模块 vs 资源:BOARD_INSUFFICIENT_MEMORY 的取舍
README 特别强调了一个"模块 vs 资源"(Modules vs. Resources)的核心思想:这个测试工具可以用来在选定目标上对 wolfSSL 包中的单个伪模块做基准测试,而默认的BOARD_INSUFFICIENT_MEMORY列表排除了所有无法运行完整测试的目标板。
该列表定义在 Makefile.ci 中,包含 50 余块板卡,例如:
BOARD_INSUFFICIENT_MEMORY := \ blackpill-stm32f103c8 \ blackpill-stm32f103cb \ bluepill-stm32f030c8 \ bluepill-stm32f103c8 \ bluepill-stm32f103cb \ cc1350-launchpad \ cc2650-launchpad \ gd32vf103c-start \ i-nucleo-lrwan1 \ im880b \ lobaro-lorabox \ maple-mini \ nucleo-f030r8 \ nucleo-f103rb \ nucleo-l011k4 \ samd10-xmini \ saml10-xpro \ saml11-xpro \ sipeed-longan-nano \ stm32f0discovery \ stm32f7508-dk \ weact-g030f6 \ # (此处省略其余条目,完整列表见 Makefile.ci)这些板卡大多是 Flash/RAM 较小的入门级 MCU 平台(如 STM32F0/F1 系列、SAM D10/L10/L11、GD32VF103、CC1350 等),无法承载完整测试固件。但 README 也给出了重要提示:
Targets included in this list may still be able to run a build with a reduced set of algorithms compiled in.
也就是说,出现在该列表中的板卡依然可能通过"裁剪算法集合"来构建运行——这正是上一节USEMODULE裁剪机制的用武之地。例如在 BluePill(STM32F103C8,64 KiB Flash)上,可以去掉wolfcrypt_ed25519、wolfcrypt_ecc等较大模块,仅保留 SHA/AES/ChaCha/Poly1305 做轻量验证。
针对嵌入式的栈与编译适配
在非 native 平台上,测试运行需要更多的栈空间。Makefile 做了两处适配:
# 基于实测的优化栈值,若观察到段错误请增大该值 CFLAGS += -DTHREAD_STACKSIZE_MAIN=2*THREAD_STACKSIZE_LARGE ifeq (,$(filter native native32 native64,$(BOARD))) CFLAGS += -DBENCH_EMBEDDED endif- 主线程栈被放大为
2 * THREAD_STACKSIZE_LARGE,以容纳 wolfCrypt 测试中的大数组与 SP 数学运算; - 非 native 平台额外定义
BENCH_EMBEDDED,让 wolfSSL 基准测试在嵌入式模式下运行(配合 pkg/wolfssl/patches/0002-fix-benchmark-timer-and-suppress-warning.patch 中针对嵌入式计时器的修复)。
程序入口与执行流程:main.c 全解析
测试应用的执行逻辑集中在 main.c,其主流程非常简洁:
int main(void) { LOG_INFO("wolfSSL Crypto Test!\n"); /* 等待 1 秒,规避在无 RTC 同步平台上测试失败的问题 */ xtimer_sleep(1); wolfcrypt_test(NULL); #ifdef MODULE_WOLFCRYPT_BENCHMARK LOG_INFO("wolfSSL Benchmark!\n"); benchmark_test(NULL); #else LOG_INFO("wolfSSL Benchmark disabled\n"); #endif return 0; }关键点:
xtimer_sleep(1)延时 1 秒:这是针对无实时时钟(RTC)或 RTC 尚未同步的平台的工作区(workaround),避免测试在系统时间未就绪时出错;wolfcrypt_test(NULL):来自wolfcrypt/test/test.h,运行所有已编译进固件的算法自检,全部通过时输出test passed!;benchmark_test(NULL):来自wolfcrypt/benchmark/benchmark.h,仅在定义了MODULE_WOLFCRYPT_BENCHMARK宏时编译并执行;禁用基准测试时打印wolfSSL Benchmark disabled。
注意#ifdef MODULE_WOLFCRYPT_BENCHMARK宏的存在:RIOT 会把USEMODULE中每个模块名自动转换为MODULE_*宏并全局定义,因此 main.c 无需手工同步 Makefile 与代码——这正是编译期按需裁剪的又一层保障。
自动化验证:01-run.py 测试脚本
tests/01-run.py 是 RIOT testrunner 体系的测试脚本,负责驱动固件并判定结果。它的逻辑揭示了本测试通过判定的关键输出特征:
def _wait_for_test(child): return child.expect(["test passed!", "Test complete"], timeout=TEST_TIMEOUT) def _wait_for_bench(child): return child.expect([r"MB\/s", r"ops\/sec", "Benchmark complete", "wolfSSL Benchmark disabled"], timeout=BENCH_TIMEOUT) def testfunc(child): while _wait_for_test(child) == 0: pass while _wait_for_bench(child) <= 1: pass即:功能测试以串口输出test passed!为通过标志,基准测试以出现MB/s、ops/sec或Benchmark complete为完成标志(禁用基准时则匹配wolfSSL Benchmark disabled)。
脚本还针对"真实硬件"做了超时适配,其注释是了解各平台耗时差异的第一手资料:
# native 是本测试的默认平台 BOARD = os.environ.get("BOARD", "native") # 在真实硬件上增大超时 # ED25519 在 samr21-xpro 上额外耗时约 160s # ED25519 在 nucleo-l073rz 上额外耗时约 230s # ED25519 在 nrf51dk 上额外耗时约 500s TEST_TIMEOUT = 600 if BOARD not in ['native', 'native32', 'native64'] else DEFAULT_TIMEOUT # ECDSA 256 在 samr21-xpro 上额外耗时约 30s # ECDSA 256 在 nrf51dk 上额外耗时约 40s BENCH_TIMEOUT = 40 if BOARD not in ['native', 'native32', 'native64'] else 20这些注释量化了在低算力 MCU 上运行 Ed25519、ECDSA 基准的真实代价(数百秒级别),也从侧面印证了"完整测试 + 完整基准"对硬件资源的要求之高。
实战:构建、运行与结果解读
在 native 上运行(默认平台)
native是测试脚本的默认平台(见BOARD = os.environ.get("BOARD", "native")),适合快速验证全流程:
cd tests/pkg/wolfssl make flash testnative 平台输出特征(示意):启动后打印wolfSSL Crypto Test!,随后 wolfCrypt 自检输出各算法测试结果并最终出现test passed!;紧接着wolfSSL Benchmark!后打印各算法吞吐量(以MB/s/ops/sec计),最后以Benchmark complete收尾。
在真实硬件上运行
以一块满足资源的板卡(例如 samr21-xpro)为例:
cd tests/pkg/wolfssl BOARD=samr21-xpro make flash term由于真实硬件上 Ed25519/ECDSA 基准耗时可达数分钟(见上文脚本注释),建议直接使用自动化测试并依赖脚本的超时机制:
BOARD=samr21-xpro make flash test内存不足时的应对流程
当目标板出现在BOARD_INSUFFICIENT_MEMORY列表中或链接失败时,按以下顺序裁剪:
- 先禁用基准测试:注释
USEMODULE += wolfcrypt-benchmark行(同时省去printf_float依赖); - 再削减重量级算法:优先移除
wolfcrypt_rsa wolfcrypt_dh(默认已关)、wolfcrypt_ecc、wolfcrypt_ed25519(连带wolfcrypt_sha512)、wolfcrypt_curve25519; - 保留最小验证集:
wolfcrypt wolfcrypt-test wolfcrypt_aes wolfcrypt_sha wolfcrypt_random足以验证移植正确性; - 如出现段错误:按 Makefile 提示增大
THREAD_STACKSIZE_MAIN的倍数。
结果解读要点
- 功能测试:
test passed!表示所有启用算法的自检通过;任何一项失败都会输出具体错误并停留在对应算法; - 性能基准:关注各算法的
MB/s(对称加密/哈希)与ops/sec(非对称运算如 ECDSA/Ed25519 签名验签)两项指标,可横向对比不同板卡、不同编译优化级别(-O0/-Os)下的移植质量; - 时间预估:完整测试在低端 MCU 上可能运行数分钟甚至更久(如 nrf51dk 上 Ed25519 单一项即额外约 500 秒),务必预留足够的测试窗口。
支撑它的包基础设施:pkg/wolfssl 一览
该测试依赖 pkg/wolfssl 包,其版本与构建信息同样值得了解:
- pkg/wolfssl/Makefile 固定 wolfSSL 源码版本为提交
addf0d4b743635a9e4c6d10d0c05458f724e56e3(v5.9.2 之后的一个提交,其选取原因是"支持 raw public key 的在线固定"),许可为 GPL-3.0; - 构建时对 gcc 额外关闭
-Wmaybe-uninitialized与-Wcast-align两类误报告警(前者源于 gcc 在-Og下对确实已初始化变量的误判,后者源于 wolfcrypt 使用uint8_t块缓冲进行 32 位操作的未对齐疑虑,包作者经检查判定为对齐正确); - pkg/wolfssl/Makefile.wolfcrypt 定义了默认编译的 wolfCrypt 源文件:核心文件(
error.c、kdf.c、hash.c、logging.c、wc_encrypt.c、wc_port.c、wolfmath.c)加上默认开启的sha.c、sha256.c、fe_low_mem.c、ge_low_mem.c、sp_int.c、sp_c32.c——其中sp_*即 SP 单精度数学库的实现文件,是 ECC/Ed25519 等算法在嵌入式上可用性的关键; - pkg/wolfssl/Makefile.wolfcrypt-benchmark 将
benchmark.c编译为独立的wolfcrypt-benchmark模块,与 main.c 中的#ifdef MODULE_WOLFCRYPT_BENCHMARK分支一一对应; - 此外还包含两份针对嵌入式移植的补丁:0001-fix-unused-vars-and-function-and-unix-io.patch(清理未使用变量/函数及 Unix I/O 依赖)与 0002-fix-benchmark-timer-and-suppress-warning.patch(修复基准计时器并压制告警)。
总结
tests/pkg/wolfssl不仅仅是一个测试,它同时是一把度量尺与一套裁剪模板:
- 作为验证工具:它用 wolfCrypt 自带自检 + 基准测试,从正确性与性能两个维度检验 wolfSSL 在特定 RIOT 目标板上的移植质量;
- 作为裁剪模板:通过
USEMODULE与user_settings.h的宏映射机制,它展示了如何把 wolfSSL 从"全量桌面库"裁剪为"嵌入式可用子集",并按板卡内存能力(BOARD_INSUFFICIENT_MEMORY)动态取舍; - 作为性能参照:01-run.py 中关于 Ed25519/ECDSA 在真实 MCU 上数百秒级耗时的注释,为在资源受限平台上部署 wolfSSL 的算力预算提供了第一手参考数据。
对于需要在 RIOT 上评估或移植 wolfSSL 的开发者,推荐的实践路径是:先在 native 上跑通默认全量配置作为基线,再针对目标板卡逐步裁剪模块,最后用make flash test在真实硬件上完成正确性与性能验收。
- 物联网
- 嵌入式
- 操作系统
- 实时系统
【免费下载链接】RIOT
RIOT - The friendly OS for IoT
相关推荐
RIOT OS 在 Ebyte E104-BT5011A 测试板(nRF52811)上的移植、烧录与调试实战指南
RIOT OS 在 Ebyte E104 BT5011A 测试板(nRF52811)上的移植、烧录与调试实战指南 E104 BT5011A Test Board
物联网嵌入式操作系统实时系统bad-words核心功能全解析:从基础过滤到高级自定义配置
bad words核心功能全解析:从基础过滤到高级自定义配置 bad words是一款强大的JavaScript脏话过滤工具,能够帮助开发者轻松实现文本内容的净
物联网嵌入式操作系统实时系统RIOT OS 定时器负载基准测试:解读 tests/bench/xtimer_load 的 drift/jitter 测量原理与实战
RIOT OS 定时器负载基准测试:解读 tests/bench/xtimer_load 的 drift/jitter 测量原理与实战 RIOT OS 的 te
物联网嵌入式操作系统实时系统
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考