あなたの天然記念物
ホーム更新雑談Perl鉄ゲタランドナーコースガイド自転車Linuxリンク経歴連絡先

タスク&割り込み処理兼用API (2013.03.24)

FreeRTOSのAPI呼び出し条件

割り込み処理から呼び出しできるAPIは例えば「xQueueSendToBackFromISR」といった「~FromISR」形式のものだけです。 汎用関数からAPIを呼ぶ際、呼出元が割り込み処理の場合と、タスクの場合で2種類作るのは面倒、というかちっともスマートじゃない。 どちらから呼び出しても良い汎用関数を作りました。

割り込み処理中か判定してAPIを切替

ユーザマニュアルのページ731に「Interrupt Program Status Register」が記載されています。ISRフィールドが0でスレッドモード中(タスク=割り込み処理でない)、1~255が割り込み処理中なので判別できるという訳です。これを使ってAPIを切り替えたコードはこんな感じ。
void ksrk_trigger(uint32_t uSignals)
{
	// 割り込み番号を取得(0=スレッドモード=割り込みなし)
	uint32_t psr = 0;
	__asm volatile ("mrs %0, psr" : "=r" (psr));
	uint32_t isr_number = psr & 0xFF;

	SIGNAL_TYPE st = {
		NULL,
		uSignals,
		~0,
		NULL
	};
	if (0 == isr_number)
	{
		portBASE_TYPE rc = xQueueSendToBack(hSignalQue, &st, portMAX_DELAY);
		KSRK_ASSERT(pdTRUE == rc);
	}
	else
	{
		portBASE_TYPE HigherPriorityTaskWoken = pdFALSE;
		portBASE_TYPE rc = xQueueSendToBackFromISR(hSignalQue, &st, &HigherPriorityTaskWoken);
		KSRK_ASSERT(pdPASS == rc);

		if (HigherPriorityTaskWoken)
		{
			//中身はvPortYieldFromISR
			taskYIELD();
		}
	}
}

今回の鉄ゲタは…

ありません、ほっ。