请选择 进入手机版 | 继续访问电脑版

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

【经验分享】STM32H7 内存管理实验将内存使用率上传至PC 以及硬件调试算法的小经验

[复制链接]
STMCU小助手 发布时间:2021-12-19 15:00
移植一些算法到STM32上,算法在PC上能够运行,而移植到STM32的时候就会出现问题,' J6 D) m* N( k  i9 l
$ ~( j1 w0 r' U( a1 V1 k: G6 ]
总结来说主要是因为编译器的版本不同,MDK5的编译器是很古老的编译器,有些C语法会有问题。
* E0 t) r) W: L; U; @1 ]8 n$ C
; }& {" Z0 C/ l; i# H- x9 ?
20180930123654334.png

/ f/ d2 j) a8 I3 Y9 y+ F% O$ `
: n* Z4 [1 ~# T% y4 l& O. ~1 Z8 F4 L. E6 y8 ^
常见的问题就是:( H% \& L" j. {0 ^8 [
9 P$ J7 d0 j6 K% `+ }
1.结构体赋值的时候,在32里面的代码,结构体赋值必须要一个变量一个变量的赋值,不能够直接赋值。
" A7 V0 y, U% V- `+ X2 X
9 D5 h1 I: f6 t4 o2.定义变量的时候不能用的时候才定义变量,需要将变量放在这个模块的前面3 n$ H- |5 i) W

/ w6 ^) R( p  A8 w将算法移植到STM32的时候,首先要考虑的就是STM32的内存大小是否足够大,如果不够大,一般就是报有.ANY的一些错误。(所以建议一开始移植算法的时候使用比较好的硬件条件来移植,不然后面出了问题可能都不知道到底在哪里出错了), F+ E. Z' |( b
如果定义的数组太大,超出了STM32堆栈的大小,那么STM32就会进入Hardfault。(因为进入Hardfault会有延时一行代码,所以建议查看Hardfault的时候建议使用上一盘中JTAG调试窗口中查看中断的窗口,能够更明白的清除Hardfault在哪里产生的)
* B' o: D4 E; A! q
+ N* R' i2 R, T( R+ {6 _8 O) P
20180930123935701.png

2 V9 W2 C9 ~  x. S: J! ~& J' b
4 B: I5 a1 }! q1 d调试算法一定要善用汇编语言,用汇编语言看C语言的本质.
& H: u2 ?2 @6 [0 b
20180930124204227.png
$ e( A. i8 R- `+ }# o; q! O

' R* y6 K* q/ |2 Q移植算法的时候也经常需要使用动态内存分配,STM32自带的SRAM又很小,很难满足算法需要的SRAM要求,所以需要在32中外扩SRAM芯片。既然需要动态内存分配,自然也就需要内存管理了。在STM32中c语言标准动态内存分配的关键字malloc也就没这么好用了,最好就是要使用正点原子的内存管理使用,用它提供的分配函数来进行内存的分配与管理。
, x" K+ ^) L0 G$ ~* c0 J* S
" R' K1 C( ?7 Q- ~' n好了,说了这么多,终于说到了标题的内存了,在调试内存管理的时候,为了防止有申请的内存溢出堆栈的大小,因此在申请的时候最好每一步都调用一次的内存使用率函数查看一下现在内存占用率。防止堆栈溢出。而且在运行的时候,最好能够清楚的了解到这个分配程序是在哪一个文件的哪一行,这样能够方便我们的调试。+ V+ B: n7 r0 Z5 Y$ P! J

& _, g! G& P7 Y; K) ~这个函数的演示效果:+ j2 g& o0 V/ C  w- W

( Z6 W0 y2 D+ q$ ]2 x) M- E, y
2018093012435772.png
; x7 d  i& \5 f4 v8 \
3 B8 p  U, L  m, l- f1 k& H0 W
分享一下H7将内存使用率和获取到这个函数在哪一行上传到串口的函数。(即实现上面效果的函数)) u+ F( @, p% L) l. i+ o) ^" I
% E2 R8 x/ t& ]8 S- R9 h" Q7 ~
.c文件中的上传代码:
+ G( _$ T! ]# N* ?- y- Y/ A# J! o8 K6 {' e, l) A1 M/ v
  1. void _uart_send_memused(const char *fileName, int line, u8 memx)
    ) }& I2 _9 L0 G- T1 [3 s) B  ?
  2. {$ W3 w9 {- u4 v6 n# H# [; R" W4 t
  3. static const char* TEXT[4] = {"SRAMIN", "SRAMEX", "SRAM12", "SRAM4"};' p5 M' @, ~  ~/ F7 A4 u. H6 {5 O

  4. 2 `6 H% i- v* e3 `& g
  5. u16 FingerVeinRun_memused=0;* }! g8 \- {; X5 d) l
  6. u8 paddr[20];  6 l# G0 s) j9 t4 N; d, S
  7. u8 send_cnt = 0;
      P: ^  j/ K% G: B3 [1 a
  8. printf("%s: ", TEXT[memx]);
    : Y9 W$ |# ~  ]# D( Z) ^
  9. " V0 k3 u  N- S4 b. D: s
  10. FingerVeinRun_memused = my_mem_perused(memx);& `7 i3 I9 F3 p; o
  11. sprintf((char*)paddr,"%d.%01d%%",FingerVeinRun_memused/10,FingerVeinRun_memused%10);% W9 n* n, k1 [4 O

  12. % }/ n! l# P/ s  m+ r( S
  13. for(send_cnt=0; send_cnt<=4; send_cnt++)
    0 k+ v( q' P! V* _" ]" S6 t
  14. {  . h* S  ]. C4 F" w( {  H
  15.     USART1->TDR = paddr[send_cnt];      5 D) c0 p! \1 Q; X
  16.     //等待发送结束/ [, E2 x/ F4 \9 ], T
  17.     while((USART1->ISR & 0X40) == 0);
    : ~; A5 I5 M0 `( N
  18. }
    2 p" n' P+ f3 H# X3 l
  19. 8 |5 \* S0 R# D# y2 P, R
  20. printf("\t%s\t%d", fileName, line);9 D( `1 G0 b% O+ f+ U
  21. printf("\r\n");
    ' G; Y% j& V1 B% U
  22. }
复制代码
/ F5 O! s: ~: g0 _) Z) E$ |( n' x9 ^+ h
在.h中需要添加的一个宏定义。
) T. W8 T, M* e: f( r2 \
  U. @* n1 j; n7 @7 d& |
  1. #define uart_send_memused(memx) _uart_send_memused(__FILE__, __LINE__, memx)
复制代码
4 r! R) a4 u0 M3 K+ h+ U. }$ {, r0 h
5 m. P! N8 _$ E+ H  `3 H- k0 Q
获取到文件名和行数不单单只可以在内存管理函数中使用,也可以看你个人的需求移植到其他的地方。
5 V1 T$ |7 x+ P- }) g0 J: N. v- C- `) s$ h1 C, x" C% z

& b  Y" Q5 u0 |+ S
收藏 评论0 发布时间:2021-12-19 15:00

举报

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