Tag*_*agc 4 c memory microcontroller
我正在尝试使用MC9S08QD4微控制器对分频器进行编程.它使用遵循HCS08指令集的8位架构(此处提供文档).
但是,为了在尽可能宽的范围内容纳输入频率,我一直在尝试使用double
和unsigned long
变量来存储诸如输入信号周期之类的属性.
我遇到的问题是:每当我为值double
或long
变量赋值时,它都会正确地将值赋给该变量,但也会覆盖完全不相关的内存部分,从而破坏可能存储在那里的其他变量.一位同事建议这可能是因为它在计算过程中使用这些位置存储中间值,如果是这样的话,这将是非常奇怪的.
这些是我正在使用的工具,作为本文其余部分的参考:
在我的代码的某些部分我给你潜在的较大值long
或double
变量."大"我的意思是大于16位值可以支持的值,但是在无符号的32位整数或双倍可以支持的范围内.
如果我在执行这些赋值时检查局部/全局变量,我可以看到我分配的变量按预期分配,但其他变量也是如此.我也可以像这样检查内存,当我分配给这些变量时,我会看到任意和不同的位置被覆盖.
通过遵循本指南,我已经采取了我所知道的所有步骤,以确保支持使用大型/可能浮动的数据类型:
将S08链接器设置为include ansis.lib
,它使用small HCS08
内存模型并支持32位浮点数和64位双精度数.
确保的__NO_FLOAT__
是不限定为预处理器符号.
Use IEEE32 for double (default is IEEE64)
在HCS08中确保编译器设置未被选中(虽然对于我的用例,32位双精度很好).
确保所有数据类型都是预期的大小HCS08 Compiler -> Type Sizes
.
我还验证了变量在生成的映射文件和变量调试屏幕中分配了正确的内存量.
SSCCE
在我设置的虚拟项目中,我已经能够使用非常少量的代码轻松地重现这个问题:
static double temp = 0;
static double temp2 = 0;
static double temp3 = 0;
void main(void)
{
double a = 1000;
double b = a + 2;
temp = 1;
temp2 = temp + 2;
temp3 = temp2 + 3;
}
Run Code Online (Sandbox Code Playgroud)
在刷新电路板后,我的IDE看起来像这样:
到现在为止还挺好.全局变量初始化为0,局部变量具有不确定的值,因为尚未分配它们.从第一行开始,我看到a
已正确分配,没有任何问题:
再踏上一行,我发现赋值b
成功但损坏了我的全局变量:
拆卸
下面是前两行代码的反汇编main
.我在概述中链接了HCS08指令集.
5 void main(void)
f092: A7F0 AIS #-16
7 double a = 1000;
f094: 5F CLRX
f095: 8C CLRH
f096: 9EFF07 STHX 7,SP
f099: 9EFF05 STHX 5,SP
f09c: 454000 LDHX #0x4000
f09f: 9EFF03 STHX 3,SP
f0a2: AE8F LDX #0x8F
f0a4: 9EFF01 STHX 1,SP
8 double b = a + 2;
f0a7: 95 TSX
f0a8: CDF4F1 JSR 0xF4F1 _DADD_RC (0xf4f1)
f0ab: 40 NEGA
f0ac: 000000 BRSET 0,0x00,*+3 main+0x15 (0xf0af)
f0af: 000000 BRSET 0,0x00,*+3 main+0x15 (0xf0b2)
f0b2: 00AF08 BRSET 0,0xAF,*+11 main+0x26 (0xf0bd)
f0b5: CDF13A JSR 0xF13A _POP64 (0xf13a)
Run Code Online (Sandbox Code Playgroud)
double a = 1000;
看起来合理的说明,但那些double b = a + 2;
涉及跳跃导致我无法返回的非常深的兔子洞.
关于为什么会发生这种情况的任何建议都将受到赞赏.
编辑
我上传了我的真实项目的内存映射文件在这里(在这个岗位留给直接包括它没有足够的空间).这是对那些暗示这是内存有限的问题的回应,我认为这是不正确的.
这很可能是堆栈溢出.HCS08QD4不是PC,它是一个非常低端的8位MCU,具有256字节的RAM(包括S08"零页")而且没有FPU.在这256个字节中,默认情况下将为堆栈保留一小部分.大概80个字节左右?要确切了解多少,请检查链接器文件(.prm).
最有可能的是浮点库本身需要的内存比你在芯片上可用的内存要多.
作为拥有这些部件15年经验的人,以及Codewarrior编译器,我将非常诚实:为需要双精度浮点和32位整数运算的项目选择这样一个有限的MCU只是纯粹的废话.要么你为这个任务指定了一个完全错误的MCU,要么就是你刚才切换到嵌入式系统的某种PC程序员.无论哪种方式,你都无法让这个程序工作.
从规范开始,从头开始重新开始项目.