我尝试使用MC9S08QD4微控制器对分频器进行编程。它使用遵循HCS08指令集(documentation available here)的8位架构。
但是,为了在尽可能宽的范围内容纳输入频率,我一直在尝试使用double
和unsigned long
变量来存储诸如输入周期之类的属性信号。
我遇到的问题是:每当我为double
或long
变量分配值时,正确将值赋给该变量,但还会覆盖完全不相关的内存部分,从而破坏可能存储在那里的其他变量。一位同事建议这可能是因为它在计算过程中使用这些位置来存储中间值,如果是这样的话会非常奇怪。
这些是我正在使用的工具,作为本文其余部分的参考:
在我的代码的某些部分,我将可能较大的值分配给long
或double
个变量。通过"大"我的意思是大于16位值可以支持的值,但是在无符号32位整数或双精度可以支持的范围内。
如果我在执行这些赋值时检查局部/全局变量,我可以看到分配给的变量按预期分配,但其他变量也是如此。我也可以像这样检查内存,当我分配给这些变量时,我会看到任意和不同的位置被覆盖。
通过关注this guide,我已采取了我所知道的所有步骤,以确保支持使用大型/可能浮动的数据类型:
将S08链接器设置为包含ansis.lib
,它使用small HCS08
内存模型并支持32位浮点数和64位双精度数。
确保__NO_FLOAT__
不定义为预处理程序符号。
HCS08中的确保Use IEEE32 for double (default is IEEE64)
编译器设置不被选中(虽然对于我的用例,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;
}
在刷板后,我的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)
double a = 1000;
的说明看似合理,但double b = a + 2;
的说明涉及跳转导致非常深的兔子洞,而我无法从...回来。
任何关于为什么会发生这种情况的建议都会受到赞赏。
修改
我已经上传了我的真实项目here的内存映射文件(此帖子中没有足够的空间来直接包含它)。这是对那些暗示这是记忆力有限的问题的回应,我不相信这是正确的。
答案 0 :(得分:5)
这很可能是堆栈溢出。 HCS08QD4不是PC,它是一个非常低端的8位MCU,具有256字节的RAM(包括S08和#34;零页")并且没有FPU。在这256个字节中,默认情况下将为堆栈保留一小部分。大概80个字节左右?要确切知道多少,请检查链接器文件(.prm)。
单独的浮点库很可能只需要比你在片上可用的RAM更多的RAM。
作为拥有这些部件15年经验的人,以及Codewarrior编译器,我将非常诚实:为需要双精度浮点和32位的项目选择这样一个有限的MCU整数算术只是纯粹的废话。要么你为这个任务指定了一个完全错误的MCU,要么就是你刚才切换到嵌入式系统的某种PC程序员。无论哪种方式,你都无法让这个程序工作。
从规划开始,从头开始重新开始项目。