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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。
8 |. p0 T% H* s* \
5 O1 Z  e0 U$ W" ^! R/ n一、CUBE配置及函数讲解
* d4 v. |7 H3 I工程我们还是用之前生成的基础模板
9 o. }# l$ f9 L. ]! q( e首先在cube中开启RNG
& Z( z5 x* ^# N& N2 q- Q" W
1.png ) h; b1 M0 h3 ~

4 F& t# s! m) P* g
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)
: S* o$ D; f: ~6 s4 u2 |7 o
3.png   t7 i, J% V9 S7 o) ]# H( a6 g' i
9 n3 }. Y* T0 {
然后把MSI的频率改成48000(也就是48M
2.png
; F+ Q: P; P6 S$ G6 B( n" e$ k! R
然后生成代码
, O$ W1 v  c! c
4.png
' h& ?4 Y% p& a& c8 ?

4 W# [, ^& C  D" a7 s/ i
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png 6 N5 R7 L5 k' Z  x/ }

* }3 b' k6 w. m2 H) F
6.png ! N$ O' _6 ^+ D
4 g9 q; j2 d& f8 e# A% @
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器' z6 g9 c  s3 [
4 G( A4 u; r) F
3 N: `$ a2 Y' A; }/ A
现在简单讲一下HAL库我们会调用的函数

; S  t8 q5 r4 f( J! A
10.png & u+ O4 q# D/ w" ^" S- t$ H

% s* H6 q) Z0 Z- l
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber

8 _) y5 L1 M- @; p+ T& ]: I0 Z: X& F' w) E
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT
$ w0 m( C1 j- Z4 a8 Z: j
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber
/ Z7 @$ Y; u& u1 w

/ k) T9 x# |7 f: a
从参数可以看到,我们每次获取的随机数类型是uint32_t

+ N5 @* k- |- i: ~% h  r# H4 L# I; j
二、阻塞式获取到随机数及获取上一次得到过的随机数

' v# i" @7 t6 K- T
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数
# k5 \. x' m5 c4 \0 t
  1. uint32_t randomData;+ t3 d" A/ k0 ?" D
复制代码
11.png

3 w# B/ {5 J* R- o3 q7 g1 [' H; a+ s" o

( }. P- [* u' k$ I) Y5 t8 d8 ]$ k, H1 f; N) g% d8 ]- d& z4 S  o
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。
7 o) w. _9 a  A% m2 L' m. U
  1. void GenerateRandomNumber_test()
    3 r. v& k4 F: m7 h. j* j, M
  2. {
    6 q0 v2 @2 `1 i; B5 h
  3.   uint32_t lastRandomData;
    6 B3 R- d- ~3 n! t# T: B$ A# y" @
  4.   printf("GenerateRandomNumber test\r\n");
    ( e# i0 j( g1 E7 B  F5 E

  5. 1 [& N! v* i' O- G7 {3 Q* x' b
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);4 I6 ~! c0 c; g  a* f
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);0 M3 V: `4 d5 Y/ X# M
  8. 6 K% U7 g. K: I" e
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
    ' Q3 W- ?$ P0 g' M- K0 A
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);
    $ [5 {6 Q% x/ b' Q4 a% B" X7 @

  11. 3 L% ~. E3 v0 X6 a9 |2 q: o
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);6 J' W1 u7 h/ }+ P
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);: A  V' \) K" z$ v. i
  14. }3 L; w7 i( }: v. J; U) ^
复制代码
/ h. Z6 h" f1 {

) u0 H$ |% S* |9 ^6 V
7.png
' y/ V) r; M% `
8 \* D" t, w- l* c9 R9 C" R
然后在main中调用
& r: A, x9 e; f& T  C
8.png $ L# w# t# ^3 }! `2 I
+ N0 X: g- n) K) l/ |9 u! B
编译下载,日志如下

) q# E$ {  b( x9 w; W% X  B4 L: z9 A
9.png
" g5 T3 A. d! D) r
  \7 @/ q' _, x( a7 O' N
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功

