[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_rng] RNG随机数生成器配置和使用 文章目录一、RNG 随机数生成器原理1.1 什么是 RNG1.2 工作原理与寄存器操作二、偏差纠正2.1 偏差纠正机制2.2 配置与影响三、速度四、常用函数4.1 random_vector_generate4.1.1 函数原型4.1.2 参数说明五、示例代码5.1 bsp_rng.c5.1.1 错误处理说明5.2 bsp_rng.h六、常见问题与排查6.1 VALRDY 一直不置位6.2 随机数全为 0xFF6.3 偏差校正后速度过慢6.4 随机数分布不均匀七、总结八、参考资料一、RNG 随机数生成器原理1.1 什么是 RNG随机数生成器RNG基于芯片内部热噪声生成真正的非确定性随机数适用于加密、安全认证、防重放攻击等对随机性要求较高的场景。与伪随机数生成器PRNG不同RNG 不需要种子值每次生成的随机数都不可预测安全性更高。应用场景RNG 常用于密钥生成、安全 Token、防重放攻击、随机延时、测试数据填充等场景。在物联网设备中硬件 RNG 是保障通信安全的重要基础组件。1.2 工作原理与寄存器操作通过触发START任务启动 RNG通过触发STOP任务停止 RNG。当启动时新的随机数将连续生成并在准备就绪时写入VALUE寄存器。每个写入VALUE寄存器的新随机数都会生成一个VALRDY事件。这意味着在生成VALRDY事件后CPU 有时间直到下一个VALRDY事件从VALUE寄存器读出随机数然后再被一个新的随机数覆盖。寄存器/任务作用TASKS_START启动 RNG开始生成随机数TASKS_STOP停止 RNG停止生成随机数VALUE存放最新生成的随机数值8 位EVENTS_VALRDY新随机数就绪事件标志CONFIG配置偏差校正等参数提示VALRDY事件是读取随机数的关键信号建议在驱动中通过中断或轮询方式及时响应避免数据被覆盖导致随机数丢失。二、偏差纠正2.1 偏差纠正机制在内部比特流上使用偏差校正算法以消除对1或0的任何偏差。然后这些位被排到一个 8 位寄存器中以便从VALUE寄存器并行读出。偏差校正算法基于冯·诺依曼von Neumann校正器原理通过丢弃连续相同的比特对来消除统计偏差从而保证输出的随机数在统计上均匀分布。2.2 配置与影响可以在CONFIG寄存器中启用偏差校正。这将导致较慢的值生成但将确保随机值的统计均匀分布。开发者需要根据实际应用场景权衡对于安全敏感场景如密钥生成、Token 生成建议启用偏差校正以保证随机性质量对于对速度要求较高、随机性要求相对宽松的场景如噪声填充、测试数据可以关闭偏差校正以提升生成速度。三、速度生成一个随机字节数据所需的时间是不可预测的并且可能随字节的不同而变化。当启用偏差校正时尤其如此因为校正算法会丢弃部分比特导致有效比特率下降。因此RNG 不适合用于对时序要求严格的场景如高速数据流加密更适合用于低频次、高安全性的随机数获取场景。四、常用函数4.1 random_vector_generate4.1.1 函数原型voidrandom_vector_generate(uint8_t*pbuff,uint8_tsize);4.1.2 参数说明参数说明pbuff指向存储随机数的缓冲区size需要生成的随机数个数五、示例代码5.1 bsp_rng.c/******************************************************************************** * file bsp_rng.c * author jianqiang.xue * version V1.0.0 * date 2021-07-09 * brief 随机数生成 ********************************************************************************//* Includes ------------------------------------------------------------------*/#includestdint.h#includestdbool.h#includeRTE_Components.h#includeCMSIS_device_header#includenrf_rng.h#includenrf_error.h#includebsp_rng.h/* Private macro --------------------------------------------------------------*/#defineRNG_TIMEOUT_LOOPS1000000u/* 超时保护等待 VALRDY 的最大循环次数 *//* Private function prototypes -----------------------------------------------*//** * brief 启动硬件随机数并返回一个随机数值 * note 增加超时保护防止硬件异常时死循环 * retval 0-255 随机数超时返回 0xFF */staticuint8_tget_random_vector(void){uint8_tvalue;uint32_ttimeoutRNG_TIMEOUT_LOOPS;NRF_RNG-CONFIG1;NRF_RNG-TASKS_START1;// 生成新的随机数并写入VALUE寄存器。NRF_RNG-EVENTS_VALRDY0;while(NRF_RNG-EVENTS_VALRDY0){if(--timeout0u){// 超时停止 RNG 并返回错误标志避免死循环NRF_RNG-TASKS_STOP1;NRF_RNG-INTENCLR0;NRF_RNG-CONFIG0;return0xFFu;/* 0xFF 作为超时错误标志 */}}valueNRF_RNG-VALUE;NRF_RNG-TASKS_STOP1;NRF_RNG-INTENCLR0;NRF_RNG-CONFIG0;returnvalue;}/** * brief 得到一组随机数 * note 超时保护若硬件异常导致 get_random_vector 返回 0xFF则填充 0xFF 并继续 * param *pbuff: 缓存区 * param size: 数量 * retval None */voidrandom_vector_generate(uint8_t*pbuff,uint8_tsize){uint8_ti;for(i0;isize;i){pbuff[i]get_random_vector();}}5.1.1 错误处理说明超时保护get_random_vector内部通过RNG_TIMEOUT_LOOPS宏默认 1000000 次循环限制等待VALRDY事件的时间。若硬件异常导致VALRDY一直未置位循环会在超时后退出避免程序死锁。超时返回值超时后函数返回0xFF作为错误标志。调用方random_vector_generate会将0xFF写入缓冲区上层应用可通过判断0xFF来识别本次随机数获取失败。资源清理无论正常返回还是超时退出函数都会执行TASKS_STOP、INTENCLR、CONFIG复位操作确保 RNG 外设处于停止状态避免影响后续调用。适用场景该保护机制在硬件异常、时钟配置错误或外设未正确初始化时尤为重要可显著提升系统的健壮性与可维护性。5.2 bsp_rng.h/******************************************************************************** * file bsp_rng.h * author jianqiang.xue * version V1.0.0 * date 2021-07-09 * brief 随机数生成 ********************************************************************************/#ifndef__BSP_RNG_H#define__BSP_RNG_H/* Includes ------------------------------------------------------------------*/#includestdint.h/* Public Function Prototypes ------------------------------------------------*/voidrandom_vector_generate(uint8_t*pbuff,uint8_tsize);#endif六、常见问题与排查在实际开发中RNG 外设的使用可能会遇到各种异常情况。下面列举几个典型问题并给出对应的排查步骤与解决方案。6.1 VALRDY 一直不置位现象调用get_random_vector后EVENTS_VALRDY始终为 0程序一直停留在等待循环中若未加超时保护则会死锁。可能原因RNG 外设时钟未使能导致外设无法工作未正确触发TASKS_START或触发后立即被复位芯片处于低功耗模式RNG 外设被关闭硬件异常或芯片损坏。排查步骤检查时钟配置确认 RNG 外设的时钟源已使能确认TASKS_START已正确写入 1且未被后续代码误清零检查是否在低功耗模式下调用 RNG必要时先唤醒外设使用调试器读取POWER、CLOCK相关寄存器确认外设供电正常。解决方案确保在调用 RNG 前完成外设初始化与时钟使能在驱动中增加超时保护如本文RNG_TIMEOUT_LOOPS宏避免死循环若确认硬件异常可考虑切换到软件伪随机数生成器PRNG作为降级方案。6.2 随机数全为 0xFF现象random_vector_generate填充的缓冲区全部为0xFF。可能原因get_random_vector超时退出返回0xFF作为错误标志VALUE寄存器读取时序错误读到复位默认值偏差校正配置异常导致输出被截断。排查步骤在get_random_vector超时分支处打断点确认是否超时退出检查CONFIG寄存器配置确认偏差校正位设置是否正确用调试器直接读取VALUE寄存器验证硬件是否正常输出随机数检查EVENTS_VALRDY是否在读取前被正确清零。解决方案若为超时导致按 6.1 节排查硬件与时钟问题若为读取时序问题确保在VALRDY置位后立即读取VALUE并在读取前清零事件标志上层应用可增加对0xFF的校验若连续多次失败则报错并重试。6.3 偏差校正后速度过慢现象启用偏差校正后生成随机数的速度明显下降无法满足应用需求。可能原因偏差校正算法会丢弃部分比特对导致有效比特率下降应用对随机数的需求量较大而 RNG 本身吞吐有限轮询方式读取VALRDY事件CPU 空转浪费大量时间。排查步骤统计单位时间内生成的随机数字节数评估实际吞吐对比关闭偏差校正前后的速度差异确认瓶颈是否在偏差校正检查是否使用中断方式读取VALRDY避免轮询空转。解决方案对于安全敏感场景保留偏差校正以保证随机性质量对于速度敏感场景可关闭偏差校正CONFIG寄存器清零改用中断或 DMA 方式读取随机数减少 CPU 等待时间若吞吐仍不足可考虑在系统初始化时预生成一批随机数缓存备用。6.4 随机数分布不均匀现象生成的随机数在统计上出现明显偏向某些值出现频率过高。可能原因未启用偏差校正内部比特流存在统计偏差读取时序错误导致部分比特丢失外部干扰影响热噪声源质量。排查步骤采集大量随机数样本进行简单的分布统计确认CONFIG寄存器中偏差校正位已正确使能检查 PCB 布局确认 RNG 相关引脚无强干扰源。解决方案启用偏差校正消除统计偏差确保读取时序正确避免数据覆盖或丢失若为硬件干扰优化 PCB 布局或增加屏蔽措施。七、总结本文围绕 nRF5 系列芯片的硬件随机数生成器RNG展开从原理到代码实现进行了系统梳理核心要点如下工作原理RNG 基于芯片内部热噪声生成真正的非确定性随机数无需种子值。通过触发START任务启动、STOP任务停止新随机数在就绪后写入VALUE寄存器并产生VALRDY事件通知 CPU 读取。偏差纠正内部比特流经偏差校正算法处理后可消除对1或0的统计偏差确保随机值均匀分布。该功能通过CONFIG寄存器启用代价是生成速度变慢。速度特性生成单个随机字节所需时间不可预测启用偏差纠正后尤为明显因此不适合对时序要求严格的场景。代码实现要点封装了random_vector_generate接口通过get_random_vector逐字节获取随机数并填充缓冲区为get_random_vector增加了超时保护机制RNG_TIMEOUT_LOOPS防止硬件异常时陷入死循环超时返回0xFF作为错误标志无论正常返回还是超时退出均会复位TASKS_STOP、INTENCLR、CONFIG确保外设状态干净提升系统健壮性。八、参考资料Nordic Semiconductor 官方文档 - RNG 外设说明nRF5 SDK 官方文档与 API 手册nRF52832 数据手册Product SpecificationCSDN 博客nRF5 系列 RNG 随机数生成器使用详解CSDN 博客nRF52832 外设驱动开发实战——RNG 篇