Atmel Studio 中的 Arduino 产量
Arduino yield in Atmel Studio
我正在尝试在 Atmel Studio 7 中为 Arduino 编写代码。为了使其与 Arduino 相似 IDE,我正在尝试调整其库。
但是我已经被使用 yield()
的 delay()
屏蔽了。产量似乎没有在任何地方实施。所以我的编译器说 "undefined reference to yield".
我不明白 Arduino IDE 是如何处理的?如何在 Atmel Studio 中使用 yield()
?
这是我的尝试:
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <util/delay.h>
#include <avr/io.h>
#include <Arduino.h>
#include <wiring.c>
int main(void) {
DDRB = (1 << DDB5);
while(1) {
PORTB = (1 << DDB5);
delay(1000);
PORTB = (0 << DDB5);
delay(1000);
}
}
尽管正如评论者所建议的那样,延迟通常是可以避免的,但我们大多数编写裸机 Atmel 芯片的人都是从 blinking LED 程序开始的。这是裸机嵌入式编程的 "Hello World"。延迟是可以的。
不过,如果您仔细观察 util/delay.h
,您会看到专门为您的芯片编写的函数。在 Arduino 版本中使用它们而不是 link。您会发现 _delay_ms()
和 _delay_us()
函数非常适合这种第一步类型的程序。
感谢您的帮助。所以我创建了一个 class 风格的解决方案:
#include "Blink.h"
#include <util/delay.h>
#include "Arduino.h"
#define boardLedOn PORTB |= (1 << DDB5);
#define boardLedOff PORTB &= ~(1 << DDB5); // inverse bits
#define delay(ms) _delay_ms(ms);
Blink::Blink(){
};
void Blink::run(){
boardLedOn;
delay(1000);
boardLedOff;
delay(1000);
}
来电者:
#include <avr/io.h>
#include <Arduino.h>
#include <Blink.h>
int main(void)
{
Blink blink;
while(1)
{
blink.run();
}
}
头文件:
#ifndef BLINK_H
#define BLINK_H
class Blink{
public:
Blink();
void run();
};
#endif
以下是它在 Arduino AVR Boards 核心中的实现方式:
https://github.com/arduino/Arduino/blob/1.8.3/hardware/arduino/avr/cores/arduino/hooks.c#L19-L31
void yield(void) __attribute__ ((weak, alias("__empty")));
正如该文件中的注释所解释的那样:
Empty yield() hook.
This function is intended to be used by library writers to build libraries or sketches that supports cooperative threads. Its defined as a weak symbol and it can be redefined to implement a real cooperative scheduler.
因此您可以根据需要在自己的代码中定义yield()
。否则空定义会阻止你遇到的未定义引用错误。
当然,最好编写适当的非阻塞代码而不是使用此 yield()
解决方法,但您询问了 Arduino IDE 如何处理它,所以您知道了。
我正在尝试在 Atmel Studio 7 中为 Arduino 编写代码。为了使其与 Arduino 相似 IDE,我正在尝试调整其库。
但是我已经被使用 yield()
的 delay()
屏蔽了。产量似乎没有在任何地方实施。所以我的编译器说 "undefined reference to yield".
我不明白 Arduino IDE 是如何处理的?如何在 Atmel Studio 中使用 yield()
?
这是我的尝试:
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <util/delay.h>
#include <avr/io.h>
#include <Arduino.h>
#include <wiring.c>
int main(void) {
DDRB = (1 << DDB5);
while(1) {
PORTB = (1 << DDB5);
delay(1000);
PORTB = (0 << DDB5);
delay(1000);
}
}
尽管正如评论者所建议的那样,延迟通常是可以避免的,但我们大多数编写裸机 Atmel 芯片的人都是从 blinking LED 程序开始的。这是裸机嵌入式编程的 "Hello World"。延迟是可以的。
不过,如果您仔细观察 util/delay.h
,您会看到专门为您的芯片编写的函数。在 Arduino 版本中使用它们而不是 link。您会发现 _delay_ms()
和 _delay_us()
函数非常适合这种第一步类型的程序。
感谢您的帮助。所以我创建了一个 class 风格的解决方案:
#include "Blink.h"
#include <util/delay.h>
#include "Arduino.h"
#define boardLedOn PORTB |= (1 << DDB5);
#define boardLedOff PORTB &= ~(1 << DDB5); // inverse bits
#define delay(ms) _delay_ms(ms);
Blink::Blink(){
};
void Blink::run(){
boardLedOn;
delay(1000);
boardLedOff;
delay(1000);
}
来电者:
#include <avr/io.h>
#include <Arduino.h>
#include <Blink.h>
int main(void)
{
Blink blink;
while(1)
{
blink.run();
}
}
头文件:
#ifndef BLINK_H
#define BLINK_H
class Blink{
public:
Blink();
void run();
};
#endif
以下是它在 Arduino AVR Boards 核心中的实现方式: https://github.com/arduino/Arduino/blob/1.8.3/hardware/arduino/avr/cores/arduino/hooks.c#L19-L31
void yield(void) __attribute__ ((weak, alias("__empty")));
正如该文件中的注释所解释的那样:
Empty yield() hook. This function is intended to be used by library writers to build libraries or sketches that supports cooperative threads. Its defined as a weak symbol and it can be redefined to implement a real cooperative scheduler.
因此您可以根据需要在自己的代码中定义yield()
。否则空定义会阻止你遇到的未定义引用错误。
当然,最好编写适当的非阻塞代码而不是使用此 yield()
解决方法,但您询问了 Arduino IDE 如何处理它,所以您知道了。