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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。
; G. j2 V# ~" W* u% g* A' Y+ L* [; I$ X, Z" G' s
一、CUBE配置及函数讲解
* s( O% m0 d) C" R工程我们还是用之前生成的基础模板' v) d: N, i: l3 |) ?
首先在cube中开启RNG
; s; F% K! R2 ~4 o' Q8 W: X7 U
1.png
3 C8 W% y' V1 p
6 P* x% c* {$ I5 R- J  m  i% i6 C  R
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)
# f& |- D" y# u( t: j4 R
3.png 7 U9 k, e) L6 v4 U' }3 s5 [3 ^( c

- t0 e) ?9 [9 I  A9 M* ?- V
然后把MSI的频率改成48000(也就是48M)
2.png
6 T  c3 D6 H& y. f5 \1 A
然后生成代码

- C0 e/ v* s2 R( p
4.png . s6 B" K5 ]* b4 B9 g

% l" @* ^; q# s7 \7 ~& `
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png ; ~5 x0 U6 z4 ^; j0 Y6 h
1 {8 I1 L/ T9 Y+ Y7 a) v
6.png
7 ]. |' A, E. @% T4 E3 P

7 X5 }+ r5 c9 n; k# w; Q$ J6 T
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器% H+ w. H2 `; B$ D" l8 W
2 H- q5 n3 m. s1 a% X

3 X0 x+ D1 B: S4 |8 m. Q/ d
现在简单讲一下HAL库我们会调用的函数
+ {1 l; g; l/ m* m% ^6 \
10.png
# `* o) J( U" N% P+ m. @4 \3 f
- E- [1 n- u8 e+ E( x1 f
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber
; N7 Y& q; h" J7 }& C7 D% n
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT
: R2 \1 x' @3 A. ^
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber

1 e2 h1 P. z3 d! _  U6 g' T% N4 X5 B" t9 e  p3 k0 s
从参数可以看到,我们每次获取的随机数类型是uint32_t

( w6 v* _# L+ }. w% K' f  v. x+ ~* r5 L& G. D  @
二、阻塞式获取到随机数及获取上一次得到过的随机数
0 d' ]5 D4 n4 Y* J& ?# C* i, g
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数

( j7 f* p) Z8 c9 w) [, u
  1. uint32_t randomData;0 g3 b8 @( p4 D6 N
复制代码
11.png

# X; g) T- L# C; a' v9 r
; B+ K1 h5 B+ G6 I: C

- S/ P7 i( ~: n
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。
* V7 E- D1 e6 C( c- y
  1. void GenerateRandomNumber_test()
    " a4 {( S) L+ J1 W3 F
  2. {& V* _) t+ m  l9 B
  3.   uint32_t lastRandomData;! a7 P5 U0 Z% j6 `* x1 L3 a; y
  4.   printf("GenerateRandomNumber test\r\n");8 {5 b! C0 {* O. c0 A' ]$ K
  5. 7 C+ E5 J$ e; T1 v
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);  D7 Q$ p$ D7 X
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);8 J0 L! u1 ?) m7 `& |) m
  8. ( s: m$ q' R* e& G/ M. L
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
    9 ?. Y+ Y6 r! |! F2 \- X
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);
    ; m& d! F% {1 l; O! }+ G1 Z

  11. 1 f$ V. j7 W) U- M& n7 {
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);6 A) P+ e* x4 K; s% I: c3 {
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);
    + R* U5 n0 I* m$ h* X8 A9 W( o5 V4 H( f
  14. }
    ' C& x' \" T" S
复制代码

* x2 \4 A8 b4 g+ k( A4 I% F8 V7 n3 n
4 `+ s+ {. z. [) V1 n
7.png ; M9 }: B, S" M) r, K  Q. ]
* u, w# s% c' B6 @6 T0 x
然后在main中调用
8 U: W$ f% f# c  [+ |$ Z
8.png
% C9 X2 _) u' M) q
0 N4 L" [; X5 O9 `( W/ a4 C! g
编译下载,日志如下

  S: d. l$ y! r) G) [, D
9.png
% I$ l: L5 X: I# }' e

& F% t8 t' R  N! t' t/ Z+ \- D
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功

6 k# R8 |4 d! S0 D
: m/ s$ W* v& b9 \/ {
三、通过中断得到随机数

2 J$ p9 M( y' e7 w: }. E4 C/ ^4 x0 K0 X
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数
' \# v+ W% @5 l* y
首先需要修改一下CUBE,设置RNG的NVIC
7 Q, T- B1 E; {9 p
12.png
2 K- F$ |; p' e3 n9 s
+ T/ ~5 e) \7 o$ A' G7 h+ m
然后点击右上角的生成代码按钮(图片略)
, U) E* v0 a% h( J7 a0 Y
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数

* m! w  x3 j4 h$ I2 N% w3 k
9 B5 R! l9 I9 [6 e7 w: ?9 t' b
这两个函数在init时就注册好了

6 l. Q2 U/ r. \
13.png
! n+ r6 E& C0 v1 ]9 }6 U6 }) }9 f
+ a4 _8 H! j! i/ g1 X) [
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数

' p3 q: y8 q3 k' E; a) }- L
14.png
( ?, k0 {7 K  R& L
3 k1 @& k9 A+ \; b, p) M4 W; R
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)

2 ^6 K/ b: r$ O: @  W% x2 n" f
15.png
+ {  ~  L/ @; g9 P" ~

% X. h) O) k) v' F$ `
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。

