割込みの禁止区間の作り方について質問させてください。
現在の環境は、RX64MマイコンCC-RX V3.000 コンパイラe2studioスマートコンフィグレータを使用しています。
外部とスマートコンフィグレータで生成したコンポーネント(Config_SCIFx)を使用して通信のやり取りをしています。生成した「R_Config_SCIF9_Serial_Receive」関数を無限ループ内で利用してデータの受信を行っているのですが、割込みタイミングによっては、データ受信直後に「R_Config_SCIF9_Serial_Receive」が再び呼び出されることで、取得したデータが損失する危険性があるかなと思っています。下記のコード内で示した位置で割込み禁止にするには具体的にどうすれば良いのでしょうか。
while(1) {
uint8_t array[DATA];
//この位置から
if(0 == Flag) //割込みのコールバック関数にて立てているフラグが立っていないときに実行 { R_Config_SCIFx_Serial_Receive(array, DATA);
//この位置まで割込み禁止
} else { Flag = 0; //受信が完了し割込みがかかるとフラグが立つので、次のデータ受信をするためにフラグをもどす }
//後続の受信データ処理
}
わわいです
うちのGCC-RXのRX630のプロジェクトでは、
#define _DISABLE() R_BSP_InterruptsDisable()
わわい様自作できるんですね。コンポーネントの「r_bsp」の中身を見ていたら、「mcu_interrupts.c」の中に、「bsp_int_err_t bsp_interrupt_enable_disable (bsp_int_src_t vector, bool enable)」という関数がありました。中身で何しているかは今の自分のレベルではさっぱりですが、もしかしてこの関数を自作されたいう事でしょうか。割込み禁止の方法は一つではないのですね.....。
いや、関数を自作したってことではなく、プロジェクトの新規作成時に自動生成されてるソースの中に、
```
cpu.c
/************************************************************************************************************************ Function Name: R_BSP_InterruptsDisable* Description : Globally disable interrupts.* Arguments : none* Return Value : none***********************************************************************************************************************/int R_BSP_InterruptsDisable (void){ if(getpsw_i()){ clrpsw_i(); return 1; } return 0;} /************************************************************************************************************************ Function Name: R_BSP_InterruptsEnable* Description : Globally enable interrupts.* Arguments : none* Return Value : none***********************************************************************************************************************/void R_BSP_InterruptsEnable (void){ setpsw_i();}
と、割り込み禁止/許可の関数が定義されています。
それをマクロにして使ってるってことです
# 結局やってることは同じ、ですねー
`
わわい様
ありました。
void R_BSP_InterruptsDisable (void){ uint32_t pmode;
/* Read current processor mode. */ pmode = (R_BSP_GET_PSW() & 0x00100000);
/* Check current processor mode. */ if (0 == pmode) { /* Use the compiler intrinsic function to clear the I flag. */ R_BSP_CLRPSW_I(); }
} /* End of function R_BSP_InterruptsDisable() */
void R_BSP_InterruptsEnable (void)
{
uint32_t pmode;
/* Read current processor mode. */
pmode = (R_BSP_GET_PSW() & 0x00100000);
/* Check current processor mode. */
if (0 == pmode)
/* Use the compiler intrinsic function to set the I flag. */
R_BSP_SETPSW_I();
} /* End of function R_BSP_InterruptsEnable() */
やっていることとしては結局PSWのIを操作するという事ですね。意味が分かりました。それを関数マクロ化することで便利に使えるようにすると良いという事ですね。ありがとうございます。
ついでに説明しときます
なんでマクロにしてるか、というと、シゴトでいろーんなCPUを相手にする関係上、同じ操作の関数は同じ名前で操作できるようにするため、です。
あらかじめこれを徹底しておくと、違うCPUに移行/移植する場合に、コードを共通化でき、最小限の修正で済むようになります
なんとなくマクロは定数定義としてほぼ使用していましたが、そういった利点もあるのですね。まねさせていただきます。ありがとうございます。