基础篇_03_堆的初始化及 map 文件

堆栈,是我们常常会听说过的词汇。搞嵌入式如果说不懂得堆栈可能会被怀疑学习了一个假的嵌入式。不过,坦白来说,我还是不太理解其中的细节,比如说栈的位置在哪?我们说栈是先进后出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.youkuaiyun.com/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.youkuaiyun.com/ybhuangfugui/article/details/75948282

### MATLAB m_map工具包概述 MATLAB的m_map工具包是一个用于地理空间数据可视化的强大插件,能够帮助研究人员和工程师创建高质量的地图图像以及处理地球科学相关的数据。该工具包提供了丰富的制图函数和支持多种地图投影方式。 #### 安装方法 为了安装m_map工具包,在官方网页上可以找到详细的指导说明[^1]。通常情况下,用户需要先访问[m_map官方网站](https://www.eoas.ubc.ca/~rich/map.html)[^1]下载最新版本的软件包。之后按照以下流程操作: - 将下载得到的压缩文件解压至MATLAB的工作目录下指定位置(通常是`toolbox`文件夹内)[^3]; - 打开MATLAB程序后通过菜单栏选择“设置路径”,接着点击“添加并包含子文件夹”选项来注册新加入的库路径; 完成上述步骤后可以通过命令窗口输入特定指令验证是否成功加载了此扩展模块,例如尝试运行简单的测试脚本来确认其正常工作状态。 #### 使用教程概览 对于希望深入了解如何利用m_map进行实际项目开发的学习者来说,网络上有不少资源可供参考学习。一较为全面的文章列举了一些基础的应用场景[^2],包括但不限于以下几个方面: - **绘制基本地图**:了解怎样快速生成世界范围内的空白底图作为后续工作的起点。 - **自定义样式调整**:掌握改变颜色方案、线条粗细以及其他视觉属性的方法以便更好地表达意图。 - **叠加气象要素分布**:学会表示诸如气温梯度变化趋势这样的复杂现象,比如制作温度场图表或描绘等温曲线。 - **增强图形细节表现力**:探索向现有作品里增添额外元素的技术手段,像标记重要地点坐标或是书写解释性文字标签。 - **应用不同色彩映射表(colormap)**:熟悉各类预设调色板的选择及其应用场景,从而让最终成果更加美观易读。 下面给出一段简单示例代码展示如何使用m_map初始化一张全球陆地板块轮廓的基础地图: ```matlab % 加载必要的m_map环境配置 load coastlines % 导入海岸线数据集 worldmap('World') % 创建覆盖整个星球的地图对象 geoshow(coastlat,coastlon,'Color','black'); % 绘制黑色边界的大陆边界 title('Global Landmass Outline Using M_MAP'); ``` 这段代码片段展示了几个核心特性——从加载外部地理特征到设定全局视窗再到渲染具体的几何形状,这些都是构建更复杂的GIS应用程序不可或缺的部分。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值