先日、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」で定義されたシンボル名が優先されるので、割り込みエントリーが
空のままとなる、そして、コンパイル、リンクはエラー無く終了するので、こ
の手のミスが明るみになる可能性はかなり低い・・・
これは、課題とする。