[STM32F4] STM32F4_随机数发生器(RNG)

[复制链接]
1079|20
 楼主| 无法去污粉 发表于 2023-12-27 12:45 | 显示全部楼层 |阅读模式
1. 随机数发生器RNG是什么
        RNG全称Random number generator;RNG处理器是一个以连续模拟噪音为基础的随机数发生器,在主机读数时提供一个32位的随机数。

        RNG的主要特性有:提供由模拟量发生器产生的32位随机数,两个连续随机数的间隔为40个PLL48CLK时钟信号周期

                                         通过监视RNG熵来标识异常行为(产生稳定值,或产生稳定的值序列)

                                         可被禁止以降低功效

2. RNG随机发生器框图

89977658bac00449fb.png

 楼主| 无法去污粉 发表于 2023-12-27 12:46 | 显示全部楼层
        首先模拟种子源源不断的生成随机数据给馈送线性反馈移位寄存器LFSR,当LFSR存储满之后,会一并给数据寄存器RNG_DR;在模拟种子生成随机数据的过程中,会有时钟检查器和故障检测器时刻检测产生的随机数是否正确,并通过状态寄存器RNG_SR相关位显示,随机数发生器通过RNG_CLK时钟支持;

RNG随机数发生器采用模拟电路实现。此电路产生馈入线性反馈移位寄存器(RNG_LFSR)的种子,用于生成32位随机数。

该模拟电路由几个环形振荡器组成,振荡器的输出进行异或运算以产生种子。RNG_LFSR由专用时钟(PLL48CLK)按恒定频率提供时钟信息,因此随机数的质量和HCLK频率无关。当将大量种子引入RNG_LFSR后,RNG_LFSR的内容会传给数据寄存器(RNG_DR)。

系统会监视模拟种子和专用时钟PLL48CLK。状态位(RNG_SR寄存器中)指示何时在种子上出现异常序列,或指示何时PLL48LCK时钟频率过低。检测到错误时生成中断。
 楼主| 无法去污粉 发表于 2023-12-27 12:46 | 显示全部楼层
3. 运行RNG
想要运行随机数发生器RNG,需要:

1. 如果需要随机数发生器RNG,进行中断(将RNG_CR控制寄存器的IE位置1)。准备好随机数时或者出现错误时生成中断。
 楼主| 无法去污粉 发表于 2023-12-27 12:46 | 显示全部楼层
2. 通过将RNG_CR控制寄存器中的RNGEN位置1使能随机数产生。这会激活模拟部分、RNG_LFSR和错误检测器。
 楼主| 无法去污粉 发表于 2023-12-27 12:46 | 显示全部楼层
3. 每次中断时,检查确认未出现错误(RNG_SR寄存器中的SEIS和CEIS位应为0),并且随机数已准备就绪(RNG_SR寄存器中的DRDY位为1)。然后即可读取RNG_DR寄存器中的内容。
 楼主| 无法去污粉 发表于 2023-12-27 12:46 | 显示全部楼层
这里检查未出现错误时,RNG_SR寄存器的SEIS和CEIS位为0;如果SEIS和CEIS其中之一为1,则表示随机数发生器出现错误;

①:如果CEIS位的值为1,则表示时钟出现了错误

出现时钟错误时,RNG无法再产生随机数,这时的PLL48CLK时钟已经不正确了。检查时钟控制器是否正常配置,是否可提供RNG时钟,然后将CEIS位清零。当CECS位为0时,RNG可以正常工作。时钟错误对产生的上一个随机数没有影响,因此RNG_DR数据寄存器的内容可以使用。
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
②:如果SEIS位的值为1,则表示种子出现了错误

出现种子错误时,只要SECS位为1,就会中断随机数产生。如果RNG_DR寄存器中有可用随机数,不能使用该随机数,因为它可能没有足够的熵。
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
总结:出现错误时,应将SEIS位清零,然后将RNGEN位清零并置1,以便重新初始化和重新启动RNG。
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
按照FIPS PUB(联邦信息处理标准出版物)140-2的要求,将RNGEN位置1后产生的第一个随机数不应使用,应保存起来,与产生的下一个随机数进行比较。随后产生的每一个随机数都需要与产生的上一个随机数进行比较。如果任何一对进行比较的随机数数字相等,则表示连续随机数发生器测试失败。
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
4. RNG寄存器
4.1 RNG控制寄存器:RNG_CR
RNG控制寄存器:RNG_CR(RNG control register) 8143658bac644f5f8.png
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
位31:4  保留,必须保持复位值

