C ++ Проверка времени компиляции, если вывод микроконтроллера уже инициализирован из другого исходного файла - PullRequest
0 голосов
/ 28 июня 2019

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

Я хочу реализовать список времени компиляции, который изначально пуст и каждый разPIN-код инициализируется, он проверит, присутствует ли контакт в этом списке, если он присутствует, он даст статическое подтверждение, в противном случае он вставит информацию о контакте в список.Список не требуется во время выполнения.

У меня недостаточно знаний о метапрограммировании, было бы замечательно, если бы кто-то мог дать мне руководство по его реализации. Если уже есть какая-то библиотека для такого рода целейПожалуйста, предоставьте ссылки

Ответы [ 2 ]

3 голосов
/ 28 июня 2019

То, что вы хотите, не возможно. Метапрограммирование C ++ не имеет состояния , оно больше похоже на функциональный язык, чем на декларативный. Таким образом, вы не можете иметь изменяемый список. Единственное состояние может быть введено путем создания новых типов, но нет доступного синтаксиса, чтобы проверить, объявлено или определено конкретное не вложенное имя.

Несколько исходных файлов (модулей компиляции) компилируются независимо, поэтому, безусловно, нет «глобального состояния», и это делает его более невозможным.

Кроме того, обратите внимание, что то, что вы делаете, является неотъемлемой частью времени выполнения. У компилятора нет инструментов, позволяющих проверить, вызываете ли вы функцию инициализации дважды. Эти вызовы могут быть скрыты за некоторыми решениями if-else времени выполнения. И просто написать HAL_GPIO_Init(); независимо от того, сколько раз во всей программе не ошибка.

Самая простая вещь, о которой я могу подумать, - это создание одноэлементного класса C ++, который отвечает за связь с выводами. Вы можете использовать выделенный метод int init_GPIO, используя коды ошибок или исключения, если они включены. Вместо static_assert вам придется полагаться на тесты - этот синглтон работает правильно, и возвращаемое значение init_GPIO не игнорируется.

Если вы действительно не хотите беспокоиться о синглтоне, этот шаблон функции также работает:

template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
    static bool initialized=false;
    if(initialized) return <already_called>;
    initialized=true;
    //Assuming that you want to propagate the return value.
    return HAL_GPIO_Init(GPIO, port, s);// Replace with the correct call.
}

Если вам требуется поточно-ориентированная инициализация, используйте:

template<std::size_t GPIO, std::size_t port> int GPIO_init(GPIO_InitStruct& s){
    static std::once_flag initialized;
    int ret_val = <already_called>;
    auto call = [&](){ret_val = HAL_GPIO_Init(GPIO, port, s)};
    std::call_once(initialized, call);
    return ret_val;
}
0 голосов
/ 03 июля 2019

Предполагая, что у каждого драйвера или HAL есть заголовочный файл, и есть main.cpp, который включает все эти заголовки, тогда вы можете сделать это с помощью препроцессора.

При необходимости создайте заголовок для всего проекта "pintype.h" с таким перечислением:

// pintype.h

typedef enum
{
  PIN_GPIO,
  PIN_PWM,
  PIN_ADC,
  PIN_UART,
  ...
} pin_t;

Затем для каждого заголовочного файла напишите проверку препроцессора, например:

// pwm.h, header of the pwm driver or HAL
#include "pintype.h"

#ifdef PIN9
  #error Pin 9 already taken
#else
  #define PIN9 PIN_PWM
#endif

Строго говоря, #error не требуется, потому что в случае конфликтов компилятор будет жаловаться на несколько определений в одной и той же единице перевода (что в main.cpp).

Когда разработчик, пишущий драйвер, получает сообщение об ошибке, он может перейти к определению вывода предварительного процессора и выяснить, какой другой модуль в проекте уже заявил о нем, не копаясь во внутренней реализации этого драйвера. .

...