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

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

[复制链接]
STMCU小助手 发布时间:2022-1-11 19:52
我们知道STM32F4当中有个CCM内存,如图所示,这个内存是挂在D总线上直接和内核相连,因此除了内核之外谁都不能访问,那么我们怎么将其利用起来呢?网上这个资料还真的很少,今天我就给大家分享一下,献给那些还不知道的人,如有错漏,还请指正。& v! ^& g; ~. T# U* O' y8 E
, n1 f& I( D/ J2 ?; ?- v
9 z& J, u8 I* M9 L. D) \7 O( k
2 @  K( i# ?4 U& h) y% U
首先,我们可以使用Keil的设置选项,将IRAM2打勾,让编译器选择什么时候使用这个内存。显然,我们还可以将这两个地址修改一下,将IRAM1改为0x10000000,这样,编译器就会优先分配CCM内存。4 @* ]4 ?0 Z, r; d# h
# Y. v) ?9 b3 |1 u* T2 T

( R. e$ \/ X1 `& l$ ^9 F) t3 A7 \- `
我们来看看结果,在MAP文件中,表明确实使用了这段内存,但是因为我们使用的内存较少, 还没有用到CCM。
9 T. ?- I. G! R$ e* S
9 I! B: `; `# B4 ?
6 q6 G* u& S3 n  Q. H
" `( c0 S1 ]8 _这种自动分配的方式有什么问题呢?这段内存是内核专有的,除了内核任何其它总线都不能访问,这就意味着,一旦编译器将数据分配到CCM中,而同时使用了DMA访问,显然会出问题。
" P, u- x$ D/ C8 `$ m. m. m' K9 B, ~" P
于是我们就想到了自己分配这段内存,__attribute__((at(address)))这个语句就是专门干这事的,然后我们可以这么做:
0 N# \! Y* F( n; `6 p2 b- C
  • int vat[10] __attribute__((at(0x10000000))) = {1,2,3,4,5,6,7,8,9,10};3 x  E. {3 S0 z/ H3 M
1 J4 A* C0 v: \% C  Q+ N6 r8 `
[color=rgb(51, 102, 153) !important]复制代码

  F2 j& D3 f. ?$ _9 f9 G. T) |
再次编译以后,发现确实如我们所愿,我们将一段数据放在在了CCM内存中:
/ U  V6 Q( v7 }2 U; i+ Q* V% x
  •     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

  • & x/ B1 s4 q# k8 t1 A+ S
- g  z5 z6 j! z% d  e
[color=rgb(51, 102, 153) !important]复制代码

9 S3 P" T" W2 q% k  R7 Z- I1 \' Z6 k, }* K
太好了,那么我们能不能将FreeRTOS的数据放进CCM中呢?将FreeRTOS要使用的内存全部移到CCM中,使其成为专有内存,显然会提高FreeRTOS的运行速度。' z" R, G" k# w
9 [8 N* V5 J' E
那么怎么放?首先我们想到了heap4.c这个文件当中有这么一段:. L+ c; {, i: T# y$ A  X# \
  • /* 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 */8 [9 v2 f; L$ j+ }: Q. S) W4 h
# n. r  W$ z  _6 m! Z" Q
[color=rgb(51, 102, 153) !important]复制代码

3 g4 h; |' I2 X这是FreeRTOS中堆内存的分配,我们可以加入__attribute__将其放进CCM中,这样做没有问题,但是去修改FreeRTOS的源代码显然不是明智之举。事到如今,我们只能自己定义链接器的储存器映射了。2 ^$ B4 N- A7 U/ c* X! _
6 t: ~  P# i% `7 j- c% B6 s
修改Keil的Linker选项,我们把Use Memory Layout from Targer Dialog的钩去掉。
6 S/ o) m! U. s, O1 l: \0 P6 K2 s7 n  s+ [% s% \! `8 {* g& Y
" P3 K: _, f$ Q& \
$ Y. y8 f$ ?; q( M
然后在Objects的目录中找到一个后缀为sct的文件,打开之后如图所示:7 q3 E. |* g  I0 R5 d
: j: u1 f8 V9 [2 x/ T( P  b9 z

1 ]0 k+ ~! g, [4 E7 j( Z6 E6 w( R) r5 P: I: S% {
由于我们只需要将RTOS的数据放入CCM中,于是我们可以这样修改,CCM_IRAM的名字是我自己取的,你可以改成任何你喜欢的,比如什么LOVEYOU之类的:
. H, k% R" W5 T/ h. D  E( ^4 g6 n

& ]( h* V" `9 O$ Z
8 Q9 u# M* H% v/ t  f8 L6 B然后在链接器中选择我们自己的文件:
- }$ Q4 V: D: I+ b% h9 ~! V7 F1 D$ H) B' M/ |7 u

( x1 m* i7 q% `; D6 C1 ^. W+ G, l& X; Y, y2 V3 \$ B
现在,映像文件变成了这样:
; {9 n: w5 w, M7 Q
' h4 A" x; q) ^* ^# b2 n& V4 e# Y0 ~
0 J. J) Y' a+ j# U; E( y
是不是很简单呢?系统堆栈仍然在主内存中,而FreeRTOS的堆内存已经移到了CCM中,由于互不影响,这里我分配了50K的空间专门给FreeRTOS使用。我们甚至还可以配置MPU将这段内存配置为特权级,避免一般任务修改等等,怎么使用,那就是你的事了。

" C/ P, J- t6 @# {! N: i/ y/ F: I
赞 收藏 评论0 发布时间:2022-1-11 19:52

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版