位3   IE:中断使能(Interrupt enable)

                0:禁止RNG中断

                1:使能RNG中断。只要RNG_SR寄存器中DRDY=1或SEIS=1或CEIS=1,就会挂起中断。

位2   RNGEN:随机数发生器使能(Random number generator enable)

                0:禁止随机数发生器

                1:使能随机数发生器

位1:0   保留,必须保持复位值
 楼主| 无法去污粉 发表于 2023-12-27 12:47 | 显示全部楼层
4.2 RNG状态寄存器:RNG_SR
RNG状态寄存器:RNG_SR(RNG status register)
38023658bac7c0ba29.png
 楼主| 无法去污粉 发表于 2023-12-27 12:48 | 显示全部楼层
位31:3   保留,必须保持复位值

位6   SEIS:种子错误中断状态(Seed error interrupt status)

                0:未检测到错误序列

                1:检测到以下错误序列之一:

                        超过64个连续位具有相同值

                        超过32个连续交替的0和1        

                如果RNG_CR寄存器中IE=1,则会挂起中断

位5   CEIS:时钟错误中断状态(Clock error interrupt status)

        此位与CECS同时设置,通过向其写入0来清零。

                0:正确检测到PLL48CLK时钟

                1:未正确检测到PLL48LCK时钟

        如果RNG_CR寄存器中IE=1,则会挂起中断。

位 2  SECS:种子错误当前状态 (Seed error current status)

                0:目前未检测到错误序列。如果 SEIS 位置 1,则意味着已检测到错误序列并已恢复正常。

                1:检测到以下错误序列之一:

                        —超过 64 个连续位具有相同值(0 或 1)

                        —超过 32 个连续交替的 0 和 1 (0101010101...01)

位 1  CECS:时钟错误当前状态 (Clock error current status)

                0:正确检测到 PLL48CLK 时钟。如果 CEIS 位置 1,则意味着已检测到时钟错误并已恢复正常。

                1:未正确检测到 PLL48CLK 时钟

位 0  DRDY:数据就绪 (Data ready)

                0:RNG_DR 寄存器尚未有效,无可用随机数据

                1:RNG_DR 寄存器包含有效随机数据   注意:如果 RNG_CR 寄存器中 IE = 1,则会挂起中断。读取 RNG_DR 寄存器后,此位恢复到 0,直到计算出新的有效值。
 楼主| 无法去污粉 发表于 2023-12-27 12:48 | 显示全部楼层
4.3 RNG数据寄存器:RNG_DR
RNG数据寄存器:RNG_DR(RNG data register)

RNG_DR寄存器是只读寄存器,在读取时提供32位随机数值。读取后,此寄存器在最多40个PLL48CLK时钟周期后,提供新的随机数值。在读取RNDATA值之前,软件必须检查DRDY位是否已经置1。 18855658bac9551a3d.png
 楼主| 无法去污粉 发表于 2023-12-27 12:48 | 显示全部楼层
5. 库函数配置随机数发生器
1. 使能随机数发生器时钟

随机数发生器时钟来自于PLL48LCK,通过AHB2ENR寄存器使能。

RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);      //开启RNG时钟
 楼主| 无法去污粉 发表于 2023-12-27 12:48 | 显示全部楼层
2. 使能随机发生器

使能随机发生器需要设置RNG_CR控制寄存器的最低位为1,使能随机数发生器。(这里注意:如果需要设置中断服务函数,那么还需要使能RNG中断)

RNG_Cmd(ENABLE);      //使能RNG随机数发生器
 楼主| 无法去污粉 发表于 2023-12-27 12:52 | 显示全部楼层
3. 判断DRDY位,读取随机数值

DRDY位是状态寄存器的最低位,是显示数据是否就绪的状态位;当该位为0时,表示数据寄存器尚未有效,无可用随机数据。当该位为1时,表示数据寄存器已经包含有效随机的数据。

通过以上的分析,我们明确了在读取随机数值之前,必须先判断状态寄存器的最低位DRDY是否为1,如果该位为1,则可以读取数据寄存器的随机数值;如果该位不为1,则需要等待。

FlagStatus RNG_GetFlagStatus(uint8_t RNG_FLAG);   //获取随机数发生器状态函数

while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET);    //判断入口参数是否有效,若无效,等待就绪

uint32_t RNG_GetRandomNumber(void);    //当判断入口参数有效以后,读取随机数发生器产生随机数
 楼主| 无法去污粉 发表于 2023-12-27 12:52 | 显示全部楼层
6. 实验程序
STM32F4随机数的实验现象是:通过KEY0获取随机数,并将获取到的随机数显示在LCD上,通过DS0指示程序运行状态。
 楼主| 无法去污粉 发表于 2023-12-27 12:53 | 显示全部楼层
