请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。& r- k& [' |4 F, R7 W' @& B: Y5 A
: s8 {8 V; \( f4 }$ Q
一、CUBE配置及函数讲解
, G; H! C. [1 `& y# V( c工程我们还是用之前生成的基础模板* v: y. H" o2 k1 s" r& a) Z
首先在cube中开启RNG' ^% M6 r! F, H+ z9 v+ m
1.png : V+ b( J/ f% y6 w% W' a2 l
1 X7 A& E; S9 l' g/ G# f6 U2 j" }
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)
: Q( ~) g' q: E) T; {
3.png
0 S0 W, W/ C4 T# U) w* k5 n

# ]: \! e( F6 ^3 n
然后把MSI的频率改成48000(也就是48M
2.png 6 N, k8 z) a" z: G6 [; y0 C
然后生成代码

; V  Z' X) P8 j! ^. k  q, h2 d- h
4.png
6 J. w8 P1 Y" a9 j9 [( K. V
0 q' Y0 K' {: |, v% G0 I
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png
( N+ l9 }4 h  i
9 R3 X' }+ J: p5 Y$ y4 H( \6 R
6.png ; E5 R9 E& r& M  h* z: t$ L

9 O9 K! T. D9 g/ N, X/ g+ c6 X
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器
1 O: f  M9 N5 c. M

* i: x$ d7 }8 i. V
" r; g. _) C5 R: G; w
现在简单讲一下HAL库我们会调用的函数

! @0 e, y) B  `3 t. ]! p
10.png   ]+ V( d. P; s* F3 M
' f8 c7 Q: F" \
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber
  f" ]6 }  E/ P0 T- G+ t
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT
) U, O6 ^( \2 f) t* D
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber

  ?- T$ n4 G8 w5 J  C4 r5 l
/ L; w/ }* K5 _9 i) y( C
从参数可以看到,我们每次获取的随机数类型是uint32_t
, b) z1 s! I( O8 g' w

! |/ x- m. c( `$ t! u
二、阻塞式获取到随机数及获取上一次得到过的随机数

6 H" P  o+ H  l' b& F2 [* a
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数

3 q; H9 a% b" |( s' \
  1. uint32_t randomData;
    8 r2 _6 _3 F: v9 z! r% O) ~
复制代码
11.png

1 E& P5 q7 f! N) {
+ }- |8 c: o8 f& e* x7 J

/ e& A2 u) U+ E, L, F3 F3 p
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。
+ `8 c5 B- Q/ ?/ @
  1. void GenerateRandomNumber_test()
    0 Y4 q: [2 u* |0 b
  2. {2 U# [% L' R: G# i9 u
  3.   uint32_t lastRandomData;
    ( N1 z, U1 |- k$ l
  4.   printf("GenerateRandomNumber test\r\n");
    4 G) u, J+ _$ t

  5. , X' m+ ~4 S- E) d) i6 M
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);7 _$ @/ j6 o+ F9 r( ~
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);& @, @' ^; D7 U) F1 {

  8. & E+ G) E& F8 v& Z' ?
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
    - M/ g$ K$ K2 W; q: D' I8 d5 U( R
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);
    3 u. g" i* t) C' V- o+ a; g

  11. $ x7 \+ w- Y! G6 P9 q8 x) Y9 j
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);/ }0 G! A% K* Z! V" C& s$ z
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);/ ?% B. p- Y) o- Z
  14. }
    % i2 w) B' ~" ]
复制代码
5 i" l4 P# m5 l) ^' D3 j

! e0 }+ V# V) ?# A
7.png   c3 O4 j8 A" q/ u+ @

( t, ^2 Q" Q: m  p2 b  I
然后在main中调用
% Y6 ~) g: H3 A9 [0 C* }# x
8.png
& g* @! A0 }2 c' u+ [

+ F3 h  _3 w: u+ P
编译下载,日志如下
, @' M0 t  q8 g2 p7 d5 r) {
9.png
1 g. f# f/ G# r& h( D9 P' k2 e

/ N' i: H, d! A
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功
. d" L% L9 o; q( w6 n

# _3 ~0 D7 N8 R% i, V/ R! r
三、通过中断得到随机数

