平成27年 4月 3日
XC32の割り込み処理の記述(その2)
昨日は、割り込み処理関数内からCP0のSTATUSレジスタ内にあるIPLを書き換えるアイデアだけを説明しました。
実際に書き換えを行う関数の記述は少し面倒です。下記に一例を示します。
#include <xc.h>
#include "pic32def.h"
/* 割り込み処理関数のIPL設定値をIPCレジスタの設定値に更新する
*/
void setInterruptIPL(uint8_t vec_no)
{
register uint32_t status = _CP0_GET_STATUS() & ~_CP0_STATUS_IPL_MASK;
//IPCnには1ワードあたり4個のIPCnが定義されている。
uint16_t add = vec_no /4*(&IPC1-&IPC0); //アドレスオフセット
uint16_t shift = vec_no %4; //ビットシフト量
uint32_t ipl = (*(&IPC0 + add) >>(8*shift+2)) & 0x07;
status |= (ipl << _CP0_STATUS_IPL_POSITION);
asm("mtc0 %0,$12,0" :: "r" (status));
}
関数に渡す引数は割り込み処理関数の__ISR()に渡すベクタ番号です。
割り込み処理関数に使用する実例は下記のようになります。
void __ISR(_TIMER_4_VECTOR, IPL7SOFT) TMR4ISR(void)
{
setInterruptIPL(_TIMER_4_VECTOR); //この関数実行中のIPLをIPC設定値にする。
IFS0bits.T4IF = 0;
//ユーザー処理
}
これで割り込み処理関数をライブラリとしてコンパイル済みの状態で使用できます。