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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。
* @' Y8 |( U9 l, d1 C6 l: p* K5 X+ ~! L7 P- P# P
一、CUBE配置及函数讲解4 N4 P2 i0 k2 M; f" ^, k" c
工程我们还是用之前生成的基础模板
, u# s3 a" j  j: O# n首先在cube中开启RNG
7 z$ l/ r% M; M% @/ _9 q" s
1.png
. V' @0 F/ B; q4 `: w" \1 |
$ S% q0 L5 ^; D6 A
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)

, L# t/ q, A( M: u0 v) C; H& K
3.png 1 b- U; x, k+ J

3 s% C8 z& S: U& H% l
然后把MSI的频率改成48000(也就是48M)
2.png
5 N. Y% w" J# y
然后生成代码
4 _. F0 Y, ]/ J; e6 W, F; N
4.png + E& ^2 M8 e% k/ J
3 u8 \  J* g2 V+ z3 W( ]2 j: x/ i  G
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png
6 j9 L, i( `) k6 y9 |* t9 A

3 `* k/ n2 t! A; _( H' I6 H
6.png
! v6 R" I' [6 Z! u/ _' e/ a5 R

4 B. C0 _$ K3 J; ?+ o  Q) M& W6 I
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器2 h- S( S, S) ~

' Q* i( ?: t9 K% f! m9 x/ Y; F1 o! E* f% O8 t) h4 _0 S1 r8 s
现在简单讲一下HAL库我们会调用的函数

. {  _# h1 K0 N  Z) Z" b
10.png
) t$ r3 g/ X5 F

* j' f3 F6 h. }$ E( G
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber
" l( F; b+ A3 a9 C8 a: W: F% K
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT

7 m7 {/ Z7 P' u8 K% V& F; r: m. D
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber

/ b" d/ I: A; @6 N' O
2 J6 c' N) G& q/ V6 {
从参数可以看到,我们每次获取的随机数类型是uint32_t

2 t' Z! {! L0 y0 |1 L. [9 a( J7 ^6 Z/ t3 r: u! y  J& Y
二、阻塞式获取到随机数及获取上一次得到过的随机数
: }5 L( V% Q% {1 w, @; r: n
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数
) Y# E% u) y9 \# N9 U
  1. uint32_t randomData;
    , ^; G% ^) C2 z
复制代码
11.png

0 n. m# K# B; \* d- q- u& F$ Q

/ t8 S) P) ]( ?: Y9 s2 i  F
  k9 Q0 Z+ o; g- k& Y: G4 D
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。

& ?' @% Y) R! x2 j! E5 N
  1. void GenerateRandomNumber_test()+ W& f" U$ t0 g. @
  2. {
    ) Q! y! h0 {0 B, X
  3.   uint32_t lastRandomData;
      f4 ~. D* p8 {& q
  4.   printf("GenerateRandomNumber test\r\n");
      P7 u4 ^8 f: V9 x8 M
  5. + t1 ]  C" t0 J( C
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);* ]: ?3 u- n( `* I/ e
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);
    ! k& ?" [" X& H

  8. * v: }% I9 F  P0 [& e
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);  a1 s- ~5 W% M5 O" n0 P
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);& |, _; R- E; n& w9 p: Y# L- U# i
  11. 5 O4 B  f5 d7 m
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);% R( @* k% t' m9 @7 w/ H  O5 m; g# ?
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);1 x( J- e9 l! `( r. h
  14. }/ s* |: W! i5 m# w& ~" [
复制代码

7 p. X0 M/ _' Q  O/ z; l  W# w

1 f4 T1 ^2 p% v& n& }
7.png
) x1 j* _$ y9 O7 m

1 |! o# f5 g0 B7 R6 F+ f6 u) V
然后在main中调用
5 a+ w8 O# k) n( T# x  h4 Y5 ?
8.png 5 E; C3 W5 O& D: x* f0 D& o
8 G) _$ y+ I  X- C5 }6 f2 l; N8 ~" x
编译下载,日志如下
3 W! T: H8 j9 c/ ]+ p
9.png 0 z9 e& ]# o- `2 k0 I  [7 z

/ O6 V4 L) ]9 |2 Q* F
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功

