本帖最后由 QianFan 于 2015-11-1 20:37 编辑 $ T* r# }* M3 ` ! v4 B7 U* ^: w3 h8 c Ubuntu下开发STM32已经接近尾声。如果不出意外的话,这篇将会是最后一篇了。突然有点心痛,毕竟,在也没有机会这么明目张胆的传图片,刷金币了。8 }& Y8 X/ P. h Newlib申请内存的机制7 e: @; Y+ ~$ h 这次介绍的是Newlib下的malloc。不同与keil mdk下的malloc。两者的实现机制是不同的。keil mdk是在汇编文件中改一个数值,用来设置堆的大小。今后的所有malloc申请的内存都在这个堆中。堆的大小是在编译的时候确定的,预先放入bss段中。而Newlib使用的是sbrk的机制。只要sbrk的申请的地址还没到当前sp的位置,就能一直申请。(代码图片是我在原先的基础上添加了点调试信息)2 V9 B) H) m' @- t+ Z9 F8 k) T end是bss段的结束地址。因为使用了extern char end asm("end")这样的语法,在编译的时候只能使用-std=gnu99,而不能使用-std=c99。stack_ptr是当前sp的值。只要上一次结束的地址加上这一次申请字节数的和不超过sp,sbrk就能成功。malloc也能成功。1 }$ V: M( t3 Z' D3 J sbrk相当于内存的经销商,malloc只是一个小贩。当有人向malloc请求内存的时候,如果malloc手中有剩余的内存并且足够这次分配,那就直接把手中剩余的内存分配出去。使用完内存之后,只要记得使用free还给malloc就行。如果申请的时候,malloc手中没有足够的内存,那么malloc会向sbrk要一块内存,自己再转手出售给其他的需要者。0 w% h: I# h" q# ~+ | ) P1 e9 v2 K' H6 d! z 内存分配测试* y9 s9 p/ g& ?, o 主函数中一直尝试无限制的分配内存,只分配不释放。将代码下载至SRAM中运行。(make sram,sudo make burns) 在内存分配之前,malloc分配的起始地址是536871400(0x2000_01E8),具体为什么是这个数值,在稍后会解释。进入main之前申请了436,1032字节(实际是428和1024字节,剩余8字节用于存储分配信息)。估计1K内存是用来给printf当缓冲区了。至于另外428字节不知道用作什么用了。0 `5 {+ H1 |1 W5 j' a, y 在170次内存之后,申请了17000个字节的空闲内存,共消耗17000+170*8=18360字节的内存。3 ?; o! R0 a* P# ^* F$ R0 M 到内存耗尽的时候,堆指针在0x2000_4F5C(536891120+108) 处。这个值差不多接近栈顶(0x2000_5000)了。 " f' D0 @. y; l9 V: A 给栈保留一定的内存$ e5 r/ a% K) h5 L 如果一直使用malloc分配内存的话,最终可能会导致栈的内存与堆的内存冲突。为了安全考虑,暂时考虑为栈保留一定的空间。在syscalls.c文件中添加一个可配置的宏,用于确定可保留的大小。这个数值可以在syscalls.c文件中更改,也可以在编译的时候使用-D来更改。这里保留了2K的空间给栈。/ {/ H2 E' @/ l( L 内存布局 可能你会疑问为什么malloc内存分配是从0x2000_01E8开始的,为什么链接文件中定义了_Min_Stack_Size,这里却还要为栈保存空间。虽然在SRAM中运行程序一节https://www.stmcu.org.cn/module/forum/thread-603793-1-1.html中也简单的提到了一些,这里打算详细的说一下。 在链接的时候,我添加了参数-Wl,-Map=flash_sram.map,用来记录代码或者数据的布局。打开文件可以看到这样的信息:) s( l8 p* W$ E4 _5 a: S* @ 从Map文件上看,bss段(未赋值的变量)是从0x2000_00a4开始的。(从0x2000_0000开始到0x2000_00a4之间的数据是用来存放已赋值的变量。)在bss段的结束地址(end)之后,有根据_Min_Heap_Size,_Min_Stack_Size保留的内存区。这两片内存去并没有什么作用,只是用来保证bss段不至于过大而已。8 W# \- W* d3 E: \% i 从sbrk的输出上也能够看出来,malloc进行内存分配的时候是从bss段的结束,也就是end地址处开始的。显然malloc的内存分配能够覆盖_Min_Heap_Size和_Min_Stack_Size。 相关的代码在malloc_v2.zip中。/ [$ W9 b* s( ?# o7 D8 c 相关Newlib系统调用的更多信息请参考:8 T5 `, P D# r5 `4 |* z! K
* L. o6 o f2 O4 E' T |
橙哥,一块交流啊
我用的是desktop版本。你说的驱动是stlink吗?
是的。你发给我的stlink驱动包,和我下载的完全一样。在server下运行报一样的错误。看你的截图应该是在desktop的配色下编写的,所以我抽空换成desktop试试。。
可能是这个原因。不知道你的libusb安装了没有
make[2]: Nothing to be done for 'install-data-am'." }% v8 ~7 J: W
% l0 A2 | ]( {( Q3 `
不知道安装是否成功了。先继续往下配置看看。
事实st-flash看看有反映吗
应该不是吧。我的是4。8。4
aoems@ubuntu:~$ st-flash 9 I7 c, Q* @, b1 T4 r
invalid command line
stlinkv1 command line: ./st-flash [--debug] [--reset] {read|write} /dev/sgX path addr <size>( K$ w! O1 t) ^1 ^1 d' x' {
stlinkv1 command line: ./st-flash [--debug] /dev/sgX erase# h* P& h$ Q9 j3 t' O- v
stlinkv2 command line: ./st-flash [--debug] [--reset] {read|write} path addr <size>* \% j" l2 L0 K
stlinkv2 command line: ./st-flash [--debug] erase1 V9 S0 ?% A8 k5 p) ?
use hex format for addr and <size>
aoems@ubuntu:~$
5 ?6 M v+ a3 G0 R+ w) @7 @" i j
对的,这就说明安装成功了。