6.1 main.c

  1. #include "stm32f4xx.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "LED.h"
  5. #include "lcd.h"
  6. #include "usmart.h"
  7. #include "Key.h"
  8. #include "RNG.h"

  9. //LCD状态设置函数
  10. void led_set(u8 sta)//只要工程目录下有usmart调试函数,主函数就必须调用这两个函数
  11. {
  12.         LED1=sta;
  13. }
  14. //函数参数调用测试函数
  15. void test_fun(void(*ledset)(u8),u8 sta)
  16. {
  17.         led_set(sta);
  18. }
  19. int main(void)
  20. {
  21.         u32 random;
  22.         u8 t=0;
  23.         delay_init(168);
  24.         uart_init(115200);
  25.         LED_Init();
  26.         Key_Init();
  27.         LCD_Init();
  28.         POINT_COLOR=RED;
  29.         LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
  30.         LCD_ShowString(30,70,200,16,16,"RNG Test");
  31.         LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
  32.         LCD_ShowString(30,110,200,16,16,"2023/20/23");
  33.         while(RNG_Init())//因为RNG存在一个等待状态位是否有效的过程,所以只要初始化RNG成功,也就意味着状态位有效,可以执行下述读取随机数的程序
  34.         //因为初始化RNG随机数发生器返回0表示初始化成功,一旦初始化返回值为1,则进入该while循环中,打印错误信息
  35.         {
  36.                 LCD_ShowString(30,130,200,16,16,"RNG Error!");
  37.                 delay_ms(200);
  38.                 LCD_ShowString(30,130,200,16,16,"RNG Trying……");
  39.         }
  40.         LCD_ShowString(30,130,200,16,16,"RNG Ready!  ");
  41.         LCD_ShowString(30,150,200,16,16,"KEY0:Get Random Num");
  42.         LCD_ShowString(30,180,200,16,16,"Random Num:");
  43.         LCD_ShowString(30,210,200,16,16,"Random Num[0-9]:");
  44.         POINT_COLOR=BLUE;
  45.         while(1)
  46.         {
  47.                 delay_ms(10);
  48.                 if(KEY0==0)
  49.                 {
  50.                         random=RNG_GetRandomNum();//获取随机数
  51.                         LCD_ShowNum(30+8*11,180,random,10,16);//显示随机数
  52.                         //30+8*11的意思是x起始坐标为30,LCD屏是按照字节来存放的,1位8个字节,Random Num占11位
  53.                 }
  54.                 if(t%20==0)//t是200ms的整数倍
  55.                 {
  56.                         LED0=!LED0;//每200ms,LED0翻转一次
  57.                         random=RNG_GetRandomRange(0,9);//获取0-9之间的随机数
  58.                         LCD_ShowNum(30+8*16,210,random,1,16);//显示范围内的随机数
  59.                 }
  60.                 delay_ms(10);
  61.                 t++;
  62.         }
  63. }
 楼主| 无法去污粉 发表于 2023-12-27 12:53 | 显示全部楼层
6.2 RNG.c
  1. #include "stm32f4xx.h"                 
  2. #include "RNG.h"
  3. #include "delay.h"

  4. //RNG初始化
  5. //返回值0成功;返回值1失败
  6. u8 RNG_Init(void)
  7. {
  8.         u16 retry=0;
  9.         RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG,ENABLE);//使能RNG时钟
  10.         RNG_Cmd(ENABLE);//使能RNG随机数发生器
  11.        
  12.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET&&retry<10000)
  13.         //判断入口参数是否有效,因为状态寄存器的最低位DRDY为1时,随机数才会有效
  14.         //所以直到状态位为1时才会离开该语句,该语句判断状态位为0时,会一直在此等待。
  15.         {
  16.                 retry++;
  17.                 delay_us(100);
  18.         }
  19.         if(retry>=10000)   //随机数发生器工作不正常
  20.                 return 1;
  21.         return 0;
  22. }
  23. //获取随机数
  24. //返回值:获取得到的随机数
  25. u32 RNG_GetRandomNum(void)
  26. {
  27.         while(RNG_GetFlagStatus(RNG_FLAG_DRDY)==RESET); //等待随机数就绪
  28.         return RNG_GetRandomNumber();
  29. }
  30. //生成[min,max]范围的随机数
  31. int RNG_GetRandomRange(int min,int max)
  32. {
  33.         return RNG_GetRandomNum()%(max-min+1)+min;
  34. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

57

主题

808

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部