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

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

[复制链接]
STMCU小助手 发布时间:2021-12-28 22:13
根据ST的参考手册描述,h750的片内flash只有128kb,在实际的项目应用中,128kb的容量有点太小了,有时候光光移植好lwip+freertos以后,flash的容量就所剩无几了,所幸可以使用QSPI FLASH来存放程序代码,可以把程序的部分或者整个程序都存放在QSPI FLASH中运行。这里介绍两种不同的方法。
" D8 Q* [$ B$ ~7 K; |
* S. L5 f9 `: b2 R+ r- u5 l一、通过分散加载文件的方式
: a# c5 e, p8 a/ ?$ Q$ I
# M5 f0 K1 l8 C% r* i9 E    本文中使用的是正点原子北极星板子的例程,跑马灯实验。例程比较简单,主要是看分散加载文件,在最后有一个LR_m_qspiflash加载域,这个就是将代码存放到QSPI FLASH的。分散加载文件的具体细节就不在这边讨论了。
! B/ ^! k# h: `) v) F+ e0 V0 O$ n+ g# D: X0 x' C
    当然,光光靠配置分散加载文件,是无法把程序下载到板子上的,因为有一部分RO是要下载到片外的flash的,因此这边还需要使用特殊的片外flash算法。在正点的资料有有提供这一算法。通过添加算法的方式,这时应该能够将程序下载到板子上了,但是,这个时候程序不一定能够跑起来,还有一个重要的步骤,那就是初始化QSPI,并设置成内存映射模式。正点的例程中是将初始化操作放在了时钟初始化函数中。至此,程序就能够正常运行了。
