Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/arduino/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging Arduino/AVR ATmega微控制器,随机复位、跳跃或变量/数据损坏_Debugging_Arduino_Microcontroller_Avr_Atmega - Fatal编程技术网

Debugging Arduino/AVR ATmega微控制器,随机复位、跳跃或变量/数据损坏

Debugging Arduino/AVR ATmega微控制器,随机复位、跳跃或变量/数据损坏,debugging,arduino,microcontroller,avr,atmega,Debugging,Arduino,Microcontroller,Avr,Atmega,我认为Arduino/AVRs MCU的许多程序员可以分享一些知识 我的具体问题是: 在我的例子中,在Atmel Atmega128 AVR上。 基于ADC数据,我运行了一个循环,在串行控制台中进行一些计算,它还驱动了一个中断 发生的事情是,当我使用一定量的串行输出时,程序突然变得非常不稳定。 代码内的随机跳跃、随机未知中断、随机变量损坏、未设置MCU寄存器位的随机重置。 在特定点添加缓冲区解决了不稳定性问题。 改变gcc的优化参数也改变了行为,没有优化,代码相当稳定 检查我的答案,找出可能的原

我认为Arduino/AVRs MCU的许多程序员可以分享一些知识

我的具体问题是:
在我的例子中,在Atmel Atmega128 AVR上。
基于ADC数据,我运行了一个循环,在串行控制台中进行一些计算,它还驱动了一个中断

发生的事情是,当我使用一定量的串行输出时,程序突然变得非常不稳定。
代码内的随机跳跃、随机未知中断、随机变量损坏、未设置MCU寄存器位的随机重置。
在特定点添加缓冲区解决了不稳定性问题。
改变gcc的优化参数也改变了行为,没有优化,代码相当稳定


检查我的答案,找出可能的原因和真正的原因。

有很多陷阱,这些都是一些卑鄙的陷阱:

1)突然重置可能有多种原因。 您的AVR可能运行的电压过低,要么降低频率,要么增加电压。检查数据表,他们有一个图表,他们对此很认真:)

2)另一个潜在问题是未处理的中断,您必须处理每个中断,因为未知IRQ将导致立即重置。
我喜欢将此代码添加到一个特殊的“捕获所有”ISR中,该ISR捕获所有未处理的IRQ

ISR(BADISR_vect)
{

    for (;;) UDR0='!';
}
这个片段将写大量的!进入UART。或者,您可以让LED闪烁,等等。只需确保不要从那里返回,因为这只会隐藏问题,并且在程序继续运行时,您可能找不到错误

3)在main()或init代码中,应尽快检查MCU状态寄存器,并将其设置为零。
在大多数重置情况下,该寄存器将保存重置原因

if(MCUCSR & (1<<PORF )) myprintf0P(PSTR("Power-on reset.\n"));
if(MCUCSR & (1<<EXTRF)) myprintf0P(PSTR("External reset!\n"));
if(MCUCSR & (1<<BORF )) myprintf0P(PSTR("Brownout reset!\n"));
if(MCUCSR & (1<<WDRF )) myprintf0P(PSTR("Watchdog reset!\n"));
if(MCUCSR & (1<<JTRF )) myprintf0P(PSTR("JTAG reset!\n"));
MCUCSR = 0;
6)这是我的特殊问题,它导致了上述所有问题和更多问题。 在我的例子中,整个问题都来自于我在3.3V和16MHZ下使用AVR的愚蠢。在该频率下,需要大约4.5V的电压才能稳定运行。
早些时候,我做了一些测试,MCU似乎运行得非常稳定,但随着代码大小的增加,稳定性降低。
这就好像我有一个非常严重的内存损坏,可能是由ISR触发的。
或者好像某些libc函数(与progmem相关的函数)出现故障。
将设备置于5V可解决此问题。这种智慧花费了我无数个小时的时间进行软件分析,我在软件方面深入搜索了每一个可能的原因。
教训:如果你给微控制器编程,千万不要把它当作纯粹的软件:)

