王昱顺 发表于 2025-3-11 19:55:24

讨论C251编译器的堆栈大小设置问题|START251.A51启动文件的设置

通过查询keil的帮助,可以得知默认堆栈设置为100H(256byte大小)


这部分也可以通过默认工程的map文件查看得到

所以,可以通过Keil安装目录下的C251/LIB/START251.A51文件修改后来设置堆栈大小
(注意,不要直接修改,需要拷贝一个副本到所需工程下,再修改,不同的单片机edata和xdata不同,所设置的也不同)
只有将START251.A51加入工程后才会生效这些设置

ai8051u的edata为2K(800H),这里同时保留edata一部分空间,设置堆栈最大为700H
相比原来扩大了7倍
这里给出修改后的START251.A51文件,只需要在Keil中,通过双击Source Group1添加START251.A51文件即可

如果名字不一样,可以随便找个最后一级的文件夹添加A51启动文件即可,编译时会自动添加的
需要注意START251.A51文件需要保存到工程目录下,最好跟main文件放在同一个目录下
以下是修改后的START251.A51文件,同时增加了XDATA部分的自动清零(默认情况XDATA上电没有清零是随机数据的)



这里测试一下,导入START251.A51文件

按下F7编译,output部分输出如下信息

然后再查看.map 文件,可以看到堆栈区域大小已经被拓展到了700H

当然这个时候我的edata使用和堆栈就互相冲突了,怎么解决呢?

点击这个小魔术棒,打开工程的配置

将内存模式改为Large(默认保存变量在xdata,不与堆栈抢edata)
再次编译
]
可以看到,实际使用的200byte左右变量都在xdata中了,此时edata被堆栈空间所占用了700H(1792byte)
这样就可以拓展堆栈空间了

国芯人工智能 发表于 2025-3-11 19:58:00

在讨论C251编译器的堆栈大小设置问题时,首先需要明确堆栈在嵌入式系统中的重要作用。堆栈用于存储函数调用的返回地址、局部变量以及中断服务例程的上下文信息。因此,合理设置堆栈大小对于系统的稳定性和性能至关重要。<br><br>### 默认堆栈大小的设置<br>根据Keil的帮助文档,C251编译器的默认堆栈大小为100H(即256字节)。这一设置可以在默认工程的.map文件中查看到。对于大多数小型嵌入式应用,256字节的堆栈可能足够,但对于较为复杂的应用,特别是涉及大量函数调用或中断处理的应用,这一默认值可能不足,导致堆栈溢出,进而引发系统崩溃。<br><br>### 修改堆栈大小的步骤<br>要修改堆栈大小,需通过修改`START251.A51`启动文件来实现。具体步骤如下:<br><br>1. **备份与拷贝**:首先,不要直接修改Keil安装目录下的`START251.A51`文件。建议将文件拷贝到工程目录下,并在副本中进行修改。这是因为不同的单片机在`edata`和`xdata`上的配置不同,堆栈大小的设置也需相应调整。<br><br>2. **堆栈大小的设置**:在`START251.A51`文件中,找到堆栈大小的定义部分。对于`ai8051u`单片机,`edata`为2K(800H)。为了保留一部分`edata`空间,建议将堆栈大小设置为700H。与默认的256字节相比,这一设置扩大了7倍,能够更好地满足复杂应用的需求。<br><br>3. **文件添加与编译**:将修改后的`START251.A51`文件添加到工程中。在Keil中,可以通过双击`Source Group1`来添加该文件。如果文件名不同,可以将文件放置在最后一级文件夹中,编译器在编译时会自动将其纳入。需要注意的是,`START251.A51`文件应保存在工程目录下,最好与`main.c`文件放在同一目录下,以确保编译时能够正确引用。<br><br>### 注意事项<br>- **堆栈大小的合理性**:虽然增加堆栈大小可以提高系统的稳定性,但过大的堆栈会占用宝贵的内存资源,影响系统的整体性能。因此,在设置堆栈大小时,需根据具体应用的需求进行权衡。<br><br>- **不同单片机的配置**:不同单片机的内存配置(如`edata`和`xdata`)不同,因此在修改堆栈大小时,需根据具体单片机的内存布局进行调整。<br><br>- **调试与验证**:在修改堆栈大小后,建议通过调试工具(如Keil的调试器)验证堆栈的使用情况,确保没有堆栈溢出的风险。<br><br>### 总结<br>通过合理设置`START251.A51`文件中的堆栈大小,可以有效提升C251编译器在嵌入式系统中的性能和稳定性。对于`ai8051u`单片机,建议将堆栈大小设置为700H,以应对复杂的应用场景。在修改过程中,需注意备份原文件、根据单片机的内存配置进行调整,并通过调试工具进行验证,以确保系统的稳定运行。<br><br>通过以上步骤,开发者可以灵活地调整堆栈大小,以满足不同应用的需求,从而优化系统的整体性能。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]

zhaoye818 发表于 2025-3-12 07:30:35

{:qiang:}

神农鼎 发表于 2025-3-12 11:25:10

内部又研究了下,给出如下看法:
对于Ai8051U-32位的C语言程序,如无特殊需求,堆栈是不用用户设置的。
首先,编译器会将堆栈的起始地址设置在用户代码中实际使用的edata结束的位置
比如:用户代码中实际使用了1K字节的edata,则编译器会将堆栈指针SPX设置为0x3FF
Ai8051U-32的内部有2K的edata,从0x400~0x7FF的edata全部都是堆栈,
虽然编译器默认只保留了256字节,但实际程序运行是超过了256,也不会有任何问题
除非程序中有使用绝对地址访问edata,否则用户代码使用的edata和堆栈不会有任何冲突

总结:
程序中如果需要定义比较大的数组,建议单独使用xdata关键字将数组分配到xdata区域,
比如:int xdata buffer;
memory model还是尽量使用官方建议的XSmall模式

页: [1]
查看完整版本: 讨论C251编译器的堆栈大小设置问题|START251.A51启动文件的设置