3 w7 ^3 {# m, `% w5 f: i! l. U- ^1 s1 j0 D7 o1 _* J: v
三、通过中断得到随机数

' y5 N. q  G0 C/ T& X2 c* G
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数

7 U" A+ X  I* K8 P7 K+ \' `' ]/ l
首先需要修改一下CUBE,设置RNG的NVIC
* W5 U! X  N, u. o
12.png 4 b, X. [: g6 R0 N* z
7 P1 b+ L4 u9 |+ V% C
然后点击右上角的生成代码按钮(图片略)

$ M  p% O7 ?: t
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数
, `! K* `# g& p5 m8 f. s

6 i2 J8 |/ e( J& J
这两个函数在init时就注册好了

& \' m* \, r: H* |% J5 B3 x0 H/ h
13.png
& i/ X% c8 r0 I

/ f8 T: ]8 n0 j( x
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数

0 T2 F  I7 c2 e7 t! z2 Q# W
14.png
0 d& A" U1 o% f/ o' U

+ ~$ o0 Z& A- K5 R3 g
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)
1 `# b* i  V" K6 s0 l0 g
15.png % K1 }4 @: o2 `  E2 j) y

! p% ?$ n4 v: b8 C; `$ T0 G5 w
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。
0 s$ w- g' t4 L& ?2 x$ }
16.png " Q1 j  O4 @% o8 Y. I# `

  U( a9 _  m, F  p
( j$ r4 y6 M; k1 v
简单的了解完后,我们开始写代码
* @# Q- Y) t0 X( |0 H
) w" c9 m# V6 u
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

! n( K8 q5 C* R- i7 o1 v, V
17.png # ^! t/ W5 Q$ F6 Y6 k& A" Y) s
  d! R+ g0 k1 V2 E7 F$ y
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印
9 j% M' @  O! Q( B3 j) g+ c
  1. #if BUTTON_TEST
    : K7 q8 |( k7 E
  2.     /* BUTTON BSP测试 */
    # q  |' H7 g" |, \& _$ y
  3.     if (UserButtonState == BUTTON_PRESSED)
    & R4 {7 n7 r; |1 S# g- K
  4.     {
    ! I+ J$ x' m  D% k* W
  5.       UserButtonState = BUTTON_RELEASED;
    9 M8 I6 j: Y" J
  6.       // BSP_LED_Toggle(LED_GREEN);) i1 _  ^1 ?5 ^$ ^
  7.       printf("start GenerateRandomNumber_IT\r\n");
    / Q3 y$ `' k' d: ?0 x
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);
    & V" ^# q0 R9 Y
  9.     }
    / g/ m9 V" H! k; w
  10. #endif
复制代码
18.png
- E7 _  |8 u% H( T' e$ y% V
接下来实现一下之前说的两个虚函数

9 T' v; s2 }- \& q, u4 j
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)
    ( k1 }& d. f& U8 O
  2. {! b0 c9 {4 U! A. d# ~- t
  3.   randomData = random32bit;- H- O( z9 i+ R6 O' g
  4.   printf("Generate RNG IT = %04X\r\n", randomData);3 \% z, I4 N% S4 j: _, \
  5. }- b4 D; t" Y8 ^3 m9 o& [

  6. , I7 W! H1 C. x) J1 d4 F
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)1 b8 s+ {0 t8 G* G, n% F
  8. {8 ?1 {2 m% r* y; o
  9.   printf("Generate RNG IT ERROR\r\n");7 p# @0 L8 p5 A9 m- o8 \
  10.   Error_Handler();+ P' b9 x* n2 z6 P
  11. }/ Q7 S) m- ~6 `+ U* ?7 m2 H# A
复制代码
19.png
+ M' w- K, ?4 T1 B. {
! ]5 Z! ^$ n3 u- U2 `
编译下载,日志如下

  M, ~, u- S8 D: Q
20.png
" s9 d* ?' L: W! m
% d8 R6 H# a4 x0 l% ?9 ^

' }& T- ]# {' E
* p7 y1 L5 A5 j) s
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好
; u, l5 j0 ?; q9 N
) G: V3 E, J' ]
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0) + u& r5 Y3 j8 P  c3 a) K, c$ w
赞 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 手机版