9 K- p  Q" n1 g0 B& m$ R) C3 C( h; |# Q- o
  1. #! armcc -E
    7 }' u9 n6 b0 W+ G$ v' {
  2. //  
    - u+ U' N7 W: \
  3. //STM32H750分散加载文件(.scf文件)
    ; _* J# r$ U# C* f' [* q4 R1 B, f5 g
  4. //ALIENTEK STM32开发板  " u. M9 c3 H1 G1 e
  5. //正点原子@ALIENTEK) `3 L1 A5 W* f: N- |
  6. //技术论坛:<a href="http://www.openedv.com" target="_blank">www.openedv.com</a>! a9 l3 i' l$ G; K9 f- x9 Y
  7. //创建日期:2019/4/21
    4 A# J7 q) ]. p
  8. //版本:V1.0
    & K& ]7 N) h  n- c' }. I
  9. //版权所有,盗版必究。
    , D! Z) H# e+ \( X1 d2 I; u$ \
  10. //Copyright(C) 广州市星翼电子科技有限公司 2014-2024) ]% o" [" I) a
  11. //All rights reserved, w0 J1 T: y! W. G2 Y
  12. //********************************************************************************
    ) C0 o6 u- C- ?9 k" K# D' @
  13. //修改说明( B. e9 e# e9 s8 i, ?" X
  14. //无
    1 N# j1 y7 g: U* y
  15. //6 }  d, \4 _' B' h* _

  16. ; ~% Y: `3 b8 g
  17. 2 N( D% h1 V% n
  18. #define m_stmflash_start                                0X08000000                //m_stmflash(STM32内部FLASH)域起始地址
    ( @# U% l2 a/ n% S
  19. #define m_stmflash_size                                        0X20000                        //m_stmflash(STM32内部FLASH)大小,H750是128KB
    + `& u: q7 D8 E, o3 u

  20. 7 @1 m! K5 V. ?- o
  21. #define m_qspiflash_start                                0X90000000                //m_qspiflash(外扩QSPI FLASH)域起始地址4 e2 [8 D; f- F, X" T2 ^% F
  22. #define m_qspiflash_size                                0X800000                //m_qspiflash(外扩QSPI FLASH)大小,W25Q64是8MB  D2 L; r% L& f- i4 f1 x4 b

  23. 2 `* p  k* I  K% D' |
  24. #define m_stmsram_start                                        0X24000000                //m_stmsram(STM32内部RAM)域起始地址,定义在D1,AXI SRAM4 F# X. }: v8 G! r9 m/ @' p+ R! W+ L, ^
  25. #define m_stmsram_size                                        0X80000                        //m_stmsram(STM32内部RAM)大小,AXI SRAM共512KB
      A& k/ S! c/ ?0 n# u
  26. 7 g$ e. z" R' u! k4 P: C; S

  27.   {3 G' L& D- _3 l* j$ O: W- F  r$ S$ i

  28. 9 Y6 e, t( B/ C$ `. l
  29. LR_m_stmflash m_stmflash_start m_stmflash_size {                //LR_m_stmflash加载域  o" I/ ^5 p& v
  30.   ER_m_stmflash m_stmflash_start m_stmflash_size {                //ER_m_stmfalsh运行域,起始地址为:m_stmflash_start,大小为:m_stmflash_size % p. v' L1 U- N9 \
  31.     *.o (RESET, +First)                                                                        //优先(+FIRST)将RESET(中断向量表)段放这个域,实际上就是把中断向量表拷贝到m_stmflash_start
    $ ~- [. X* S3 R9 D8 X" s
  32.                                                                                                                 //RESET是一个段名,表示中断向量表(在.s文件定义);+FIRST表示时第一个要加载的.
    , i+ _' |: c6 M4 v3 \
  33.         * (InRoot$Sections)                                                                //将所有的库段(C/C++标准库)放在root region.如__main.o,__scatter*.o等
    1 v# r# k3 \. M- d7 s- w
  34.         * (Veneer$Code)
    . v& c  x0 r% J$ L  |
  35.         libinit.o1 \" [* V, \; r
  36.         libinit2.o" ?" G* N( J# F- J' Y
  37.         libshutdown.o! y- s0 K1 n4 l: {, e
  38.         libshutdown2.o
    . q. f" T& Q! k$ q0 V
  39.         __rtentry.o
    $ `) i! r7 r; U$ l7 N
  40.         __rtentry2.o* x+ ^) y- a2 q( R( s
  41.         __rtentry4.o
    . q( I9 T  |/ E1 |( [
  42.         rtexit.o
    ; p& C  z- L3 h2 T2 d( U. B
  43.         rtexit2.o & z# Y6 B' b% k  ^
  44.         
    # D; v/ q7 {- t  h' m/ d
  45.         use_no_semi_2.o2 y6 G; ^' X' M1 K6 Z# j
  46.         heapauxi.o
    ! R" ?' z% Q: S3 A3 e: K3 l
  47.         use_no_semi.o
    - k0 Y+ w- _7 C
  48.         sys_stackheap_outer.o
    2 X6 v- u9 ~! T& v. }# W
  49.         exit.o
    8 G' }- P2 F6 j$ g$ b
  50.         libspace.o& }# I  j; J% m* m
  51.         fpinit.o
    3 ?1 U! u4 R9 h- M) w$ D! O
  52.         lludivv7m.o
    1 m. _  A$ u& a* J3 j) S3 \1 F
  53.         startup_stm32h750xx.o
    7 K9 Q: k- C8 ^+ l* G* D3 Z" n
  54.          
    / J" [1 A/ z( [7 A" A6 n8 u
  55.         rt_locale_intlibspace.o  0 f1 A3 a0 c' Z1 w$ ?0 ?1 a$ ?
  56.         lc_numeric_c.o
    8 W" y" D" L5 t
  57.         lc_ctype_c.o/ X. l& I5 [* k! Q3 G
  58. $ \% V! h8 Y3 b* m
  59.         startup_stm32h750xx.o/ X+ _! }( S" c5 j% Y( A
  60.         system_stm32h7xx.o
    8 c( L4 P2 |/ b
  61.         stm32h7xx_hal.o( w) @0 g  b) I8 c9 C) |# \, S
  62.         stm32h7xx_hal_cortex.o
    0 q, {7 `) d. y: B) |
  63.         stm32h7xx_hal_rcc.o
    7 B8 J7 n% I+ g. ?( V$ F
  64.         stm32h7xx_hal_gpio.o# C# P4 a( R- |" a- \; S7 Q
  65.         stm32h7xx_hal_msp.o" x1 ^+ a6 E8 X& o
  66.         & O2 L  Y# S3 V3 A0 h3 m; K& k
  67.         main.o 2 ^& D! p1 c9 u- \6 i7 V
  68.     sys.o
    ' x5 s0 E# l4 i' Z. Q; b
  69.         usart.o4 {$ B+ u! W; R
  70.         delay.o
    1 u1 [* `. F& m% ^  o/ U' g
  71.   } 7 O' {( h7 a0 N' z# c
  72.   RW_m_stmsram m_stmsram_start m_stmsram_size {                        //RW_m_stmsram运行域,起始地址为:m_stmsram_start,大小为:m_stmsram_size.
    # d9 R( l8 d: T5 `8 ^$ W1 s& d: f* T
  73.    .ANY (+RW +ZI)                                                                                //将所有用到的RAM都放在这个区域
    . m% o6 ^' M/ J( r" y0 p5 O% \
  74.   }( Z" B% |! E: I' ^! k  E
  75. }
    7 q6 l! ?2 @  E8 G* `& u7 G; P
  76. 5 `* z3 V, G+ N
  77. LR_m_qspiflash m_qspiflash_start m_qspiflash_size {                //LR_m_qspiflash加载域
    ) ]7 e& b( C% V$ Z: C: _( E; C1 j
  78.    ER_m_qspiflash m_qspiflash_start m_qspiflash_size {        //ER_m_qspiflash加载域,起始地址为:m_qspiflash_start,大小为:m_qspiflash_size 8 G3 Z2 |0 u& j5 ^) n! G' i7 V$ b( R
  79.     .ANY (+RO)                                                                                         //将只读数据(+RO)放这个域,任意分配.相当于程序就是存放在这个域的., E9 Q7 _& P& r. i7 R
  80.   }                                                                                                                        
    & M( d( M! E' a. ^# c& }
  81. }
复制代码

: h/ g8 y6 P" @( B以上分散加载文件,由正点原子编写,为了方便大家使用,不用频繁修改.sct 文件,特意
/ b  x! V& G+ f% X+ B, J5 e/ ]3 X5 z. f/ Y' H- b% n" v4 s
将.ANY ROM 区域放在外部 SPI FLASH,这样大家在新增.c 参与编译时,默认就是存放在外部
2 T( q0 {( x8 G3 Y5 X5 `( g) T1 Y/ I% _& O5 Y( ?
SPI FLASH 的,这样使用起来就更方便。
8 [5 \/ R# U0 J& ?" J* f4 U! m' [% U( y/ _- E
注意:. I6 `, E+ x/ U  k* z' \* j" P0 D
2 G5 c- q5 t' p+ m, Q* {
1, 如果你新增的代码,对速度有要求,可以将其对应的.o 添加到内部 FLASH,即放在:' G3 u' k- U: a# H8 B5 C2 ^

) i; @8 h8 O# ~6 s, B; [3 ?* HER_m_stmflash 运行域。9 I' [9 Y# ]8 {4 [! }/ [

) j9 M1 P! w; L5 \$ U2, 如果添加新代码后,程序无法正常运行(通常表现为黑屏/不启动),可以尝试将新增  m& z: i9 }. D# ]

  @1 i4 z1 G% [6 q( }/ }3 L的.o 放到 ER_m_stmflash 运行域后(重新编译)再尝试。如果还不行,可以尝试将所' a7 C8 |( H+ r( o

# O* {& Q. s% i, D/ J有代码都放到 ER_m_stmflash 运行域后再尝试。
" q+ l2 C4 O* }4 G; n7 E: I- \* Y2 t8 g
20200609103620392.jpg

9 o2 ^: _3 v! o# K
& `/ X' J$ u3 d二、通过boot程序跳转到qspi flash执行用户程序8 `, F) m% k$ n. d* ~

4 N3 l, `* n" l    第二种方式就是通过在片内flash中存放boot程序,然后通过boot程序跳转到用户程序,用户程序就放在qspi flash中。
4 H7 ]/ T" m9 x1 k3 q" t" b2 N4 ^3 I; k; s+ ~
boot程序主要的工作就是初始化qspi,并设置成内存映射模式;禁用中断,重新配置中断向量表地址,然后进行跳转。这里分散加载文件直接使用系统自动生成的就可以了。程序起始地址0x08000000。
2 u0 u0 Q( U& r7 T& J) |! ]9 }( p8 K2 {  T% M# d
用户程序需要做的操作就是把程序起始地址改成0x90000000,然后添加下载算法,因为整个程序都是存放在qspi flash上的。下载完成后,用户程序就可以通过boot程序跳转执行了。
# z: A* B2 K7 U/ s% \) I- ]: T9 Y3 l/ d( R
20200609104938687.jpg

: t0 P5 h0 @/ M4 T" ~' Q( G9 J9 S2 A( x& C2 M: q  H
20200609104944216.jpg
0 q/ k+ P2 X0 t3 d4 K
+ C; j" y9 {! k- _5 d6 F! ]3 f
注意,不管是第一种还是第二种方法,都是将qspi flash给设置成了内存映射模式,而此模式下qspi flash是只读的,所以这个时候就没办法用来作为存储器来存储数据了。不过网上也有人说内存映射模式下也是可以写数据的,至于真假,还没验证过。+ @1 x% C5 l+ I: }% h, \9 f8 ^
/ J& G- Y- l( H" G5 v. h3 K

( p1 A& @- J' Q6 o- b( D
收藏 评论0 发布时间:2021-12-28 22:13

举报

0个回答

所属标签

相似分享

官网相关资源

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