3.有关堆的初始化及xxx_stm32.map文件的思考 //依据RT-Thread内核编程的学习记录(非内核实现)

堆栈,是我们常常会听说过的词汇。搞嵌入式如果说不懂得堆栈可能会被怀疑学习了一个假的嵌入式。不过,坦白来说,我还是不太理解其中的细节,比如说栈的位置在哪?我们说栈是先进后出FILO形式的数据结构,堆是先进FIFO先出的形式的数据结构。栈是由系统操作的,而堆是由程序员操作的。我感觉这些解释都是玄而又玄的说法,我现在还没有理清头绪,以后有具体头绪了再来写出我的想法。现在先学习大佬的想法:

  1. 栈经常与 sp 寄存器(译者注:"stack pointer",了解汇编的朋友应该都知道)一起工作,最初 sp 指向栈顶(栈的高地址)。
  2. CPU 用 push 指令来将数据压栈,用 pop 指令来弹栈。当用 push 压栈时,sp 值减少(向低地址扩展)。当用 pop 弹栈时,sp 值增大。存储和获取数据都是 CPU 寄存器的值。
  3. 当函数被调用时,CPU使用特定的指令把当前的 IP (译者注:“instruction pointer”,是一个寄存器,用来记录 CPU 指令的位置)压栈。即执行代码的地址。CPU 接下来将调用函数地址赋给 IP ,进行调用。当函数返回时,旧的 IP 被弹栈,CPU 继续去函数调用之前的代码。
  4. 当进入函数时,sp 向下扩展,扩展到确保为函数的局部变量留足够大小的空间。如果函数中有一个 32-bit 的局部变量会在栈中留够四字节的空间。当函数返回时,sp 通过返回原来的位置来释放空间。
  5. 如果函数有参数的话,在函数调用之前,会将参数压栈。函数中的代码通过 sp 的当前位置来定位参数并访问它们。
  6. 函数嵌套调用和使用魔法一样,每一次新调用的函数都会分配函数参数,返回值地址、局部变量空间、嵌套调用的活动记录都要被压入栈中。函数返回时,按照正确方式的撤销。
  7. 栈要受到内存块的限制,不断的函数嵌套/为局部变量分配太多的空间,可能会导致栈溢出。当栈中的内存区域都已经被使用完之后继续向下写(低地址),会触发一个 CPU 异常。这个异常接下会通过语言的运行时转成各种类型的栈溢出异常。(译者注:“不同语言的异常提示不同,因此通过语言运行时来转换”我想他表达的是这个含义) 

https://blog.csdn.net/henryzhang2009/article/details/44863295具体内容可以参看这个博客

不过在本次的内容中,不对栈做研究,只讨论堆的话题。例如:在RT-Thread下堆是怎么使用的?以及如何从xx.map中获取有关数据?

/* 线程入口 */
void thread1_entry(void *parameter)
{
    int i;
    char *ptr = RT_NULL; /* 内存块的指针 */
		char a = 40,b = 40,flag;                //堆空间申请,所支持两个参数
		
    for (i = 0; ; i++)
    {
        if(i == 0)
        {
            ptr = rt_malloc(1);
            rt_kprintf("malloc get memory :%d byte\n", 1);
            flag = 0;
        }
        /* 每次分配 (1 << i) 大小字节数的内存空间 */
        ptr = rt_realloc(ptr,1 << i);
//		ptr = rt_malloc(1 << i);
        /* 如果分配成功 */
        if (ptr != RT_NULL)
        {
			if(flag == 0)
                rt_kprintf("rt_malloc get memory :%d byte\n", (1 << i));
			else
				rt_kprintf("rt_realloc get memory :%d byte\n",(1 << i));
            /* 释放内存块 */
            //rt_free(ptr);
            rt_kprintf("free memory :%d byte\n", (1 << i));
            ptr = RT_NULL;
        }
        else
        {
            rt_kprintf("try to get %d byte memory failed!\n", (1 << i));
            return;
        }
		rt_thread_mdelay(1000);
		rt_free(ptr);
    }
		
//		ptr = rt_calloc(a,b);
//		if(ptr != RT_NULL)
//		{
//			rt_kprintf("rt_calloc get memory : %d byte\n",a*b);
//			rt_free(ptr);
//			rt_kprintf("free memory :%d byte\n",a*b);
//		}
//		else
//		{
//			rt_kprintf("Failed to try to get %d byte\n",a*b);
//			return ;
//		}
}

内存的申请函数:

rt_malloc(xx);

rt_realloc(xx,xx);

rt_calloc(xx,xx);

内存的删除函数:

rt_free(xx);

在学习过程中,有一个初步接触得东西xx.map文件

双击这个,就可以得到rtthread-stm32.map的文件。

RO RW ROM的具体意义

Program Size: Code=908 RO-data=320 RW-data=0 ZI-data=1024

Code:指代码的大小;

Ro-data:指除了内联数据(inline data)之外的常量数据;

RW-data:指可读写(RW)、已初始化的变量数据;

ZI-data:指未初始化(ZI)的变量数据;

Code、Ro-data:位于FLASH中;

RW-data、ZI-data:位于RAM中;

提醒:RW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM中。

map文件的具体意义,请参看:

http://blog.csdn.net/ybhuangfugui/article/details/75948282

猜你喜欢

转载自blog.csdn.net/xiangxistu/article/details/82776732