; C& a: ^- M! K+ i/ K1 @5 U
16.png
5 x$ ^( z+ ?/ p8 G) ?# ^8 m  f
7 r0 F) t* T. w
6 h  j! U" I( I, y- c! @
简单的了解完后,我们开始写代码

% ^( ^9 H& I& A/ h( H2 g1 v" w- ?1 b* B. e6 s( ]' W, @
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

- Q4 Y4 R; w( T0 V; _9 _) N
17.png : X* @1 t* J0 n, l! u; Y

  I7 D# s$ d% O8 Q* v3 Y2 g. Z
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印
+ m- |' w6 Y0 \' k/ a* P: H" U
  1. #if BUTTON_TEST
    , F4 q$ Y3 f. V( N( G$ i% Q
  2.     /* BUTTON BSP测试 */+ _, U$ _- A( U  g" ]. N- ^+ I) V  g
  3.     if (UserButtonState == BUTTON_PRESSED)0 s4 \8 \: h1 d! ?! n3 p( w4 ~
  4.     {* c4 s) Z5 F- {9 ~1 T# [8 t1 u6 t
  5.       UserButtonState = BUTTON_RELEASED;( f: c' ]+ Z6 A0 j2 _7 k6 i
  6.       // BSP_LED_Toggle(LED_GREEN);' n2 Q$ X7 @! f! F9 J% O  j8 c
  7.       printf("start GenerateRandomNumber_IT\r\n");
    1 r4 |( r# g  ~9 _0 a0 r+ F
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);: r6 N2 a& k+ X
  9.     }: y; f9 i' w' ~" p
  10. #endif
复制代码
18.png
9 h* n% }& a" k! p2 v9 |
接下来实现一下之前说的两个虚函数

7 W' D' F0 ~: l( b5 D
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)# g6 `$ T2 K  }
  2. {
    2 t9 j; [" \" Y
  3.   randomData = random32bit;
    6 P" C5 X( a- P# b! ?+ A
  4.   printf("Generate RNG IT = %04X\r\n", randomData);
    7 {$ f  z% D" b( \2 \
  5. }
    ' A8 `' a0 v5 m8 X7 k
  6. / g8 F/ l3 J& J! f9 L% ]
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
    - p3 C* Z- z7 c+ P
  8. {
    ; c) s2 R3 ]; i% Y8 _
  9.   printf("Generate RNG IT ERROR\r\n");
    5 N9 j/ D: @  x- b; P1 @
  10.   Error_Handler();
    * T5 u' B5 F% g) F. |1 D
  11. }
    + o$ b! `. x' }
复制代码
19.png

# C; W' V1 D' Z

' ^0 d/ U8 u1 `$ Q* o  r" a5 o2 x
编译下载,日志如下

; r" F$ `( ~( h- D  a
20.png   b1 G, o3 u2 V4 f# ]

3 G4 V. I  S( N0 d! x9 {/ _$ M. j+ T
/ d1 u- p6 v' Y: B4 ^; `
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好
- m. h* s* [' z4 J3 R. t

# v0 X9 U$ s, ~) k
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
: j0 Y+ r0 t- b* k; [
赞 1 收藏 评论1 发布时间:2024-5-14 00:30

举报

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

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

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版