PRSEV ライブラリ
複数の違った振る舞いをするアプリケーションをひとつのバイナリに格納する方法と、イベント状態ごとに関数定義する方法を提供します。
App_Tag のエンドデバイスでは、複数のセンサーの取り扱いについて一つのアプリケーションにまとめて、設定により動作を切り替えています。
各 vProcessEv_???.c ファイルには、個別の振る舞いをするアプリケーションの定義や手続きが含まれます。

コールバック関数の定義

コールバック関数は静的に定義するので、複数のアプリケーション動作をひとつにまとめるには都合が良くありません。ここでは、ソースファイル中に static 定義します。
1
/**
2
* ハードウェア割り込み
3
* @param u32DeviceId
4
* @param u32ItemBitmap
5
* @return
6
*/
7
static uint8 cbAppToCoNet_u8HwInt(uint32 u32DeviceId, uint32 u32ItemBitmap) {
8
uint8 u8handled = FALSE;
9
switch (u32DeviceId) {
10
default:
11
break;
12
}
13
return u8handled;
14
}
15
16
/**
17
* ハードウェアイベント(遅延実行)
18
* @param u32DeviceId
19
* @param u32ItemBitmap
20
*/
21
static void cbAppToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) {
22
}
23
24
/**
25
* メイン処理
26
*/
27
static void cbAppToCoNet_vMain() {
28
/* handle serial input */
29
vHandleSerialInput();
30
}
31
32
/**
33
* ネットワークイベント
34
* @param eEvent
35
* @param u32arg
36
*/
37
static void cbAppToCoNet_vNwkEvent(teEvent eEvent, uint32 u32arg) {
38
}
39
40
/**
41
* RXイベント
42
* @param pRx
43
*/
44
static void cbAppToCoNet_vRxEvent(tsRxDataApp *pRx) {
45
}
46
47
/**
48
* TXイベント
49
* @param u8CbId
50
* @param bStatus
51
*/
52
static void cbAppToCoNet_vTxEvent(uint8 u8CbId, uint8 bStatus) {
53
// 送信完了
54
ToCoNet_Event_Process(E_ORDER_KICK, 0, vProcessEvCore);
55
}
56
Copied!
最後に一覧のtsCbHandler構造体を用意します。
1
/**
2
* アプリケーションハンドラー定義
3
* 使わないものは NULL にする。
4
*/
5
static tsCbHandler sCbHandler = {
6
NULL, // cbAppToCoNet_u8HwInt,
7
cbAppToCoNet_vHwEvent,
8
NULL, // cbAppToCoNet_vMain,
9
NULL, // cbAppToCoNet_vNwkEvent,
10
NULL, // cbAppToCoNet_vRxEvent,
11
cbAppToCoNet_vTxEvent
12
};
13
Copied!

状態の定義

利用するイベントの数だけ定義を行います。
1
/**
2
* イベント処理関数リスト
3
*/
4
static const tsToCoNet_Event_StateHandler asStateFuncTbl[] = {
5
PRSEV_HANDLER_TBL_DEF(E_STATE_IDLE),
6
PRSEV_HANDLER_TBL_DEF(E_STATE_RUNNING),
7
PRSEV_HANDLER_TBL_DEF(E_STATE_APP_WAIT_TX),
8
PRSEV_HANDLER_TBL_DEF(E_STATE_APP_SLEEP),
9
PRSEV_HANDLER_TBL_TRM
10
};
11
Copied!
実体は以下のように定義します。
1
PRSEV_HANDLER_TBL_DEF(E_STATE_IDLE, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
2
// 開始時の状態
3
if (eEvent == E_EVENT_START_UP) {
4
// 電源投入またはスリープ復帰時のイベント処理
5
...
6
ToCoNet_Event_SetState(pEv, E_STATE_RUNNING);
7
}
8
}
9
10
PRSEV_HANDLER_TBL_DEF(E_STATE_RUNNING, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
11
// 実行中(センサーの取得、送信要求など)
12
bOk = bTransmitToParent( ... ); // 送信処理を行う if ( bOk ) {
13
ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_TX);
14
} else {
15
ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP);
16
}
17
}
18
19
PRSEV_HANDLER_TBL_DEF(E_STATE_APP_WAIT_TX, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
20
// 送信完了待ち
21
if (..) {
22
ToCoNet_Event_SetState(pEv, E_STATE_APP_SLEEP); // スリープ状態へ遷移
23
}
24
}
25
26
PRSEV_HANDLER_DEF(E_STATE_APP_SLEEP, tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
27
// スリープ手続き(以下にコード例)
28
if (eEvent == E_EVENT_NEW_STATE) {
29
// Sleep は必ず E_EVENT_NEW_STATE 内など1回のみ呼び出される場所で呼び出す。
30
V_PRINTF(LB"Sleeping...");
31
V_FLUSH();
32
33
// Mininode の場合、特別な処理は無いのだが、ポーズ処理を行う
34
ToCoNet_Nwk_bPause(sAppData.pContextNwk);
35
36
// 周期スリープに入る
37
// - 初回は5秒あけて、次回以降はスリープ復帰を基点に5秒
38
vSleep(sAppData.sFlash.sData.u32Slp, sAppData.u16frame_count == 1 ? FALSE : TRUE, FALSE);
39
}
40
}
Copied!

