R8C の割り込みベクターを共有する

先日、R8C関係のブログにコメントが入り、「誰かの役に立ってるんだなぁ」
と実感、RXで得た知見を元に、R8Cにも少しばかり反映を行った。

AVRの「ATTINY2313-20PU」は、以前は、ちょっとした物を創
る場合の救世主だったが、最近は、単価が上がり、気軽に使えなくなった。
※それでも、USBの直接接続など、需要は少なく無い。
それに代わって、現れた救世主が、「ルネサスのR8C/M120AN」で、値
段も100円で、隠し機能のおかげで重宝している。

R8C関係のC++テンプレートも、それなりに充実してきて、何か実験やテス
トを行うのに困らなくなってきている。

-----
RXのテンプレートクラスライブラリーを実装する課程で、gcc 独自の「拡張」
機能を学んだ。

__attribute__((weak));

これは、シンボル名に対する拡張で、二重定義の場合に「後から宣言されたシン
ボル」を有効にするもので、割り込みベクターの定義に有用だと判った。

つまり、

void UART0_TX_intr(void) __attribute__((weak));
void UART0_TX_intr(void) { }

上記のように「仮」の関数を定義しておき、割り込みベクターを宣言しておく事
ができる。

const void* variable_vectors_[] __attribute__ ((section (".vvec"))) = {
...
    UART0_TX_intr,   NULL,    // (17) UART0 送信
...

アプリケーション側で、割り込みが必要なクラスを使いたい場合、同じ名前で、
再定義すると、そちらが優先される。


#include "common/uart_io.hpp"
#include "common/fifo.hpp"

namespace {
    typedef utils::fifo<uint8_t, 16> buffer;
    typedef device::uart_io<device::UART0, buffer, buffer> uart;
    uart uart_;
}

extern "C" {

    void UART0_TX_intr(void) {
        uart_.isend();
    }

...

};

この改修で、今まで、アプリケーション側に定義していた、割り込みベクター
テーブルを追い出す事ができ、冗長なコードが改善できる。

追記:
しかし・・・、問題が全く無い訳では無い。
アプリ側のコードで、割り込みエントリーのシンボル名を「タイポ」した場合、
「vect.c」で定義されたシンボル名が優先されるので、割り込みエントリーが
空のままとなる、そして、コンパイル、リンクはエラー無く終了するので、こ
の手のミスが明るみになる可能性はかなり低い・・・
これは、課題とする。