子機の実装 (MININODES)
子機の基本的な実装を見ます。
本ページでは LAYERTREE_MININODES モジュールによる、送信専用子機について紹介します。

モジュール定義, include

1
#define ToCoNet_USE_MOD_NWK_LAYERTREE_MININODES
2
3
// includes
4
#include "ToCoNet.h"
5
#include "ToCoNet_mod_prototype.h"
Copied!

cbAppColdStart()

アプリケーションIDやチャネルは、ここで決めておきます。また初期化処理等は vProcessEvCore() 関数に記述します。
1
void cbAppColdStart(bool_t bAfterAhiInit) {
2
if (!bAfterAhiInit) { // before AHI init, very first of code.
3
// Register modules
4
ToCoNet_REG_MOD_ALL();
5
} else {
6
// TWELITE NET configuration
7
/// Application ID
8
sToCoNet_AppContext.u32AppId = 0x12345678;
9
sToCoNet_AppContext.u8Channel = 18;
10
11
/// 受信回路は OFF
12
sToCoNet_AppContext.bRxOnIdle = FALSE;
13
14
/// CCA は最小限にする
15
sToCoNet_AppContext.u8CCA_Level = 1;
16
sToCoNet_AppContext.u8CCA_Retry = 0;
17
18
/// 起動時の MAC 初期化を後回しにする。
19
/// 送信直前で初期化し、不要な場合は初期化しない。
20
sToCoNet_AppContext.u8MacInitPending = TRUE;
21
22
// Register user PRSEV.
23
ToCoNet_Event_Register_State_Machine(vProcessEvCore);
24
}
25
}
Copied!

cbAppWarmStart()

単純ネットと同様にハードウェアの初期化等を実施するが、中継ネット特有の処理は vProcessEvCore() にて実施する。

cbToCoNet_vNwkEvent()

LayerTree MININODES は、上位ノードの決定といった手続きは省略されるため、 E_EVENT_TOCONET_NWK_START E_EVENT_TOCONET_NWK_DISCONNECT イベントについては処理する必要がありません。

cbToCoNet_vRxEvent()

受信方法は単純ネットと大きく変わりません。tsRxDataApp 構造体には違いがあります。
中継パケットは cbToCoNet_vRxEvent() コールバックでは処理されません。中継器に直接届いたパケット(送信専用の子機からパケットなど)を処理します。
1
void cbToCoNet_vRxEvent(tsRxDataApp *pRx) {
2
uint8 *p = pRx->auData;
3
4
// パケットの表示
5
if (pRx->u8Cmd == TOCONET_PACKET_CMD_APP_DATA) {
6
// 基本情報
7
uint8 u8lqi_1st = pRx->u8Lqi; // LQI
8
uint32 u32addr_1st = pRx->u32SrcAddr; // 送信元
9
10
// データの解釈
11
uint8 u8b = G_OCTET();
12
...
13
}
14
}
Copied!

vProcessEvCore()

システム始動時 E_EVENT_START_UP に、tsToCoNet_NwkLyTr_Config 構造体の設定、ToCoNet_NwkLyTr_psConfig_MiniNodes() 関数の実行、 ToCoNet_Nwk_bInit() 関数によるネットワークの初期化、ToCoNet_Nwk_bStart() 関数によるネットワークの開始を行います。
スリープ前にはToCoNet_Nwk_bPause()、スリープからの起床時には ToCoNet_Nwk_bResumte() を実行します。
1
static tsToCoNet_NwkLyTr_Config sNwkLayerTreeConfig;
2
static tsToCoNet_Nwk_Context* pContextNwk;
3
4
static void vProcessEvCore(tsEvent *pEv, teEvent eEvent, uint32 u32evarg) {
5
switch (pEv->eState) {
6
case E_STATE_IDLE:
7
if (eEvent == E_EVENT_START_UP) {
8
if (u32evarg & EVARG_START_UP_WAKEUP_RAMHOLD_MASK) {
9
// RESUME
10
ToCoNet_Nwk_bResume(pContextNwk);
11
} else {
12
// 始動時の処理
13
memset(&sNwkLayerTreeConfig, 0, sizeof(sNwkLayerTreeConfig));
14
sNwkLayerTreeConfig.u8Role =
15
TOCONET_NWK_ROLE_ENDDEVICE;
16
// ネットワークの初期化
17
pContextNwk =
18
ToCoNet_NwkLyTr_psConfig_MiniNodes(&sNwkLayerTreeConfig);
19
20
if (sAppData.pContextNwk) {
21
ToCoNet_Nwk_bInit(pContextNwk);
22
ToCoNet_Nwk_bStart(pContextNwk);
23
}
24
}
25
}
26
// RUNNING状態へ遷移
27
ToCoNet_Event_SetState(pEv, E_STATE_RUNNING);
28
break;
29
30
case E_STATE_RUNNING:
31
if (E_EVENT_NEW_STATE) {
32
// センサーデータの取得など
33
} else {
34
//
35
tsTxDataApp sTx;
36
memset(&sTx, 0, sizeof(sTx)); // 必ず0クリアしてから使う!
37
uint8 *q = sTx.auData;
38
39
sTx.u32SrcAddr = ToCoNet_u32GetSerial();
40
41
if (IS_APPCONF_OPT_TO_ROUTER()) {
42
// ルータがアプリ中で一度受信して、ルータから親機に再配送
43
sTx.u32DstAddr = TOCONET_NWK_ADDR_NEIGHBOUR_ABOVE;
44
} else {
45
// ルータがアプリ中では受信せず、単純に中継する
46
sTx.u32DstAddr = TOCONET_NWK_ADDR_PARENT;
47
}
48
49
// ペイロードの準備
50
S_OCTET('T');
51
S_OCTET(sAppData.sFlash.sData.u8id);
52
S_BE_WORD(sAppData.u16frame_count);
53
54
// センサ固有のデータ
55
memcpy(q,pu8Data,u8Len);
56
q += u8Len;
57
58
sTx.u8Cmd = 0; // 0..7 の値を取る。パケットの種別を分けたい時に使用する
59
sTx.u8Len = q - sTx.auData; // パケットのサイズ
60
sTx.u8CbId = sAppData.u16frame_count & 0xFF; // TxEvent で通知される番号、送信先には通知されない
61
sTx.u8Seq = sAppData.u16frame_count & 0xFF; // シーケンス番号(送信先に通知される)
62
sTx.u8Retry = sAppData.u8Retry;
63
64
if (ToCoNet_Nwk_bTx(pNwk, &sTx)) {
65
ToCoNet_Event_SetState(pEv, E_STATE_APP_WAIT_TX);
66
} else {
67
// ...失敗した(スリープ処理)
68
ToCoNet_Event_SetState(pEv, E_STATE_SLEEP);
69
}
70
}
71
break;
72
73
case E_STATE_APP_WAIT_TX:
74
if (...) { // Wait Tx Completion
75
ToCoNet_Event_SetState(pEv, E_STATE_SLEEP);
76
}
77
break;
78
79
case E_STATE_APP_SLEEP:
80
if (eEvent == E_EVENT_NEW_STATE) {
81
// 中継ネットのポーズ処理を行う
82
ToCoNet_Nwk_bPause(sAppData.pContextNwk);
83
84
// 周期スリープに入る
85
// - 初回は5秒あけて、次回以降はスリープ復帰を基点に5秒
86
vSleep(5000, TRUE, FALSE);
87
}
88
break;
89
90
default:
91
break;
92
}
93
}
94
Copied!