В настоящее время я работаю с ATmega328p (находится в Arduino Uno) и абстрагируюсь от изменения таблицы векторов прерываний во время выполнения.
Моя проблема заключается в доступности и видимости глобальной переменной g_VectorTable
. Я хочу, чтобы он был доступен только из реализации, но не из чего-либо еще. Есть ли способ обойти это, определив переменную как stati c с некоторыми другими модификациями? (Реализация по специализации должна остаться, ее можно переместить в .tcc
файлы, реструктурировать и т.д. c.)
Я знаю, что глобальная переменная не является решением. Я ищу конструкцию, которая позволяет мне получить доступ к этому массиву из подпрограммы обработки прерываний, а также из специализации шаблона, ограничивая доступ ко всему остальному.
Текущее состояние моего проекта:
интерфейс <hal/InterruptVectorTable.hpp>
:
template <class Impl, class IRQType>
class InterruptVectorTable
{
private:
InterruptVectorTable();
public:
InterruptVectorTable(InterruptVectorTable const&) = delete;
void operator=(InterruptVectorTable const&) = delete;
static auto getInstance() -> InterruptVectorTable&;
auto setISR(IRQType InterruptIndex, void (*Callback)(void)) -> void;
};
Реализация по специализации InterruptVectorTable.hpp
:
extern void (*g_VectorTable[26])(void);
template <>
class InterruptVectorTable<DeviceAtMega328p, IRQType> // IRQType is an enum class
{
private:
InterruptVectorTable()
{
auto DefaultHandler = []() -> void {};
g_VectorTable[0] = 0x0;
for (uint8_t i = 1; i < 26; i++)
{
g_VectorTable[i] = DefaultHandler;
}
m_VectorTable = reinterpret_cast<uint8_t*>(g_VectorTable);
}
uint8_t* m_VectorTable;
public:
static auto getInstance() -> InterruptVectorTable&
{
static InterruptVectorTable instance;
return instance;
}
auto setISR(IRQType InterruptIndex, void (*Callback)(void)) -> void
{
g_VectorTable[static_cast<uint8_t>(InterruptIndex)] = Callback;
}
// ...
};
Реализация InterruptVectorTable.cpp
:
#include <avr/interrupt.h>
void (*g_VectorTable[26])(void) = {0x0, };
ISR(INT0_vect)
{
g_VectorTable[1]();
}
ISR(INT1_vect)
{
g_VectorTable[2]();
}
ISR(PCINT0_vect)
{
g_VectorTable[3]();
}
ISR(PCINT1_vect)
{
g_VectorTable[4]();
}
// ...