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

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

[复制链接]
小萝卜啦啦啦 发布时间:2024-5-14 00:30
U0具备硬件RNG随机数发生器,相比软件算法得到的随机数,这个硬件RNG是真随机数。在加密时用它生成IV或者随机数,可以使得加密更加的安全。
, k: E* \: S) R3 S6 A" d  \5 r! t* F: c9 o
一、CUBE配置及函数讲解" @+ ~- O( T5 v8 v9 j
工程我们还是用之前生成的基础模板; G, l1 b! L) D# @$ Z& `3 p) L
首先在cube中开启RNG: y1 ?. `) h, d2 d- E7 M
1.png
9 \' d. }' N6 [6 W" `7 G9 B, O
! n+ q! R1 U5 R- u( w9 c
然后配置一下时钟,RNG的始终要求必须为48Mhz,我选择使用MSI(我一开始尝试了HSI48。但是初始化通不过,没跑通,那就只有换一个)
: y2 L/ O# p4 k0 n+ R
3.png
: _% s# T/ L" a4 z- k

2 u/ C0 c; C& N$ `3 K& y. y
然后把MSI的频率改成48000(也就是48M
2.png
" c% m' V5 O8 r
然后生成代码

8 z, t+ V0 J- X0 T5 d3 N# j) y. k
4.png 9 s4 b( Y9 u+ J) \# ?1 `
& J' q, o5 ]! x: r( d/ l. X. z6 x
接下来开始写代码,库函数我没有在cube中修改,使用的是默认的HAL
首先看一下自动生成的代码
CUBE帮我生成了RNG的初始化函数
5.png 5 K  p( k2 S8 y5 [4 F, [
5 i2 }3 H; x. |9 I. n" K* s
6.png / q8 g8 D8 {5 a+ \( S! C, D5 f
# x, S, I. e; }2 y1 V! I, ^' \. m0 w
HAL_RNG_Init我就不进去看了,里面主要是做一些参数配置和RNG时钟enable。如果有想仔细研究的可以自行查看。当然想要研究的跟底层,我推荐更换LL库,回头配合寄存器手册,可以学习到最底层的寄存器- m& J6 ~& Y( P: ~% y
0 a& I" \& {. P" i9 L) S
0 }3 l( h7 s" b" V
现在简单讲一下HAL库我们会调用的函数

1 z) ]5 Q1 E( x8 N, O, Z8 @& h
10.png
. Q5 h, |* O4 `6 R0 w- {
8 ~7 [6 y6 {. m) F1 Z# T$ E' u
阻塞式获取到随机数的函数:HAL_RNG_GenerateRandomNumber

/ K, Z: }5 L: \$ q+ d$ h# j
通过中断得到随机数:HAL_RNG_GenerateRandomNumber_IT

3 T( a( a) Z9 a( X9 z' N
获取上一次得到过的随机数:HAL_RNG_ReadLastRandomNumber

$ n0 |# U& a7 O6 G5 c0 L, E* L7 K3 x% F
从参数可以看到,我们每次获取的随机数类型是uint32_t
( m' _5 r3 h7 |
1 j+ O6 u# V2 X7 q1 E9 i' D
二、阻塞式获取到随机数及获取上一次得到过的随机数
# h  r! {" J/ j- M
首先设置一个uint32_t类型的全局变量,用于保存得到的随机数
% O  J5 v/ g5 P# i
  1. uint32_t randomData;
    ( u- l! G) Y" _2 C5 R8 @/ ]
复制代码
11.png
$ y) |' E& c; }# `, C
* ^9 i! R6 G& F1 l# D+ Z0 o4 R
' l( ]8 y- d) S2 P6 z
初始化后就可以直接调用获取随机数函数,我做了一个测试函数,会连续调用2次获取随机数函数,并且生成后再次调用获取上一次得到过的随机数函数,看看他会不会得到两个不同的随机数。

% z  b4 n; S; k9 U
  1. void GenerateRandomNumber_test(): Z& w! o5 i/ J5 B5 H, ?  D
  2. {
    , k+ W2 p7 N* T! Q' x9 R& r
  3.   uint32_t lastRandomData;4 F1 W: U+ [# j0 |
  4.   printf("GenerateRandomNumber test\r\n");
    % c( ]. m7 f/ D' n& a2 I
  5. . x- x% |& t3 F0 {
  6.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);
    0 ]& [# b' S# l
  7.   printf("GenerateRandomNumber = %04X\r\n", randomData);
    % F4 u% U# G; q- ^3 g0 N$ [9 \( T

  8. * J7 F8 x7 K+ K3 E# X2 v( \
  9.   lastRandomData = HAL_RNG_ReadLastRandomNumber(&hrng);
    5 l- u  V5 J0 M- Y: j3 o5 l
  10.   printf("lastRandomData = %04X\r\n", lastRandomData);8 ~2 o  H" j+ o9 ?

  11. * c# a8 a, r& I
  12.   HAL_RNG_GenerateRandomNumber(&hrng, &randomData);& o. s5 h% E' D+ M4 o
  13.   printf("GenerateRandomNumber = %04X\r\n", randomData);/ g# a' y, f  X! M0 ?7 T
  14. }
    9 X  J& m2 {; I# f& b  s
复制代码

; A, d& n  n5 j2 Z
* p3 l2 |, _% Z) r7 e, u' B. w6 Z
7.png 5 M# j5 v/ K; s# w* I8 @
, ]0 F9 h' _3 {! E: Z6 N' B
然后在main中调用
9 U; |# }% n  n1 w$ p- T1 [
8.png & x! F! P# q/ ~4 s) r& c
% l8 @* v9 c# B7 _$ X+ P) g6 w
编译下载,日志如下

* b, J. S4 q8 B1 _( Z& l
9.png 7 G- u/ B5 I$ [# x; A9 {4 E, T6 b( D

# {; c0 t5 N% y! k2 `: ~& D
两个随机数已经生成,不重复。并且获取上一次得到的随机数也成功
" h3 u% O: ^9 l: \

& J5 w8 c8 a; `
三、通过中断得到随机数
1 U* G% R3 a2 N0 D' r: C7 y
如果不想阻塞式获取随机数,那我们可以选择使用异步的通过中断获取随机数
' Q$ T& E  v8 \, E
首先需要修改一下CUBE,设置RNG的NVIC

0 ?. A! @4 P/ S# z. a
12.png ! b4 w6 y7 g4 W# |, U& ]; e( e

$ n2 G4 a) U/ L& Z
然后点击右上角的生成代码按钮(图片略)
2 w$ Q* V- F5 D6 M
刚才我们说了通过中断得到随机数为HAL_RNG_GenerateRandomNumber_IT。和之前的BSP的按键一样,中断相关的函数CUBE都帮我配置好了,用户层只要关注回调函数的实现即可。现在我们来看看成功生成随机数的回调函数、生成随机数失败的回调函数
, A3 i5 `, l# l7 i$ x7 j* {5 m3 `
. @3 q3 L. Y  L- X4 b& ]
这两个函数在init时就注册好了
8 o5 t: |2 {+ q$ c* s; t9 B
13.png   v! X. i4 ?5 ~& w  H: C/ y% ~

; w" t' F- K/ q' f# s; |+ _# A
这两个函数是HAL库中定义好的两个虚函数,回头我们就要来实现这两个函数。现在看看定义的虚函数
- |4 ^7 u3 m7 \7 o) l$ U4 }
14.png   |! z8 k* X* R$ o5 `  e/ F

3 d8 x( Q, \; M+ r! E
接下来看看这两个函数是如何被调用的,首先来到stm32u0xx_it.c,看看RNG和CRYP的中断函数(他俩公用一个中断源)
3 F5 e3 F) j; i- y3 ?7 |+ L
15.png
) Q& X$ g5 P8 L
/ \/ N, }! B% U7 h) B8 B+ W
在HAL_RNG_IRQHandler中判断各种寄存器和清除对应寄存器的值等,然后还会调用ReadyDataCallback或者ErrorCallback。

0 v% v* p! I0 v; o1 w* M8 z& u
16.png 7 k3 r9 _  q' }3 [7 u
% P/ p+ t- C& F- s
. m8 X: @- |8 z2 [
简单的了解完后,我们开始写代码

# I* A% ]# [/ Z- O% y6 ~$ J3 k: q5 q* N! @6 p" c. \
先把按键测试给打开,这样当按键按下后,我们调用一次HAL_RNG_GenerateRandomNumber_IT

- g5 P2 F+ A' X7 V% I
17.png
; V1 t4 v$ l( k+ `$ \

2 B  A1 ~6 {) I8 {3 r* o
while1中的按键测试函数中注释掉LED的翻转,添加HAL_RNG_GenerateRandomNumber_IT和打印

7 z* G$ p9 n$ Y$ z( c3 L! }
  1. #if BUTTON_TEST
    * k, K: Z! Q+ F
  2.     /* BUTTON BSP测试 */$ y# _5 n8 W) R& @; u
  3.     if (UserButtonState == BUTTON_PRESSED)
    9 m7 L- P; D3 a' J% o3 W5 d
  4.     {
    / N. B$ Y& e, Q( Q: u. u% U
  5.       UserButtonState = BUTTON_RELEASED;
    ' [4 w; h% @# E
  6.       // BSP_LED_Toggle(LED_GREEN);
    . W3 p8 t1 ^% q
  7.       printf("start GenerateRandomNumber_IT\r\n");
    # {# M3 d" @# G  w0 j
  8.       HAL_RNG_GenerateRandomNumber_IT(&hrng);" h- {& }7 Q# M) }- ^1 y# d! i+ ]" J, T
  9.     }7 R, ^6 L) H" Y# v! ~
  10. #endif
复制代码
18.png
* _' I$ y4 ~3 {
接下来实现一下之前说的两个虚函数
% w0 M/ `7 }. o
  1. void HAL_RNG_ReadyDataCallback(RNG_HandleTypeDef *hrng, uint32_t random32bit): q% t+ X& t  ?0 x0 [& K! j
  2. {6 _4 @* _+ d$ O: @
  3.   randomData = random32bit;
    4 p% X# h# ]  E% d& i; f& `3 Q) y
  4.   printf("Generate RNG IT = %04X\r\n", randomData);
    $ l& u4 L/ b' K1 G+ Q1 E6 a
  5. }4 F0 b6 f2 f+ z6 j' F8 A3 z

  6.   m% e; T5 |: Z" \% x8 w) P0 B; z& x
  7. void HAL_RNG_ErrorCallback(RNG_HandleTypeDef *hrng). G  q8 L. \0 \* y$ N
  8. {1 o/ t) l9 _$ N2 C5 s# w7 q! `
  9.   printf("Generate RNG IT ERROR\r\n");& e/ B- P7 N8 }2 D
  10.   Error_Handler();% }" m6 l+ a. [7 S( ~
  11. }% R' g! }2 Y, w. ?! s
复制代码
19.png

% z  M4 }' K$ o) Q

2 A' Z7 t& T' h: s5 {' z
编译下载,日志如下
: M* O4 e  }7 V5 L4 A, T! |& z
20.png ! ]# q  X* {1 F* t5 A
0 u* E  Y7 ]( F4 B* L6 L1 F
' A5 n. G9 c" D9 [

$ m% x& j( w1 s9 z" X( ?; S% O/ t
今日关于RNG的测试都顺利完成,ST的HAL库还是做得不错的,让用户就关注业务相关的函数,不需要去具体了解每个芯片的各个寄存器,对于开发很友好

# l) k* U) Y2 [! w+ p) `- w+ _& S) Z( i# \
今日工程: STM32U0_RNG_test.rar (5.16 MB, 下载次数: 0)
7 Y4 A" k  S  f* i- ?' G1 q
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 手机版