news 2026/9/14 11:08:01

[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_rng] RNG随机数生成器配置和使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[单片机框架][bsp层][nrf52832][nrf52840][nrf52810][nrf52820][bsp_rng] RNG随机数生成器配置和使用

文章目录

  • 一、RNG 随机数生成器原理
    • 1.1 什么是 RNG?
    • 1.2 工作原理与寄存器操作
  • 二、偏差纠正
    • 2.1 偏差纠正机制
    • 2.2 配置与影响
  • 三、速度
  • 四、常用函数
    • 4.1 random_vector_generate
      • 4.1.1 函数原型
      • 4.1.2 参数说明
  • 五、示例代码
    • 5.1 bsp_rng.c
      • 5.1.1 错误处理说明
    • 5.2 bsp_rng.h
  • 六、常见问题与排查
    • 6.1 VALRDY 一直不置位
    • 6.2 随机数全为 0xFF
    • 6.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_generate

4.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 ------------------------------------------------------------------*/#include<stdint.h>#include<stdbool.h>#include"RTE_Components.h"#includeCMSIS_device_header#include"nrf_rng.h"#include"nrf_error.h"#include"bsp_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_ttimeout=RNG_TIMEOUT_LOOPS;NRF_RNG->CONFIG=1;NRF_RNG->TASKS_START=1;// 生成新的随机数并写入VALUE寄存器。NRF_RNG->EVENTS_VALRDY=0;while(NRF_RNG->EVENTS_VALRDY==0){if(--timeout==0u){// 超时:停止 RNG 并返回错误标志,避免死循环NRF_RNG->TASKS_STOP=1;NRF_RNG->INTENCLR=0;NRF_RNG->CONFIG=0;return0xFFu;/* 0xFF 作为超时错误标志 */}}value=NRF_RNG->VALUE;NRF_RNG->TASKS_STOP=1;NRF_RNG->INTENCLR=0;NRF_RNG->CONFIG=0;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(i=0;i<size;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_STOPINTENCLRCONFIG复位操作,确保 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 ------------------------------------------------------------------*/#include<stdint.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 外设被关闭;
  • 硬件异常或芯片损坏。

排查步骤

  1. 检查时钟配置,确认 RNG 外设的时钟源已使能;
  2. 确认TASKS_START已正确写入 1,且未被后续代码误清零;
  3. 检查是否在低功耗模式下调用 RNG,必要时先唤醒外设;
  4. 使用调试器读取POWERCLOCK相关寄存器,确认外设供电正常。

解决方案

  • 确保在调用 RNG 前完成外设初始化与时钟使能;
  • 在驱动中增加超时保护(如本文RNG_TIMEOUT_LOOPS宏),避免死循环;
  • 若确认硬件异常,可考虑切换到软件伪随机数生成器(PRNG)作为降级方案。

6.2 随机数全为 0xFF

现象random_vector_generate填充的缓冲区全部为0xFF

可能原因

  • get_random_vector超时退出,返回0xFF作为错误标志;
  • VALUE寄存器读取时序错误,读到复位默认值;
  • 偏差校正配置异常,导致输出被截断。

排查步骤

  1. get_random_vector超时分支处打断点,确认是否超时退出;
  2. 检查CONFIG寄存器配置,确认偏差校正位设置是否正确;
  3. 用调试器直接读取VALUE寄存器,验证硬件是否正常输出随机数;
  4. 检查EVENTS_VALRDY是否在读取前被正确清零。

解决方案

  • 若为超时导致,按 6.1 节排查硬件与时钟问题;
  • 若为读取时序问题,确保在VALRDY置位后立即读取VALUE,并在读取前清零事件标志;
  • 上层应用可增加对0xFF的校验,若连续多次失败则报错并重试。

6.3 偏差校正后速度过慢

现象:启用偏差校正后,生成随机数的速度明显下降,无法满足应用需求。

可能原因

  • 偏差校正算法会丢弃部分比特对,导致有效比特率下降;
  • 应用对随机数的需求量较大,而 RNG 本身吞吐有限;
  • 轮询方式读取VALRDY事件,CPU 空转浪费大量时间。

排查步骤

  1. 统计单位时间内生成的随机数字节数,评估实际吞吐;
  2. 对比关闭偏差校正前后的速度差异,确认瓶颈是否在偏差校正;
  3. 检查是否使用中断方式读取VALRDY,避免轮询空转。

解决方案

  • 对于安全敏感场景,保留偏差校正以保证随机性质量;
  • 对于速度敏感场景,可关闭偏差校正(CONFIG寄存器清零);
  • 改用中断或 DMA 方式读取随机数,减少 CPU 等待时间;
  • 若吞吐仍不足,可考虑在系统初始化时预生成一批随机数缓存备用。

6.4 随机数分布不均匀

现象:生成的随机数在统计上出现明显偏向,某些值出现频率过高。

可能原因

  • 未启用偏差校正,内部比特流存在统计偏差;
  • 读取时序错误,导致部分比特丢失;
  • 外部干扰影响热噪声源质量。

排查步骤

  1. 采集大量随机数样本,进行简单的分布统计;
  2. 确认CONFIG寄存器中偏差校正位已正确使能;
  3. 检查 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_STOPINTENCLRCONFIG,确保外设状态干净,提升系统健壮性。

八、参考资料

  • Nordic Semiconductor 官方文档 - RNG 外设说明
  • nRF5 SDK 官方文档与 API 手册
  • nRF52832 数据手册(Product Specification)
  • CSDN 博客:nRF5 系列 RNG 随机数生成器使用详解
  • CSDN 博客:nRF52832 外设驱动开发实战——RNG 篇
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 11:05:15

虚拟机安装 Linux 系统完整图文教程

TL;DR&#xff1a;本文以图文结合的方式&#xff0c;手把手演示如何在虚拟机中安装 Linux 系统。从创建虚拟机、加载系统镜像&#xff0c;到分区配置、用户设置、系统安装与重启登录&#xff0c;再到切换中文与安装串口工具 minicom&#xff0c;全程约 10 分钟即可完成&#xf…

作者头像 李华
网站建设 2026/9/14 11:05:09

STM32 蜂鸣器驱动:CubeMX 配置与代码实现

文章目录1. 引言2. 硬件原理3. CubeMX 引脚配置4. 驱动代码实现4.1 头文件 fmq.h4.2 源文件 fmq.c5. 应用示例5.1 多任务互斥保护6. 常见问题与排查6.1 蜂鸣器不响6.2 声音异常&#xff08;音量小或音调不对&#xff09;6.3 误触发&#xff08;上电即响或异常鸣叫&#xff09;7…

作者头像 李华
网站建设 2026/9/14 11:04:25

SpringBoot2+Vue3校园美食分享平台开发实战:从技术选型到部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华