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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。" G* _* A5 Y6 d" ~0 U
/ F* x8 \& `# ?8 g  _  P
一、CUBE配置及函数讲解
8 U$ `; B: S4 ~5 ^; R0 E# X* w; c2 [2 s工程我们还是用之前生成的基础模板8 J  X6 U3 O$ a0 z0 ^8 |
首先在cube中开启RNG6 n+ ~0 W. @4 o7 M8 y$ ?
1.png
0 ?6 F! }( _# S/ J3 T- j( \

; Y, F, \; P/ O) C7 v
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)
, [, H/ P6 z9 l: N
3.png
4 X. H$ p0 c/ v* Z1 Z0 K

4 n- O5 S! T% h) U; s
然后把MSI的频率改成48000(也就是48M)
2.png
- @: D0 l" {% x% {8 t  R' l( `
然后生成代码
: p! F* u# z& ^9 b1 C
4.png 7 m" Z- Y: h  v3 f. R$ C3 @

  n, w9 y5 s& T6 [% d/ }2 [  C0 Q
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png ) |+ ^8 s# v/ t
' O; \9 H/ L) ^/ \3 I
6.png
( E1 P0 Y$ A$ X
) r0 G7 Q6 x" b0 e" j$ [
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器- d) x9 @! [3 x5 ]4 x  L
# P$ A% e2 S6 \3 P# ^3 R4 D

5 w' Z- }3 X# s9 r1 r, w6 g
现在简单讲一下HAL库我们会调用的函数

" G- q# z+ |* \! v2 I# g2 K
10.png
; r4 `3 q2 P8 c
- `5 D/ G  C3 K4 a) a% f1 c/ s$ l
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber
+ \8 r' u" @# u
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT

" Y! N% R; s. m: c4 t6 `5 ~" {# N
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber
/ ~7 j+ F( U) G
( @+ V( f6 U4 q) V& w" v
从参数可以看到,我们每次获取的随机数类型是uint32_t

" l& J( \' c6 ]" ^
4 e7 Z, q- g: \( o
二、阻塞式获取到随机数及获取上一次得到过的随机数
, z$ X4 n2 N" V, \
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数

$ n$ o1 z' D8 t5 E( s& q6 b1 B
  1. uint32_t randomData;
    3 k+ @( G/ l; \5 }
复制代码
11.png
+ `6 E# r0 R+ E0 J8 B0 d6 @5 u5 q
: E+ J% `8 F' ]$ D; W( e

% t1 _) P/ g' G3 T
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。
' H  U+ E4 x6 I9 @
  1. void GenerateRandomNumber_test()/ a, c3 B. E5 _5 J0 T
  2. {
    ' L2 }: s4 Q) |  P
  3.   uint32_t lastRandomData;
    ! W! |6 a* O  `+ u  z8 y
  4.   printf("GenerateRandomNumber test\r\n");0 U2 G& o# y9 u2 f  h
  5. 1 e. C/ }# `( u% ]- q6 |
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);) d) I" O, p6 Y
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);
    9 Y* R' i! g# W: P8 p
  8. 5 w/ |; v' M6 i" @" ?
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
    % S( k" t1 r( V+ J# r
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);
      N' Z# B, u" u- R2 r

  11. 5 D6 m. ~2 B7 o, I- R3 o
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);
    3 H- ?2 y7 k( Z" ~, U* h: y
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);# z; o% a+ N; _/ M% c9 a/ C: g
  14. }
    ' K7 L$ V) [( m+ P! n2 h" Z' {* U) B
复制代码

2 p% K( Z5 r+ r+ P2 ^  q4 q8 u6 _

: ?: ]# J& A7 o  R" @2 l
7.png
' V+ ?. }2 q- C5 ?2 r+ E5 Y& R

) @- `+ Y/ [3 T* z7 Y4 E
然后在main中调用
8 ?6 f. ^3 V) [3 t+ {' P
8.png
1 r% b" u7 f1 y( a# V' Q' v- _

5 \2 K0 m# h; `4 Y" _6 L7 U# {
编译下载,日志如下

