include/jsp_stddef.h中の, inline関数などのマクロ定義に関して,次の定義を追加します.
ここではNC30というコンパイラ側であらかじめ用意されているマクロを使用しています.
#elif defined(NC30) #define inline #define Inline _inline #define asm _asm #define Asm _asm
VP_INT型はfar領域を格納するポインタとして使用するため,include/itron.hでVP_INT定義を次のように定義します.
#ifdef NC30 typedef void _far *VP_INT; /* VP または INT */ #else typedef VP VP_INT; /* VP または INT */ #endif
コンパイラのマニュアルより, M16C用のCコンパイラは,プロトタイプ宣言された関数については第1引数がUINT型の時にレジスタ(第1引数の場合はR1)経由で引数を渡します.しかし,関数をプロトタイプ宣言なしで使用するとスタック渡しになります.
プロトタイプ宣言しない関数を呼び出した場合,呼び出される側の関数はレジスタ渡しを前提としたコードをコンパイラが出力し,呼び出し側はスタック渡しのコードをコンパイラが出力するため,問題が発生する可能性があります.コールバック関数の呼び出しなど,プロトタイプ宣言することができない場合は,呼出時に関数ポインタをキャストしないと,同様の問題が発生する可能性があります.
以上の理由により,カーネルソースの一部に変更を加えます.
kernel/task.c , 341行目
変更前
(*runtsk->tinib->texrtn)(texptn, runtsk->tinib->exinf);
変更後
(*(void (*)(TEXPTN,VP_INT))runtsk->tinib->texrtn)(texptn, runtsk->ti
nib->exinf);
次は, M16C依存部ではVP_INTをfarポインタとして使用する前提のため, VP_INT型の引数はスタック渡しになり問題は生じないのですが,コンパイル時にワーニングが発生するための対策としてキャストを行います.
kernel/cyclic.c , 168行目
変更前
(*cyccb->cycinib->cychdr)(cyccb->cycinib->exinf);
変更後
(*(void (*)(VP_INT))cyccb->cycinib->cychdr)(cyccb->cycinib->exinf);
シリアルドライバを使用する場合,以下の変更を加える必要があります.
シリアルドライバ関連は次期バージョンでは変更される予定となっているため,将来のカーネルバージョンではこの変更は必要がなくなるでしょう.
175行目
#define MAX_FLUSH_LOOP 1000000L
181行目
UW i;
カーネルに標準で用意されているログ出力機能を利用する場合は,以下のように,ポインタ変数の宣言時やキャスト時にfar領域のアドレスを格納するポインタとしてkernel/syslog.cの以下の部分を変更する必要があります(理由).
syslogt_terminate関数
189行目
const char *bufmsg = "-- buffered messages --";
190行目
const char *lostmsg = "%d messages are lost.";
syslog_printf関数
250行目
char far *format;
256行目
char far *str;
258行目
format = (char far*)(p_syslog->loginfo[0]);
304行目
str = (char far*)(p_syslog->loginfo[argno++]);
さらに,可変数引数のシステムログライブラリであるsyslog関数を使用する場合は, libjsp/vasyslog.cの次の個所も変更してください.
83行目
syslog.loginfo[i++] = (VP_INT) va_arg(ap, char far *);
カーネル標準で用意されているログタスクを利用する場合は,systask/logtask.cに以下の変更を加える必要があります(理由).
66行目 ( logtask 関数内 )
const char *lostmsg = "%d messages are lost.";
(ここは変更箇所ではありません)
マニュアルより,インライン関数はプロトタイプ宣言して使用しないとインライン展開されないことになっています.また,使用する関数はすべてプロトタイプ宣言しないとコンパイル時にワーニングが発生します(場合によっては引数が正しく渡されないこともあります).そのため,カーネルコードの中の,プロトタイプ宣言されていない関数のプロトタイプ宣言をヘッダファイルに記述するようにしました.そのような理由から,プロセッサ依存部のヘッダファイル内には次のプロトタイプ宣言を含んでいます.
(cpu_config.h) extern void kernel_start(void); Inline void tmevtb_delete_top(void);
(cpu_context.h) static TCB *search_schedtsk(void);
(cpu_defs.h) extern ER vxget_tim(SYSUTIM *);