, @* z( x2 v. m1 S7 z. k: i( V( @: r5 |, z7 m
三、通过中断得到随机数
# b+ U0 N! X% f3 T6 G: N0 Q
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数

7 A  G' p; ]5 e, ?6 l$ d
首先需要修改一下CUBE,设置RNG的NVIC

) r' I' ^* r  H' C, E. H& Q
12.png 6 ?  d3 |/ u8 H7 I& r( E
- n- i" s# R. h5 c& b+ \
然后点击右上角的生成代码按钮(图片略)

' S( P& _3 J6 D/ N5 V2 Y; F
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数
# y& p5 P. ^' ^- X- f9 _

2 B$ z7 S3 b  f/ a: N  d; n
这两个函数在init时就注册好了

; l3 R+ _) [$ j+ Y3 V# y  ?% p
13.png 8 d' I& E$ r$ ]* h+ o  }

0 z  A) l- A# N3 r
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数

5 P# C/ w4 W8 A( a
14.png
7 Z$ a% {1 k9 t* ^* u8 A. z: k# p) j8 k
, y8 ~3 r- r% _
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)

: F! `. b8 o% e2 b+ P/ P
15.png 4 }- N3 m, g  q

3 @% \6 a, o4 ?/ h- g% d
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。

* E" Z, `' R. S1 c8 a% @! @! ^
16.png 1 D' V, q9 C: R, `* ]5 ~! {! n5 ]- o

' N! |' L$ R6 M: H$ m2 ?: X0 l" K! `' A& c$ e
简单的了解完后,我们开始写代码
) p* ~5 `5 \: g4 `" c4 z
& B; \6 o3 S5 \9 C0 w8 q. ?
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

# G1 p1 T# m: i4 D+ P( b
17.png
0 N% c5 \% J6 J5 L" d7 G# j- F6 ?

" o/ _7 [4 K, A8 b2 j& ?
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印
0 y) Q9 R* ^9 }. B6 E" t
  1. #if BUTTON_TEST# }( z7 |  }( }# h6 K! _( _
  2.     /* BUTTON BSP测试 */
    . ~( q& s2 N9 R8 W5 ^$ j1 ]
  3.     if (UserButtonState == BUTTON_PRESSED)
    * F7 Y' d7 s$ r6 d# i% T
  4.     {
    . ]3 l* D, W( C! D- P9 A
  5.       UserButtonState = BUTTON_RELEASED;
    . I* \( S/ q, k/ X
  6.       // BSP_LED_Toggle(LED_GREEN);, j* P5 w6 T# ~+ j
  7.       printf("start GenerateRandomNumber_IT\r\n");
    4 D' D4 L! m* a+ [: r$ ?" f
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);/ ]* U3 m' d2 [) j$ U5 Z- Y; Y: Q1 p' j
  9.     }
    / _3 O$ R' j; B* L  U* v, I/ q
  10. #endif
复制代码
18.png
0 z. E* ^$ ]0 E+ y4 z' x
接下来实现一下之前说的两个虚函数

  S6 E. V, g, K( B0 N
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit)" n  F2 S" J# a; w0 ]$ @
  2. {: e: |* K3 G5 k- a5 ?
  3.   randomData = random32bit;/ w4 ]- Z5 c6 K0 N# L4 ^
  4.   printf("Generate RNG IT = %04X\r\n", randomData);: ~/ V! r, x" \5 q& q
  5. }
    - ?2 W$ M  g8 d# k7 ]" X1 [0 D
  6. & v, Y0 l3 o" C5 E8 \+ N4 I
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng)5 H% {4 F" l8 n. i0 S7 e- f
  8. {
    , i7 D4 i9 X- z3 p
  9.   printf("Generate RNG IT ERROR\r\n");! w* C; p' v+ X* Y! o! ^
  10.   Error_Handler();
    ( y- h4 x2 `( d" i2 `" f* L
  11. }  m! ^3 y4 J; w" M9 `  M
复制代码
19.png
4 {+ k  y7 @) F: l3 q& R0 u

+ \& K# X0 h2 s
编译下载,日志如下

' c( a6 Y9 X! j) o7 R( n6 d8 P7 i
20.png
  F! u0 c4 U) Y9 e( G2 e

2 R# i4 |7 \! E
" d4 _4 j1 a2 @* X% J7 ?
$ v7 _4 C1 m) ^$ l2 ~
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好
6 [9 g. Q7 c- |
8 h$ S! g$ l" Q3 q# x
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
. U" y) v2 f+ _! |3 H; F
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 手机版