7)对于高级内存损坏分析可以将堆栈设置为特定的预定义状态。这可以极大地帮助您进行调试,因为您可以观察数据中变量的增长情况。
此外,空终止的丢失会使指针运行到已知数据而不是未知数据中。
只需向项目中添加一个C文件,代码如下:

extern void *_end, *__stack;
#define __ALD(x) ((uintptr_t)(x) - ((uintptr_t)(x) & 0x03))
#define __ALU(x)   ((uintptr_t)(x) + ((uintptr_t)(x) & 0x03))
void _stackfill(void) __attribute__((naked)) __attribute__((optimize("O3"))) __attribute__((section (".init1")));
void _stackfill(void)
{
    uint32_t* start = (uint32_t*)__ALU(&_end);
    uint32_t* end   = (uint32_t*)__ALD(&__stack);

    for (uint32_t *pos = start; pos < end; pos++)
        *pos = 0x41424142; // ends up as endless ascii BABA
}
extern void*\u end,*\u堆栈;
#定义ALD(x)((uintpttr(t)(x)-(uintpttr(t)(x)和0x03))
#定义uu ALU(x)((uintpttr_ut)(x)+((uintpttr_ut)(x)和0x03))
void(void)stackfill(void)(裸)(裸))属性(优化(O3))(部分(init1));
空隙_堆垛填充(空隙)
{
uint32_t*开始=(uint32_t*)逻辑单元(&u结束);
uint32_t*端=(uint32_t*)ALD(&堆栈);
对于(uint32_t*pos=start;pos
此代码将自动挂接到代码的init部分,并在sram上编写模式babababababa。
这对您的程序没有不良影响,它只是用已知模式初始化sram。
如果您在调试期间查看它,您将看到在哪里分配变量,在哪里不分配变量。
它工作正常,也可以写入init3

现在就这样。 我希望这篇简短的综述能帮助一些程序员用AVR解决奇怪/令人沮丧的行为

代码部分是为ATMEGA 128编写的,但将在任何8位AVR上运行,只是一些寄存器名称可能需要稍作更改。

8)使用最新的gcc编译器 降低错误编译器优化的可能性(Arduino gcc 4.3.2问题)

9)使用JTAG调试器 为了提高随机错误的捕获概率

TLDR: 约翰当然给出了一个可能的原因清单。然而,另一个是缺少的,这是由断电引起的重置

长版本: 我遇到了一个类似的问题,我的Atmega328在进入设置、初始化MicroSD和打开wifi(esp8266)模块后一直在重置。每次wifi模块通电时,它都会重置。此外,只有当设备由电池供电而不是由FTDI232 USB电缆供电时,才会发生这种情况

我用的是3xAA电池,但当时电压降到了3.6v。因此,当MicroSD和wifi都打开时,我的DMM读数垂直于3.2v。我相信瞬时最小电压远低于这个值

我使用Arduino Pro Mini 8M 3.3v的默认引导加载程序,efuse设置为0x5。根据Atmega328表29-12,相应的BOD水平为2.7v。所以发生的情况是:当wifi和MicroSD打开时,电压下降到2.7v以下,棕色输出功能重置程序

那么解决方案呢?将BODLEVEL降低到1.8或像我一样禁用它。只需修改boards.txt文件并在Arduino Pro Mini下更改以下设置:

atmega328_384_8.bootloader.extended_fuses=0x05

然后重新启动Arduino IDE并重新刻录引导加载程序。然后这个问题就消失了

论坛上有一些关于禁用它或选择正确级别是否明智的讨论。但对于我的项目来说,让程序不断地自我重置并耗尽电池是没有意义的。但它可以做h
atmega328_384_8.bootloader.extended_fuses=0x05
atmega328_384_8.bootloader.extended_fuses=0x07