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

【经验分享】使用STM32F4的CCM内存

[复制链接]
STMCU小助手 发布时间:2022-1-11 19:52
我们知道STM32F4当中有个CCM内存,如图所示,这个内存是挂在D总线上直接和内核相连,因此除了内核之外谁都不能访问,那么我们怎么将其利用起来呢?网上这个资料还真的很少,今天我就给大家分享一下,献给那些还不知道的人,如有错漏,还请指正。
: ?$ J- T( G/ \5 A) G: M7 ?* _6 F+ j9 v( s8 U- Z# p# \! ^

) b5 x% C$ `" F/ ]; @/ J
) r$ F- b# Y8 U  z首先,我们可以使用Keil的设置选项,将IRAM2打勾,让编译器选择什么时候使用这个内存。显然,我们还可以将这两个地址修改一下,将IRAM1改为0x10000000,这样,编译器就会优先分配CCM内存。
7 |. i0 p3 _$ E% O+ x, |5 \: a/ P  Y/ Q" ], z: k/ q

% G4 b1 f( Z4 e' `1 n& I( a! J) J5 ~6 {- }' J- Q
我们来看看结果,在MAP文件中,表明确实使用了这段内存,但是因为我们使用的内存较少, 还没有用到CCM。
/ c! N1 ~' d# O
" ~% G& T3 _9 D
7 G2 u  O4 r' r& |% _) t
% o* z, t+ y/ N+ g3 N这种自动分配的方式有什么问题呢?这段内存是内核专有的,除了内核任何其它总线都不能访问,这就意味着,一旦编译器将数据分配到CCM中,而同时使用了DMA访问,显然会出问题。
, s0 @  V* Z  T6 n. |7 u, a# J8 f3 g' s
于是我们就想到了自己分配这段内存,__attribute__((at(address)))这个语句就是专门干这事的,然后我们可以这么做:
& a! r1 O5 P" G3 d$ j. B$ y. ]
  • int vat[10] __attribute__((at(0x10000000))) = {1,2,3,4,5,6,7,8,9,10};* W, c8 C* L/ c3 P# _0 g6 }* X

( N+ [0 t8 B# q7 F[color=rgb(51, 102, 153) !important]复制代码

# m8 f" S* s* O0 C7 c  }; d# I5 Y+ Z9 v3 u, h% p- t- c- E
再次编译以后,发现确实如我们所愿,我们将一段数据放在在了CCM内存中:
- x5 W3 z' ^/ E# F( `
  •     Execution Region RW_IRAM2 (Base: 0x10000000, Size: 0x00000028, Max: 0x00010000, ABSOLUTE)
  •     Base Addr    Size         Type   Attr      Idx    E Section Name        Object
  •     0x10000000   0x00000028   Data   RW            7    .ARM.__AT_0x10000000  main.o
  • & `/ C) X# F4 U4 l8 O* A) Q

2 S* L8 M0 q& f[color=rgb(51, 102, 153) !important]复制代码
' V% _- u6 y: U* @! o4 W" b
$ E/ y+ @! ]  v8 E$ c, i+ x4 _
太好了,那么我们能不能将FreeRTOS的数据放进CCM中呢?将FreeRTOS要使用的内存全部移到CCM中,使其成为专有内存,显然会提高FreeRTOS的运行速度。
/ x/ d* i- y" q( `* f0 W+ n2 E! F3 M- v% x9 P  `. Z$ U
那么怎么放?首先我们想到了heap4.c这个文件当中有这么一段:
* s7 l8 h) @& D1 H" K  ^. g
  • /* Allocate the memory for the heap. */
  • #if( configAPPLICATION_ALLOCATED_HEAP == 1 )
  •         /* The application writer has already defined the array used for the RTOS
  •         heap - probably so it can be placed in a special segment or address. */
  •         extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
  • #else
  •         static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
  • #endif /* configAPPLICATION_ALLOCATED_HEAP */4 N& k$ }! f& e$ x' S4 B0 M) N
" p& _8 H7 {: x6 L$ O# m
[color=rgb(51, 102, 153) !important]复制代码
. x/ ?, h+ y  v$ Y+ }8 z
这是FreeRTOS中堆内存的分配,我们可以加入__attribute__将其放进CCM中,这样做没有问题,但是去修改FreeRTOS的源代码显然不是明智之举。事到如今,我们只能自己定义链接器的储存器映射了。' x3 I7 c$ q4 q# {7 H: I! w! {

- @; n1 }- v1 J! @$ T修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。! Q" D, B7 Z! {. ~' K' ~; c4 I
: R; K1 D- N, E, [; j: Y5 i# [
) ^: O7 q7 s" K3 q* @
6 q9 y( r& n7 J  @, N& f4 R. s* v. l
然后在Objects的目录中找到一个后缀为sct的文件,打开之后如图所示:
; N3 c* W) R2 |2 M
# R. Z4 T8 w4 u5 F( M( `1 ~0 V- [  o

+ d5 A; C0 U. P7 o, ^' m
由于我们只需要将RTOS的数据放入CCM中,于是我们可以这样修改,CCM_IRAM的名字是我自己取的,你可以改成任何你喜欢的,比如什么LOVEYOU之类的:1 |3 U4 E2 X9 O8 K

8 h' q3 t5 b  s3 \& M$ n' F( f3 A6 ~7 Q4 I% C" k! q( _% r" E

8 h0 ]) O2 ~$ W% z: Y" w* E: @然后在链接器中选择我们自己的文件:8 ]7 @) T1 W  Z2 o

3 \6 i- R  M3 Y: b
$ w0 j# L  T/ F& x) C8 }
; m* }+ W; r0 P7 u9 V9 T5 E现在,映像文件变成了这样:
! W; }: I0 j" s$ V% Z. P7 B# c; Z" `% i2 q9 O3 V3 i+ ?

) i% M2 p7 a, X# L9 Z6 f
( I, C9 v" j, r3 _, u/ S! W0 ^是不是很简单呢?系统堆栈仍然在主内存中,而FreeRTOS的堆内存已经移到了CCM中,由于互不影响,这里我分配了50K的空间专门给FreeRTOS使用。我们甚至还可以配置MPU将这段内存配置为特权级,避免一般任务修改等等,怎么使用,那就是你的事了。

7 `2 [( ]# Z  j$ @0 ]
收藏 评论0 发布时间:2022-1-11 19:52

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版