Я пытаюсь написать код для Arduino в Atmel Studio 7. Чтобы он был похож на Arduino IDE, я пытаюсь адаптировать его библиотеки.
Но я уже заблокирован delay()
, который использует yield()
, Урожай, похоже, нигде не реализован. Так мой компилятор говорит «неопределенная ссылка на доходность».
Я не понимаю, как Arduino IDE справляется с этим? Что я могу сделать, чтобы использовать yield()
в студии Atmel?
Вот моя попытка:
#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, начинают с мигающей светодиодной программы. Это «Hello World» из голого метала. Задержка хорошо для этого.
Если вы будете смотреть в себя util/delay.h
тем не менее, вы увидите функции, специально написанные для вашего чипа. Используйте их и не используйте ссылки в версиях Arduino. Вы найдете _delay_ms()
а также _delay_us()
функции, которые идеально подходят для этого типа программы первых шагов.
Вот как это реализовано в ядре плат Arduino AVR:
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")));
Как поясняют комментарии в этом файле:
Пустой крюк yield ().
Эта функция предназначена для использования авторами библиотек для создания библиотек или эскизов, поддерживающих совместные потоки. Он определен как слабый символ и может быть переопределен для реализации реального совместного планировщика.
Таким образом, вы можете определить yield()
в вашем собственном коде, если хотите. В противном случае пустое определение предотвратит ошибку неопределенной ссылки, с которой вы столкнулись.
Конечно, лучше писать правильный неблокирующий код, чем использовать это yield()
Обходной путь, но вы спросили, как Arduino IDE справляется с этим, и вот оно у вас есть.
Спасибо за помощь. Поэтому я создал решение со стилем класса:
#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