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

【经验分享】STM32H750 QSPI FLASH使用小结

[复制链接]
STMCU小助手 发布时间:2021-12-28 22:13
根据ST的参考手册描述,h750的片内flash只有128kb,在实际的项目应用中,128kb的容量有点太小了,有时候光光移植好lwip+freertos以后,flash的容量就所剩无几了,所幸可以使用QSPI FLASH来存放程序代码,可以把程序的部分或者整个程序都存放在QSPI FLASH中运行。这里介绍两种不同的方法。
& j2 n' \9 q, Y/ `" G: A8 Z0 a/ E8 {1 ?* P: [  P
一、通过分散加载文件的方式* V" |; ]# _6 S( Z9 M
! a+ D3 _  [, n
    本文中使用的是正点原子北极星板子的例程,跑马灯实验。例程比较简单,主要是看分散加载文件,在最后有一个LR_m_qspiflash加载域,这个就是将代码存放到QSPI FLASH的。分散加载文件的具体细节就不在这边讨论了。
2 R" B4 y- B( X. |1 X# t* D  F' n) {  M2 U5 {, z2 o
    当然,光光靠配置分散加载文件,是无法把程序下载到板子上的,因为有一部分RO是要下载到片外的flash的,因此这边还需要使用特殊的片外flash算法。在正点的资料有有提供这一算法。通过添加算法的方式,这时应该能够将程序下载到板子上了,但是,这个时候程序不一定能够跑起来,还有一个重要的步骤,那就是初始化QSPI,并设置成内存映射模式。正点的例程中是将初始化操作放在了时钟初始化函数中。至此,程序就能够正常运行了。
5 w' W' O: y8 x- L/ y2 ]
- z4 X! n# ^  I8 @4 R& C& t1 ^
  1. #! armcc -E . y  g0 _- [) F! w
  2. //  4 ^/ ]6 Q) V6 [4 C1 h
  3. //STM32H750分散加载文件(.scf文件)
    5 }6 ~( _" {& m/ g
  4. //ALIENTEK STM32开发板  
    $ ?; `) @: ?  N! L
  5. //正点原子@ALIENTEK4 ?0 U1 C6 j  ~' X
  6. //技术论坛:<a href="http://www.openedv.com" target="_blank">www.openedv.com</a>7 X" Z% ^) _& Z, A! j# m3 O2 P
  7. //创建日期:2019/4/21
    6 g# e% N3 A; d
  8. //版本:V1.0
    $ v8 r( x9 [9 K: Y
  9. //版权所有,盗版必究。
    % D" u7 E1 U! u! q
  10. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024
    + E1 f7 t& G; @1 l( f% e8 n
  11. //All rights reserved
    6 s5 ~: ^2 O  W5 |
  12. //********************************************************************************9 M9 X7 g/ }) y$ W; j% `/ E; U) U- x
  13. //修改说明
    ' P- [% c3 A, X' Q& n
  14. //无  }% G+ }* {* U
  15. //8 G" O( _3 K" x
  16. * J3 P; [1 E9 l$ Q3 H- t' U
  17. , V' P- r: S. N5 |: \. B
  18. #define m_stmflash_start                                0X08000000                //m_stmflash(STM32内部FLASH)域起始地址
    & j1 [5 u$ N( O+ l
  19. #define m_stmflash_size                                        0X20000                        //m_stmflash(STM32内部FLASH)大小,H750是128KB
      P9 A5 ^% c; l; @# v* x8 L1 `

  20. 8 X8 o, t, D; a2 X  K% p
  21. #define m_qspiflash_start                                0X90000000                //m_qspiflash(外扩QSPI FLASH)域起始地址; c, q9 \& ^3 _8 c0 N, U& x
  22. #define m_qspiflash_size                                0X800000                //m_qspiflash(外扩QSPI FLASH)大小,W25Q64是8MB
    ) @* F8 j3 D  z' X' G$ X3 w
  23. 2 `2 p  \, `, [: ~+ u1 P7 _
  24. #define m_stmsram_start                                        0X24000000                //m_stmsram(STM32内部RAM)域起始地址,定义在D1,AXI SRAM6 f# m) B# ]6 d4 t7 v; c! C/ y
  25. #define m_stmsram_size                                        0X80000                        //m_stmsram(STM32内部RAM)大小,AXI SRAM共512KB
    ' r7 U5 a: S% d& M+ O
  26. : X/ D- p1 d7 H4 ^

  27. 1 c+ C, {* H: n: C' L4 v

  28. / K8 v! b; \8 m; z) \
  29. LR_m_stmflash m_stmflash_start m_stmflash_size {                //LR_m_stmflash加载域
    - s" v/ \( H& c6 Y; I. V7 m/ G+ @
  30.   ER_m_stmflash m_stmflash_start m_stmflash_size {                //ER_m_stmfalsh运行域,起始地址为:m_stmflash_start,大小为:m_stmflash_size
    . p. c; ~( ?$ I5 i; W3 G
  31.     *.o (RESET, +First)                                                                        //优先(+FIRST)将RESET(中断向量表)段放这个域,实际上就是把中断向量表拷贝到m_stmflash_start
    8 a" W) k6 t- q# h
  32.                                                                                                                 //RESET是一个段名,表示中断向量表(在.s文件定义);+FIRST表示时第一个要加载的.
    ; d( E/ g  @5 V  N/ ~5 d' u
  33.         * (InRoot$Sections)                                                                //将所有的库段(C/C++标准库)放在root region.如__main.o,__scatter*.o等
    . e# |6 H0 Y4 z$ B& b
  34.         * (Veneer$Code)
    2 z: R' c$ \) k  I$ `+ l% \. Z
  35.         libinit.o4 z6 |1 g3 C5 \7 K- j' {3 C3 [9 e
  36.         libinit2.o
    ! y* s  G& b& J* @5 X# \6 _
  37.         libshutdown.o. `7 f: D' k- N
  38.         libshutdown2.o
      J! ?: j( a/ k% z5 X6 x7 r
  39.         __rtentry.o
    ; R4 |' o% L1 _# y9 \) M- Z
  40.         __rtentry2.o+ |7 t& V4 @: j/ ^  i/ d% i
  41.         __rtentry4.o) \8 t" b) s. `( t
  42.         rtexit.o: z! R! k- a: h. V5 b! _. c
  43.         rtexit2.o 4 W! c; q2 r. f2 W; m
  44.         9 u' N) B* {& p7 ?, Y1 Q8 e( _* `
  45.         use_no_semi_2.o
    / e5 o0 y. y& O8 a
  46.         heapauxi.o3 {! q7 p' r( A- n
  47.         use_no_semi.o
    . I8 J' g& w# D
  48.         sys_stackheap_outer.o
    2 H; ]" M2 c- N$ K* L4 N
  49.         exit.o
    # [. k9 m) w& s" V9 s, d% x0 d: y
  50.         libspace.o; h2 Z; z  p4 _  J% `% L" i' P" c* y
  51.         fpinit.o7 M3 Q: ]+ a4 l7 ~% Z( l
  52.         lludivv7m.o6 {* P$ F5 b( h! ^  }4 s/ y8 Y
  53.         startup_stm32h750xx.o6 s9 s) h& o5 g( I
  54.          
    8 _% k) Q7 w0 m6 O& `7 e6 T% e
  55.         rt_locale_intlibspace.o  9 u3 f; `8 c7 Y. u4 {/ P
  56.         lc_numeric_c.o 8 W0 f4 L; g4 G( m9 f& e- h
  57.         lc_ctype_c.o
    8 }; t: O2 ]9 ^0 M% {% H
  58. ; b* y/ I  i- Y! O2 {! }3 N
  59.         startup_stm32h750xx.o, V8 x% ~' H+ {, {; o+ |6 d" K
  60.         system_stm32h7xx.o' F8 ^, B! {1 C) [
  61.         stm32h7xx_hal.o: ^/ j+ j9 C1 f& n
  62.         stm32h7xx_hal_cortex.o4 v6 N/ ?; C3 j9 B! z) @
  63.         stm32h7xx_hal_rcc.o2 @9 M: `  [. ~* @
  64.         stm32h7xx_hal_gpio.o3 l( E* d4 l4 |2 p9 }8 {* `$ l
  65.         stm32h7xx_hal_msp.o+ E! z3 M5 V; f4 w# u
  66.         
    4 x, Y  E' A  |, ^* U8 Q
  67.         main.o
    : h% G' ]  b6 [! s
  68.     sys.o : M6 g1 t- x! w1 M2 F, _
  69.         usart.o5 w  t% I+ G. ]- @. d) N5 s
  70.         delay.o
    9 p7 z3 h# @4 j' T& W6 q
  71.   } $ X8 o  }+ h$ U3 R! y
  72.   RW_m_stmsram m_stmsram_start m_stmsram_size {                        //RW_m_stmsram运行域,起始地址为:m_stmsram_start,大小为:m_stmsram_size.
    & t; i, T2 d3 {3 r8 ?
  73.    .ANY (+RW +ZI)                                                                                //将所有用到的RAM都放在这个区域1 t" Y/ Y. ?2 @' ?9 n, Z7 Z. }
  74.   }
    2 @6 v) u5 ~5 V
  75. }
    1 r8 w6 j" Q* e* A

  76. - Y3 H* g2 a6 t( k" a2 |
  77. LR_m_qspiflash m_qspiflash_start m_qspiflash_size {                //LR_m_qspiflash加载域
    # R! M& D( u3 b+ Z+ D9 q
  78.    ER_m_qspiflash m_qspiflash_start m_qspiflash_size {        //ER_m_qspiflash加载域,起始地址为:m_qspiflash_start,大小为:m_qspiflash_size
    . i# x' k0 ~% r
  79.     .ANY (+RO)                                                                                         //将只读数据(+RO)放这个域,任意分配.相当于程序就是存放在这个域的.
    ( e1 k: Z* F8 ^
  80.   }                                                                                                                        
    - j- P& K  v/ V: ^
  81. }
复制代码
1 Y$ y0 O2 x/ }8 k" z/ G
以上分散加载文件,由正点原子编写,为了方便大家使用,不用频繁修改.sct 文件,特意
" k/ L. f; ]" Y: q6 u
# k3 a" o2 Z* c4 T, @/ q将.ANY ROM 区域放在外部 SPI FLASH,这样大家在新增.c 参与编译时,默认就是存放在外部
+ ?7 Y& l, M# s. r4 I* @+ `' W: H/ U
SPI FLASH 的,这样使用起来就更方便。
+ L# h( v! P6 f
3 o1 R* L9 s# a; q! F注意:3 Q* _8 p1 T2 D* ]/ `" O1 Q
3 [4 b1 f- a* Z& S& p; [
1, 如果你新增的代码,对速度有要求,可以将其对应的.o 添加到内部 FLASH,即放在:
5 k9 d# [1 c0 Z$ y8 v
0 H- j, ~7 B+ `" mER_m_stmflash 运行域。- w! U6 c, `* _" }/ K! |6 j% D" T& y
4 K  `6 Y. m7 q9 M- @' f
2, 如果添加新代码后,程序无法正常运行(通常表现为黑屏/不启动),可以尝试将新增
+ [: s8 A: K  s8 {; w- |5 H+ d3 K: k1 I6 {- Z# b
的.o 放到 ER_m_stmflash 运行域后(重新编译)再尝试。如果还不行,可以尝试将所
8 w! T1 x7 J: ^; ?1 g" U* J; Q, n& l; S
有代码都放到 ER_m_stmflash 运行域后再尝试。; d2 p% ^7 h* a2 }% E+ |
5 E& n+ \( n1 k& }
20200609103620392.jpg
4 R7 \4 J' R0 f' e( b% x; y1 C
( P4 |/ y) _8 g$ d0 `8 q8 u
二、通过boot程序跳转到qspi flash执行用户程序
7 A8 v4 h$ @0 C8 B! J) D% _4 f# w  m2 O
    第二种方式就是通过在片内flash中存放boot程序,然后通过boot程序跳转到用户程序,用户程序就放在qspi flash中。, H( {4 `) [; o5 E7 E9 y8 f& f' _

( E$ A3 n3 C/ V4 h) x& ]4 mboot程序主要的工作就是初始化qspi,并设置成内存映射模式;禁用中断,重新配置中断向量表地址,然后进行跳转。这里分散加载文件直接使用系统自动生成的就可以了。程序起始地址0x08000000。# f  w/ }# ~/ A+ }2 @: J

5 n- W- K0 s2 u8 V7 C- I" e  u用户程序需要做的操作就是把程序起始地址改成0x90000000,然后添加下载算法,因为整个程序都是存放在qspi flash上的。下载完成后,用户程序就可以通过boot程序跳转执行了。3 Y! [% P3 V2 F) l4 J! X

. L) n0 D; J! x- g4 i8 c  W
20200609104938687.jpg

1 x2 I- Q6 J$ a( ^6 v' V& H  T. t& E/ m+ h) C
20200609104944216.jpg

; N0 R& t. b  i' J- V6 {- D& m( \4 x; K$ i; F
注意,不管是第一种还是第二种方法,都是将qspi flash给设置成了内存映射模式,而此模式下qspi flash是只读的,所以这个时候就没办法用来作为存储器来存储数据了。不过网上也有人说内存映射模式下也是可以写数据的,至于真假,还没验证过。
7 x3 g( y( f9 a1 t0 v( u& B
4 k2 j9 l/ [: s6 I( `1 i7 ~( K9 w9 S4 T; A; j: |* n/ l
收藏 评论0 发布时间:2021-12-28 22:13

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版