gpt4 book ai didi

c++ - Arduino 锁定

转载 作者:太空狗 更新时间:2023-10-29 19:44:18 25 4
gpt4 key购买 nike

下面程序的目的是定期输出串行数据帧。该周期由定时中断定义,每秒。

代码在 Arduino IDE 版本 0022 上运行,但在 1.0 上我无法运行。当使用计时器例程并且 maxFrameLength 设置为 0x40 或更高时, Controller 会锁定。当使用 0x39 或更低时,程序保持运行(由闪烁的 LED 指示)。

这里出了什么问题,为什么?这是一个错误吗?我做错了什么吗?

我正在使用 http://code.google.com/p/arduino-timerone/downloads/detail?name=TimerOne-v9.zip用于 Mega1280 上的定时器例程。

#include "TimerOne.h"

#define LED 13
#define maxFrameLength 0x40

boolean stateLED = true;
byte frame[ maxFrameLength ];

void sendFrame() {
digitalWrite( LED , stateLED );
stateLED = !stateLED;
Serial.write( frame, maxFrameLength ); // ptr + bytes to send
}

void setup() {
pinMode( LED , OUTPUT );
Timer1.initialize( 1000000 ); // initialize timer1 with 1 second period
Timer1.attachInterrupt( sendFrame );
Serial.begin( 9600 );
};

void loop() {
};

最佳答案

有许多问题可能会或可能不会导致问题,但无论如何都应该解决。这些意见是一般性的;我不熟悉 Arduino 或其库。

在中断处理程序 (ISR) 中发出 Serial.write() 调用几乎肯定是不合适的。如果 Serial 对象是中断驱动的,它将有一个关联的缓冲区。如果该缓冲区不够大,无法获取所有数据,该函数可能会阻塞,这在中断处理程序中是一个不行不行。此外,如果定时器中断的优先级高于串行中断,则当 Serial.write() 阻塞时将导致死锁。 0x40(64 字节)似乎是串行输出的可能缓冲区大小,因此这可能是主要原因。如果您可以增加可能使其工作的缓冲区大小,但在 ISR 中执行可能阻塞的操作仍然是一个坏主意。

即使串行输出是轮询而不是中断驱动,你的中断处理程序也会花费相当长的时间,这也是一个坏主意,但在这种情况下可能不是问题,但在 9600,n,8,1 ,64个字符需要67毫秒来清除发送寄存器。

stateLEDframe 是共享变量(在中断和主上下文之间),因此应声明为 volatile .

您的片段中没有显示 frame 更新的方式和位置,但由于中断将异步发生,因此对 frame 的任何更新都应该在 critical section - 至少禁用 timer1 中断。


更新

鉴于A.H.的回复,我下载了源码看了一下。 Serial 是\arduino-1.0\hardware\arduino\cores\arduino\hardwareSerial.cpp/.h 中定义的类 HardwareSerial 的静态对象。传输缓冲区长度确实是 64 字节,如果缓冲区已满,HardwareSerial::write() 函数会执行“忙等待”。您将需要修改并重新构建源代码以扩展缓冲区或添加 write() 的非阻塞版本。

然而,这肯定是锁定的原因 - 缓冲区永远不会为空,因为在 timer1 中断运行时无法处理传输中断。

关于c++ - Arduino 锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10565305/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com