Зачем нужны функции begin() для инициализации оборудования (если они есть)?

Я пишу программу для микроконтроллера ATmega, используя платформу Arduino. При реализации класса, связанного с оборудованием (один для управления светодиодами), я поместил в конструктор класса некоторый код инициализации оборудования, такой как pinMode(OUTPUT). Затем я понял, что во всех известных мне библиотеках Arduino аппаратная инициализация выполняется в begin() или init(), поэтому я также создал один для своего класса Led и переместил туда pinMode().

Теперь мне интересно, действительно ли я должен определять такие функции инициализации, т.е. зачем они нужны, а если нет, то почему они есть во многих библиотеках. Я немного поигрался и обнаружил, что, например, этот код работает на ATmega1284 (загорается светодиод на контакте 28).

struct Test {
  Test() {
    pinMode(28, OUTPUT);
    digitalWrite(28, HIGH);
    // другие вещи
  }
  // ...
};

Test test;

void setup() {
}

void loop() {
}

Я предполагаю, что этот код какой-то непродуманный, не говоря уже о том, что он зажигает светодиод без какого-либо кода в основной функции (или, может быть, именно в этом проблема?), но если это так, я не понимаю, почему . Что я не учел? Должен ли приведенный выше код быть написанным, как в следующем фрагменте, как мне кажется существование всех этих функций begin()?

struct Test {
  Test() {
    // другие вещи
  }
  void begin() {
    pinMode(28, OUTPUT);
    digitalWrite(28, HIGH);
  }
  // ...
};

Test test;

void setup() {
  test.begin();
}

void loop() {
}

, 👍0

Обсуждение

Хотя Arduino [Руководство по стилю API](https://www.arduino.cc/en/Reference/APIStyleGuide) рекомендует использовать begin() для настройки. Для меня и то, и другое является работой и является соображением дизайна, при условии, что вы знаете, что было настроено и инициализировано с помощью Arduino.h и [варианты](https://github.com/arduino/ArduinoCore-avr/tree/master /variants) для конкретной платы, и то, что вы пытаетесь сделать в конструкции, не будет переопределено init() внутри Arduino Core main(). Например, вы видите, что многие библиотеки используют конструкцию для настройки, например, «LCD lcd (SDL, SDA);»., @hcheung

На ваш вопрос о setup() и loop() см. исходный код Arduino Core [main.cpp](https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp ) для лучшего понимания., @hcheung


1 ответ


Лучший ответ:

1

Все дело в порядке выполнения.

Конструкторы выполняются перед обычными функциями. Это включает в себя функцию main(), которая в конечном итоге вызывает setup() и (неоднократно) loop(). Еще одна вещь, которую делает main(), — это вызов init() (или его вариант), который настраивает аппаратное обеспечение.

Поскольку это происходит после запуска любых глобальных конструкторов, все, что конструктор сделал с оборудованием, потенциально может быть отменено.

Таким образом, нормально откладывать любую настройку оборудования до тех пор, пока после main() не выполнит настройку, и по соглашению используется begin() для этого.

,

Спасибо за ответ! И что на самом деле представляет собой эта функция init()? Где это определено? И, кстати, где функция main() в проекте Arduino?, @noearchimede

Это все в ядре. Прочтите исходный код ядра., @Majenko