2 l+ Z4 k9 R2 i* o0 }; E
9.png 1 ?( `7 g. w. r% J

+ s1 A" f+ y) q' c* j/ j
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功
9 D9 V* g4 Z( }- N) P0 g
3 [: p) B5 x5 j7 L/ F
三、通过中断得到随机数

6 @2 F2 f4 h4 v  M1 {
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数
8 e/ m% z& I& z, a4 n: H4 X( D9 H
首先需要修改一下CUBE,设置RNG的NVIC

# ^) L: l$ A/ l) I
12.png
" z7 V( {# R& F  P, b) [5 n

- P6 I* _+ d: v, @; K
然后点击右上角的生成代码按钮(图片略)

- m! A3 }( v+ i. L3 C3 w! H* v0 j
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数
, ?. @* M1 L4 S- Z3 D+ Z! j

  t' m1 i0 f, I8 x: Q) z
这两个函数在init时就注册好了

0 g0 d7 }! p  W7 o% D. [) y
13.png
3 E# c8 j2 n& J* ~2 q* I

5 A' U! l4 J+ ?4 n( l7 J
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数
! t& C" d2 m/ N: k$ k) w
14.png ( _/ j0 O$ D  D! f$ H( D; \. I9 M3 q

2 B0 G$ y6 i' E1 E6 n/ ?/ ?
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)

$ m3 B2 |' x/ y) [2 R2 x! d
15.png
& d8 `8 a# ?4 Y
* g+ x# v0 U' @) A3 i! W3 P
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。
7 ?# D6 x$ D9 A& F9 [
16.png
  J3 Z% ~; ~$ W% R, P5 j
- U+ W& q; E9 C* ]' P- K) B
* r: o: X6 S) }; V
简单的了解完后,我们开始写代码
8 t' O2 |) A( b8 l
; v; A/ I' u" h+ x0 n5 b  Z
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

% S3 F0 k6 }, Y) Y. K3 z6 a% ^
17.png . E4 X2 q2 p, \) v( T
) F4 D! b- p- C2 v
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印
5 B, }% V. c) D# o& X% x
  1. #if BUTTON_TEST
    ; G- y: a3 t0 `6 d" u, C- Y
  2.     /* BUTTON BSP测试 */
    ' K+ H; Y8 k$ q) g5 [8 w: F+ s
  3.     if (UserButtonState == BUTTON_PRESSED)( r5 c7 r, M4 ^% m% N; g
  4.     {" G" ^4 b, F- y
  5.       UserButtonState = BUTTON_RELEASED;
    9 V  x/ ]( E* m3 B+ Q
  6.       // BSP_LED_Toggle(LED_GREEN);+ i/ M# l" F3 K0 h9 s5 E
  7.       printf("start GenerateRandomNumber_IT\r\n");: O$ m" i. [, z1 T
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);
    , E/ L* B0 }0 J& W* V# t+ X6 }8 {
  9.     }
    / P8 V! b' o& B; d
  10. #endif
复制代码
18.png

, b% Y6 M6 J3 s, k
接下来实现一下之前说的两个虚函数

; S; ~# b2 {. W: k+ H) t& x( b3 a
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)9 j- P& C( {% p, o
  2. {
    5 U7 G: _  I% S8 L  C8 C& B
  3.   randomData = random32bit;; U' Q5 @9 w' R. f7 \! V: s
  4.   printf("Generate RNG IT = %04X\r\n", randomData);- I' C% C1 L, V& _
  5. }
    0 a# c1 y% \: P9 r

  6. : x: [8 @- j7 S& r/ u
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)
    / |$ q/ K& U% h  d5 x
  8. {
    2 D/ h+ n: M, W; t- a6 D+ E0 W6 G0 F
  9.   printf("Generate RNG IT ERROR\r\n");
    2 @3 J  O$ @1 B4 V
  10.   Error_Handler();- f$ O- C5 U4 A$ C
  11. }% A( ]2 `, n7 e, R
复制代码
19.png
: u* i. O! ?# I- m2 s0 n$ \
! U0 u" k) c) w5 M
编译下载,日志如下
; Q* q3 M- e1 s2 j- e
20.png
0 \9 k# b9 d% s8 g; [) ~
* V- l, U, L. P1 S

0 V- s5 {. A; Q4 y" u0 }: d8 k7 m5 j( a: ], e( j/ d8 h
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好

6 ?& ~  U3 i$ I0 _9 P/ \* E# `7 H* S. z7 O
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
0 s2 r  x, @/ m% [) v' o
赞 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 手机版