7 l! G+ B/ y  p- T1 b. ~0 O/ R
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数
2 c8 y. p1 K" a5 X+ x! Z# J6 [
首先需要修改一下CUBE,设置RNG的NVIC
1 W- w6 h) h# ^
12.png 2 q3 a1 t( g" e' H$ d/ U

0 Z0 ?- j  X0 ?2 C3 c3 a! o
然后点击右上角的生成代码按钮(图片略)
/ ^1 P* p5 Q. v: o! v
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数
5 ~: S* ^0 E. r9 v- X: |

: w: ]1 x3 e! `) j( h: M, ^
这两个函数在init时就注册好了

/ w! z1 R- I) w4 k3 b$ R
13.png
. I; O3 w+ F4 W' C" _
  X$ j1 w6 u- g$ R4 I: x) |
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数
+ x  F/ E. h& J$ t% ?9 X( l
14.png ) V( \' R. p, g- m9 t, @( W
9 w- ]" N# j  p1 Y
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)
- w1 I8 r3 Q7 m% d" ^- B; ^" U
15.png 1 v7 U9 n+ c2 D' @

$ s+ N' C, [$ s1 V
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。

$ q4 z9 ~, N( B) N# A
16.png ! q5 [  V, g! N8 X) H4 U+ e

/ f; v! [% V8 R4 O4 V4 q# q
: O0 ?  s0 E+ y( z/ w2 ^
简单的了解完后,我们开始写代码
8 O( g+ y1 g8 Y& e& E6 J6 S
1 h# z: R% V. r& L
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT
% u3 _+ X. o+ J
17.png
1 B9 l" x6 B: m' D! [0 {/ D: K
* O/ E/ {) I6 u3 h. z
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印
5 ]  V2 o: V( i% }. `; Y; Q
  1. #if BUTTON_TEST/ x, a. i* Q3 M
  2.     /* BUTTON BSP测试 */, c+ O0 X3 y$ Y9 o7 R% m/ D
  3.     if (UserButtonState == BUTTON_PRESSED)
    . T5 K- e  v  v  a0 Q: b2 ?7 K
  4.     {
    # I; ]3 H( u3 ^$ ~% D- P
  5.       UserButtonState = BUTTON_RELEASED;
    " S: q, k! }# ?6 e
  6.       // BSP_LED_Toggle(LED_GREEN);
    - ~# ^* L$ N6 k9 ^* D! P! y
  7.       printf("start GenerateRandomNumber_IT\r\n");
    7 t3 p6 [; Z6 |/ X! E
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);
    - y& ?8 H' Y+ V/ E0 ?& F$ |
  9.     }
    $ h3 }+ p, F  W/ Z: b# L5 i
  10. #endif
复制代码
18.png
3 E! z. ?+ N$ U
接下来实现一下之前说的两个虚函数
  [  o! d( B- J: K1 S
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
    7 o3 l6 e8 `& b6 C! V5 U0 ?3 U
  2. {
    - a8 G5 ]( G- O" i  l
  3.   randomData = random32bit;
    : K2 k7 ~1 y! z7 V
  4.   printf("Generate RNG IT = %04X\r\n", randomData);; B$ ?8 i0 L4 s. ~- T
  5. }
    2 o+ ]! X6 d5 i

  6. 3 s+ J$ Q% @$ F  A6 d: j4 a: t
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng). }2 d) t: v6 B; ]
  8. {- m6 H- D8 F& F0 ~& r
  9.   printf("Generate RNG IT ERROR\r\n");
    $ B" U. G2 f* `$ Q
  10.   Error_Handler();
    , d/ P. I4 ]: y  B; [
  11. }
    8 s* v! |0 M# z
复制代码
19.png

; I& q9 g( y, p4 \. U

4 j% k" H2 J# e5 M
编译下载,日志如下
+ n& X) x' L. u$ j5 [6 \
20.png
2 v& U. k( h' u' q; y; I/ n7 z3 K9 H

# ~$ n# G3 z" c; t+ v4 ]% M
* v- }+ e& F5 q' X, J  w3 e0 x/ X4 x# i& t
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好
: c4 _0 |/ r$ K/ y. f' L

, Y9 g2 K, w! W7 `' t1 _
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
. n3 D& ^- L* J! B. P; U! }9 d
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 手机版