Короче, разобрался я, в чём причина. Всё дело в шаблонах

Базовый класс у меня объявлен как шаблон:
Код
template<uint16_t rx_buf_size, uint16_t tx_buf_size>
class TCustomUart
{
public:
TCustomUart() : RxChannel(), TxChannel(), tx_active(false) { }
void putchar(char ch);
void puts(char * ch);
char getchar(void);
...
protected:
OS::channel<char, rx_buf_size> RxChannel;
OS::channel<char, tx_buf_size> TxChannel;
virtual void disable_tx_interrupt(void) = 0;
virtual void enable_tx_interrupt(void) = 0;
virtual void write_tx_reg(char ch) = 0;
...
};
соответственно, класс uart1:
Код
template<uint16_t rx_buf_size, uint16_t tx_buf_size>
class TUart1 : public TCustomUart<rx_buf_size, tx_buf_size>
{
...
static OS_INTERRUPT void usart0_rx(void);
static OS_INTERRUPT void usart0_tx(void);
};
- тоже шаблон.
Убрав шаблоны, получил нормальную линковку обработчиков прерываний.
Видимо, это так работает механизм шаблонирования - всё, что не вызывается, то не инстанцируется?
Если бы я знал, что такое электричество...