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

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

[复制链接]
STMCU小助手 发布时间:2022-1-11 19:52
我们知道STM32F4当中有个CCM内存,如图所示,这个内存是挂在D总线上直接和内核相连,因此除了内核之外谁都不能访问,那么我们怎么将其利用起来呢?网上这个资料还真的很少,今天我就给大家分享一下,献给那些还不知道的人,如有错漏,还请指正。
4 @+ C" `! m) B7 V) P* D( O, R' Y

" r7 T  t1 @! J
% g1 F* m1 Q! d首先,我们可以使用Keil的设置选项,将IRAM2打勾,让编译器选择什么时候使用这个内存。显然,我们还可以将这两个地址修改一下,将IRAM1改为0x10000000,这样,编译器就会优先分配CCM内存。
- b5 ^7 z+ ?: H3 {$ u
9 M/ X+ @4 l; E4 O* ~4 V0 z: Z& S+ {( O7 {
: ~# f- r: n" M# N- r
我们来看看结果,在MAP文件中,表明确实使用了这段内存,但是因为我们使用的内存较少, 还没有用到CCM。
6 k! Z: n* B( m$ `" o# u! l: X& D- P* L

2 |/ f& |0 |6 b' F
5 I- V  B, \3 ?/ z9 J这种自动分配的方式有什么问题呢?这段内存是内核专有的,除了内核任何其它总线都不能访问,这就意味着,一旦编译器将数据分配到CCM中,而同时使用了DMA访问,显然会出问题。
/ G0 h) E! d2 {* U2 U. N7 P7 z6 ?) J  R( ]$ v/ `5 o
于是我们就想到了自己分配这段内存,__attribute__((at(address)))这个语句就是专门干这事的,然后我们可以这么做:0 p; K. {) c0 }6 ]- }) v
  • int vat[10] __attribute__((at(0x10000000))) = {1,2,3,4,5,6,7,8,9,10};
    ; m* \1 V1 W; h+ J9 E
0 ?  U& L5 X, M7 ^4 [
[color=rgb(51, 102, 153) !important]复制代码
9 O' [& P+ o) z1 i2 W# H, y' U

& d: u6 l) o; A& @再次编译以后,发现确实如我们所愿,我们将一段数据放在在了CCM内存中:% E: Q2 ~) W5 T7 d  U4 s0 ~( k
  •     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
  • 7 v. v$ e, E" p2 e: }
: i: i! J6 F7 O' a
[color=rgb(51, 102, 153) !important]复制代码

4 Q4 u! k. J. _. J9 Y9 ?. K  S
/ ^1 _7 m3 G/ L4 p. A- ?/ b太好了,那么我们能不能将FreeRTOS的数据放进CCM中呢?将FreeRTOS要使用的内存全部移到CCM中,使其成为专有内存,显然会提高FreeRTOS的运行速度。5 {2 S8 \* N8 ]& N" W' N5 C

! t0 z$ R! i) x$ n7 S那么怎么放?首先我们想到了heap4.c这个文件当中有这么一段:4 l4 H8 k  [# T: y4 H; P% L
  • /* 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 */- N" O4 f" F- f, |) s$ a
8 H+ a7 R/ L0 T" X5 V9 L3 j
[color=rgb(51, 102, 153) !important]复制代码

6 C6 H# \9 g; g% C这是FreeRTOS中堆内存的分配,我们可以加入__attribute__将其放进CCM中,这样做没有问题,但是去修改FreeRTOS的源代码显然不是明智之举。事到如今,我们只能自己定义链接器的储存器映射了。
, [. F6 W+ B" u$ B8 T) c& n- c# r3 l5 t+ L% ~% N
修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。
' a$ A; b% n! d* K9 R& E# t% [; X9 s- a0 Y$ D: _4 P

, T7 I. a6 I0 ?) C

+ B- L, L& L" J然后在Objects的目录中找到一个后缀为sct的文件,打开之后如图所示:
' {+ E7 O5 T/ J8 B4 y" F& P- A1 s5 s9 _' S3 H, K
/ ?0 d( ?/ p$ @

8 x- \7 X3 \* G3 f& E
由于我们只需要将RTOS的数据放入CCM中,于是我们可以这样修改,CCM_IRAM的名字是我自己取的,你可以改成任何你喜欢的,比如什么LOVEYOU之类的:) {# r  i' S$ Y7 f; m
$ l& R7 ~" Z2 p' B3 S. N

  U& z* Z! E" n/ \6 E+ e' I1 Y. F% b) Z: W" Q) Z: m8 D
然后在链接器中选择我们自己的文件:. U$ Z5 g7 L0 c+ D$ F3 _% t
: f5 p. h+ }, e# L

7 s$ Y5 `& p: W$ g+ B  p  o) N3 ~) ^' [+ b, J
现在,映像文件变成了这样:
9 {/ G! c7 B; d$ o) k% w
$ |* E6 G0 n4 \  p& Z0 E
& _; w; j8 r/ @8 q+ q3 |$ R8 [6 y
, G  P: N, @& ?# w" ^+ f是不是很简单呢?系统堆栈仍然在主内存中,而FreeRTOS的堆内存已经移到了CCM中,由于互不影响,这里我分配了50K的空间专门给FreeRTOS使用。我们甚至还可以配置MPU将这段内存配置为特权级,避免一般任务修改等等,怎么使用,那就是你的事了。

8 A: z; ^' ?1 ?: W: W, p# a
收藏 评论0 发布时间:2022-1-11 19:52

举报

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