イベント処理関数

イベント処理関数を以下のように定義しておきます。先程の状態の定義で用意した asStateFuncTbl に従って、イベント処理が行われます。
1
/**
2
* イベント処理関数
3
* @param pEv
4
* @param eEvent
5
* @param u32evarg
6
*/
7
static void vProcessEvCore(tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
8
ToCoNet_Event_StateExec(asStateFuncTbl, pEv, eEvent, u32evarg);
9
}
10
Copied!

初期化処理

以下のようにグローバル変数として用意した psCbHandler, pvProcessEv1 に値を格納する初期化関数を用意しておきます。
1
/**
2
* アプリケーション初期化
3
*/
4
void vInitAppStandard() {
5
psCbHandler = &sCbHandler;
6
pvProcessEv1 = vProcessEvCore;
7
}
Copied!

アプリケーションの実行

コールバック関数を格納するメインファイルについて説明します。メインファイルでは、上記で定義した個々の処理用の関数を呼び出す処理を行います。
ユーザ定義イベント処理関数とTWELITE NET のコールバック関数は以下のように定義しておきます。関数ポインタで指定されるアプリケーション独自のコールバック関数を呼び出し、アプリケーション独自のユーザ定義イベント処理を実行します。
1
void cbAppColdStart(bool_t bInit) {
2
if (bInit == FALSE) {
3
...
4
} else {
5
switch(u8AppType) {
6
case 0x00: vInitAppStandard(); break;// AppStandard で起動
7
...
8
}
9
...
10
ToCoNet_Event_Register_State_Machine(pvProcessEv1);
11
}
12
}
13
14
/**
15
* メイン処理
16
*/
17
void cbToCoNet_vMain(void) {
18
if (psCbHandler && psCbHandler->pf_cbToCoNet_vMain) {
19
(*psCbHandler->pf_cbToCoNet_vMain)();
20
}
21
}
22
23
/**
24
* 受信処理
25
*/
26
void cbToCoNet_vRxEvent(tsRxDataApp *pRx) {
27
if (psCbHandler && psCbHandler->pf_cbToCoNet_vRxEvent) {
28
(*psCbHandler->pf_cbToCoNet_vRxEvent)(pRx);
29
}
30
}
31
32
/**
33
* 送信完了イベント
34
*/
35
void cbToCoNet_vTxEvent(uint8 u8CbId, uint8 bStatus) {
36
if (psCbHandler && psCbHandler->pf_cbToCoNet_vTxEvent) {
37
(*psCbHandler->pf_cbToCoNet_vTxEvent)(u8CbId, bStatus);
38
}
39
}
40
41
/**
42
* ネットワークイベント
43
* @param eEvent
44
* @param u32arg
45
*/
46
void cbToCoNet_vNwkEvent(teEvent eEvent, uint32 u32arg) {
47
if (psCbHandler && psCbHandler->pf_cbToCoNet_vNwkEvent) {
48
(*psCbHandler->pf_cbToCoNet_vNwkEvent)(eEvent, u32arg);
49
}
50
}
51
52
/**
53
* ハードウェアイベント処理(割り込み遅延実行)
54
*/
55
void cbToCoNet_vHwEvent(uint32 u32DeviceId, uint32 u32ItemBitmap) {
56
if (psCbHandler && psCbHandler->pf_cbToCoNet_vHwEvent) {
57
(*psCbHandler->pf_cbToCoNet_vHwEvent)(u32DeviceId, u32ItemBitmap);
58
}
59
}
60
61
/**
62
* ハードウェア割り込みハンドラ
63
*/
64
uint8 cbToCoNet_u8HwInt(uint32 u32DeviceId, uint32 u32ItemBitmap) {
65
bool_t bRet = FALSE;
66
if (psCbHandler && psCbHandler->pf_cbToCoNet_u8HwInt) {
67
bRet = (*psCbHandler->pf_cbToCoNet_u8HwInt)(u32DeviceId, u32ItemBitmap);
68
}
69
return bRet;
70
}
Copied!
最終更新 3mo ago