4,最后说说,STM32内存的问题。
还是以附件工程为例,在前面第一个图,程序总共占用内存:20+2348字节,这么多内存,到底是怎么得来的呢?
我们可以双击Project侧边栏的:Targt1,会弹出test.map,在这个里面,我们就可以清楚的知道这些内存到底是怎么来的了。在这个test.map最后,Image 部分有:
==============================================================================
Image component sizes
Code (inc. data) RO Data RW Data ZI Data Debug Object Name
172 10 0 4 0 995 delay.o//delay.c里面,fac_us和fac_ms,共占用4字节
112 12 0 0 0 427 led.o
72 26 304 0 2048 828 startup_stm32f10x_hd.o //启动文件,里面定义了Stack_Size为0X800,所以这里是2048.
712 52 0 0 0 2715 sys.o
348 154 0 6 0 208720 test.o//test.c里面,stack_dir和cpu_endian 以及*addr ,占用6字节。
384 24 0 8 200 3050 usart.o//usart.c定义了一个串口接收数组buffer,占用200字节。
----------------------------------------------------------------------
1800 278 336 20 2248 216735 Object Totals //总共2248+20字节
0 0 32 0 0 0 (incl. Generated)
0 0 0 2 0 0 (incl. Padding)//2字节用于对其
----------------------------------------------------------------------
Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name
8 0 0 0 0 68 __main.o
104 0 0 0 0 84 __printf.o
52 8 0 0 0 0 __scatter.o
26 0 0 0 0 0 __scatter_copy.o
28 0 0 0 0 0 __scatter_zi.o
48 6 0 0 0 96 _printf_char_common.o
36 4 0 0 0 80 _printf_char_file.o
92 4 40 0 0 88 _printf_hex_int.o
184 0 0 0 0 88 _printf_intcommon.o
0 0 0 0 0 0 _printf_percent.o
4 0 0 0 0 0 _printf_percent_end.o
6 0 0 0 0 0 _printf_x.o
12 0 0 0 0 72 exit.o
8 0 0 0 0 68 ferror.o
6 0 0 0 0 152 heapauxi.o
2 0 0 0 0 0 libinit.o
2 0 0 0 0 0 libinit2.o
2 0 0 0 0 0 libshutdown.o
2 0 0 0 0 0 libshutdown2.o
8 4 0 0 96 68 libspace.o //库文件(printf使用),占用了96字节
24 4 0 0 0 84 noretval__2printf.o
0 0 0 0 0 0 rtentry.o
12 0 0 0 0 0 rtentry2.o
6 0 0 0 0 0 rtentry4.o
2 0 0 0 0 0 rtexit.o
10 0 0 0 0 0 rtexit2.o
74 0 0 0 0 80 sys_stackheap_outer.o
2 0 0 0 0 68 use_no_semi.o
2 0 0 0 0 68 use_no_semi_2.o
450 8 0 0 0 236 faddsub_clz.o
388 76 0 0 0 96 fdiv.o
62 4 0 0 0 84 ffixu.o
38 0 0 0 0 68 fflt_clz.o
258 4 0 0 0 84 fmul.o
140 4 0 0 0 84 fnaninf.o
10 0 0 0 0 68 fretinf.o
0 0 0 0 0 0 usenofp.o
----------------------------------------------------------------------
2118 126 42 0 100 1884 Library Totals //调用的库用了100字节。
10 0 2 0 4 0 (incl. Padding) //用于对其多占用了4个字节
----------------------------------------------------------------------
Code (inc. data) RO Data RW Data ZI Data Debug Library Name
762 30 40 0 96 1164 c_w.l
1346 96 0 0 0 720 fz_ws.l
----------------------------------------------------------------------
2118 126 42 0 100 1884 Library Totals
----------------------------------------------------------------------
==============================================================================
Code (inc. data) RO Data RW Data ZI Data Debug
3918 404 378 20 2348 217111 Grand Totals
3918 404 378 20 2348 217111 ELF Image Totals
3918 404 378 20 0 0 ROM Totals
==============================================================================
Total RO Size (Code + RO Data) 4296 ( 4.20kB)
Total RW Size (RW Data + ZI Data) 2368 ( 2.31kB) //总共占用:2248+20+100=2368.
Total ROM Size (Code + RO Data + RW Data) 4316 ( 4.21kB)
==============================================================================
通过这个文件,我们就可以分析整个内存,是怎么被占用的,具体到每个文件,占用多少。一目了然了。
5,最后,看看整个测试代码:
main.c代码如下,工程见附件。
[objc] view plain copy#include “sys.h”
#include “usart.h”
#include “delay.h”
#include “led.h”
#include “beep.h”
#include “key.h”
//ALIENTEK战舰STM32开发板堆栈增长方向以及CPU大小端测试
//保存栈增长方向
//0,向下增长;1,向上增长。
static u8 stack_dir;
//CPU大小端
//0,小端模式;1,大端模式。
static u8 cpu_endian;
//查找栈增长方向,结果保存在stack_dir里面。
void find_stack_direction(void)
{
static u8 *addr=NULL; //用于存放第一个dummy的地址。
u8 dummy; //用于获取栈地址
if(addr==NULL) //第一次进入
{
addr=&dummy; //保存dummy的地址
find_stack_direction (); //递归
}else //第二次进入
{
if(&dummy》addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的。
else stack_dir=0; //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的。
}
}
//获取CPU大小端模式,结果保存在cpu_endian里面
void find_cpu_endian(void)
{
int x=1;
if(*(char*)&x==1)cpu_endian=0; //小端模式
else cpu_endian=1; //大端模式
}
int main(void)
{
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,9600); //串口初始化为9600
delay_init(72); //延时初始化
printf(“stack_dir:%x\r\n”,&stack_dir);
printf(“cpu_endian:%x\r\n”,&cpu_endian);
find_stack_direction(); //获取栈增长方式
find_cpu_endian(); //获取CPU大小端模式
while(1)
{
if(stack_dir)printf(“STACK DIRCTION:向上生长\r\n\r\n”);
else printf(“STACK DIRCTION:向下生长\r\n\r\n”);
if(cpu_endian)printf(“CPU ENDIAN:大端模式\r\n\r\n”);
else printf(“CPU ENDIAN:小端模式\r\n\r\n”);
delay_ms(500);
LED0=!LED0;
}
}
评论
查看更多