你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【NUCLEO-U083RC评测】④RNG随机数发生器

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。

一、CUBE配置及函数讲解
工程我们还是用之前生成的基础模板
首先在cube中开启RNG
1.png

然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)

3.png

然后把MSI的频率改成48000(也就是48M
2.png
然后生成代码

4.png

接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png

6.png

HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器


现在简单讲一下HAL库我们会调用的函数

10.png

阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber

通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT

获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber


从参数可以看到,我们每次获取的随机数类型是uint32_t


二、阻塞式获取到随机数及获取上一次得到过的随机数

首先设置一个uint32_t类型的全局变量,用于保存得到的随机数

  1. uint32_t randomData;
复制代码
11.png



初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。

  1. void GenerateRandomNumber_test()
  2. {
  3.   uint32_t lastRandomData;
  4.   printf("GenerateRandomNumber test\r\n");

  5.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);
  6.   printf("GenerateRandomNumber = %04X\r\n", randomData);

  7.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
  8.   printf("lastRandomData = %04X\r\n", lastRandomData);

  9.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);
  10.   printf("GenerateRandomNumber = %04X\r\n", randomData);
  11. }
复制代码


7.png

然后在main中调用

8.png

编译下载,日志如下

9.png

两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功


三、通过中断得到随机数

如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数

首先需要修改一下CUBE,设置RNG的NVIC

12.png

然后点击右上角的生成代码按钮(图片略)

刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数


这两个函数在init时就注册好了

13.png

这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数

14.png

接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)

15.png

在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。

16.png


简单的了解完后,我们开始写代码


先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

17.png

while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印

  1. #if BUTTON_TEST
  2.     /* BUTTON BSP测试 */
  3.     if (UserButtonState == BUTTON_PRESSED)
  4.     {
  5.       UserButtonState = BUTTON_RELEASED;
  6.       // BSP_LED_Toggle(LED_GREEN);
  7.       printf("start GenerateRandomNumber_IT\r\n");
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);
  9.     }
  10. #endif
复制代码
18.png

接下来实现一下之前说的两个虚函数

  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
  2. {
  3.   randomData = random32bit;
  4.   printf("Generate RNG IT = %04X\r\n", randomData);
  5. }

  6. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
  7. {
  8.   printf("Generate RNG IT ERROR\r\n");
  9.   Error_Handler();
  10. }
复制代码
19.png


编译下载,日志如下

20.png



今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好


今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
1 收藏 评论1 发布时间:2024-5-14 00:30

举报

1个回答
STM1024 回答时间:2024-5-19 22:27:49

大佬分析测试的很不错👍,看来我得写点别的了😄

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版