【发布时间】:2017-09-05 13:36:18
【问题描述】:
有人可以帮忙吗?
总而言之:声明和初始化变量在 PIC 硬件中不起作用——而在仿真中却可以正常工作。此外,如果变量是结构,这个问题似乎更糟。我正在使用:带有 PICKIT3 调试器电缆的 Explorer 8 板上的 MPLAB X IDE V3.55、XC8 V1.41、PIC18F26K40。
详情:
对于一个简单的情况,例如:
uint8_t myvar = 0x55;
void main(void)
{
uint8_t var = myvar;
}
当我在硬件中运行它时,使用调试器 myvar 中的变量窗口始终为零。但是,如果我在模拟器中运行相同的代码,那就没问题了!
我有:
- 将问题分解为重现问题的最简单形式
- 尝试禁用编译器优化 - 无法解决此问题
检查“文件寄存器”调试器窗口中的值。在硬件中运行时我看不到 0x55 - 但它在模拟器中(地址 0x21)。
如果满足以下条件,它确实可以在硬件中工作:
- myvar 被声明并初始化为 const
- myvar 在本地(main 内部)声明和初始化
现在,如果我使用结构类型而不是简单的 uint8_t,例如:
typedef struct {
uint8_t a;
char b[8];
}MYSTRUCT;
MYSTRUCT ms = { 0x55, "HELLO" };
void main(void)
{
uint8_t var = ms.a;
}
ms 变量在模拟中正确初始化,但在硬件中没有。如果变量在 main 中声明或作为全局声明,这一次它不会初始化。同样,声明为 const 确实有效。 所以这里似乎有不一致的地方:
uint8_t struct type
global variable declaration and initialisation N N
global const declaration and initialisation Y Y
local variable declaration and initialisation Y N
在调试并单步执行汇编程序 (.as) 文件后,看起来 myVar 正在尝试初始化,但由于某种原因,它并没有在硬件中。 请参阅下面 .as 文件中的相关行。关键阶段的地址和值显示为在仿真期间从调试器捕获的。您可以在末尾看到“__pdataCOMRAM”(指向 myVar 的 ram 的指针)分配了 0x55。如果我在硬件中逐步执行此操作,所有步骤都是相同的,但是当我们走到最后时,'__pdataCOMRAM' 的值不是 0x55,而是 0x00。
Address Value
global __pdataCOMRAM
__pdataCOMRAM:
file "main.c"
line 32
global _myVar
myVar: 0x21 0x00
ds 1
file "dist/C18_18F87K22/debug\initTest.X.debug.as"
line #
psect cinit
; Initialize objects allocated to COMRAM (1 bytes)
global __pidataCOMRAM 0x144 0xff55
; load TBLPTR registers with __pidataCOMRAM
movlw low (__pidataCOMRAM)
movwf tblptrl
movlw high(__pidataCOMRAM)
movwf tblptrh
movlw low highword(__pidataCOMRAM)
movwf tblptru
tblrd*+ ;fetch initializer
movff tablat, __pdataCOMRAM+0 0x21 0x55
我是在做一些愚蠢的事情,还是缺少编译器选项,或者是编译器或调试器错误? 我想了解这个问题,以免在我的开发过程中进一步陷入任何陷阱。
干杯, 史蒂夫
【问题讨论】:
-
你应该看看你的链接器脚本,我想。据我所知,启动代码不会执行从 flash
.data部分到 ram 到 init 全局变量的复制。似乎所有全局变量都被视为.bss部分,因此在启动时归零。您是否尝试声明为静态uint8_t myvar = 0x55? -
这是一般微控制器编程中非常常见的错误。我不知道这个特定的工具链,但可能你已经创建了一个具有“最小启动”或“快速启动”或类似的项目。创建一个新项目,看看是否有一些名为“标准启动”、“ANSI 启动”或类似名称的选项。
-
优化编译器可以删除整个
uint8_t var = myvar;分配var因为var从未使用过。使用var做某事,无需使用调试器即可看到。 -
我已经尝试了“清除 bss”和“初始化数据”链接器选项的所有组合,但它们对这个问题没有影响。我正在用 C 编写,所以不认为我应该创建内存初始化文件。我可以看到 myVar 在 .as 和 lst 文件中被初始化为 0x55。实际上,这里确定的(程序)内存位置确实有 0x55 - 但它不在 ram 中,继续了解启动过程:)
-
查看生成的汇编代码并单步执行 myVar 正在尝试初始化,但由于某种原因没有 - 请参阅有问题的更新。
标签: c embedded microcontroller pic