/* * 7-3 UDP サーバによるスイッチの状態取得と LED の制御 * * OS: T-Kernel * */ #include /* T-Kernel ヘッダ */ #include /* ハードウェア定義 */ #include /* tm_printf() など */ #include /* memcpy() など */ #include /* 6LoWPAN */ /* オブジェクト ID 番号 */ LOCAL ID tidA; /* タスク A の ID */ /* スイッチから入力するように設定する */ LOCAL void init_sw(void) { PIO_CR(A) &= ~(1 << 3); PIO_IE(A) |= (1 << 3); /* SW3 (PA3) */ PIO_CR(E) &= ~(1 << 7); PIO_IE(E) |= (1 << 7); /* SW4 (PE7) */ } /* スイッチの状態を読み込む */ /* n: スイッチ番号 (3, 4) */ /* 戻値: 0:押されていない, 1:押されている */ LOCAL INT get_sw(INT n) { switch (n) { case 3: /* SW3 (PA3) */ return (PIO_DATA(A) & (1 << 3)) == 0; case 4: /* SW4 (PE7) */ return (PIO_DATA(E) & (1 << 7)) == 0; } return 0; } /* LED に出力するように設定する */ LOCAL void init_led(void) { PIO_IE(H) &= ~((1 << 2) | (1 << 1)); /* D1 (PH2), D2 (PH1) */ PIO_CR(H) |= ((1 << 2) | (1 << 1)); PIO_DATA(H) |= ((1 << 2) | (1 << 1)); /* 消灯 */ } /* LED の状態を設定する */ /* n: LED 番号 (1, 2) */ /* v: 0:消灯, 1:点灯 */ LOCAL void set_led(INT n, INT v) { switch (n) { case 1: /* D1 (PH2) */ if (v) PIO_DATA(H) &= ~(1 << 2); /* 点灯 */ else PIO_DATA(H) |= (1 << 2); /* 消灯 */ break; case 2: /* D2 (PH1) */ if (v) PIO_DATA(H) &= ~(1 << 1); /* 点灯 */ else PIO_DATA(H) |= (1 << 1); /* 消灯 */ break; } } /* タスク A */ LOCAL void taskA(INT stacd, void *exinf) { static const utkn_6ln_init_t param = { .channel = RF_CHANNEL_ANY, .scan_type = WPAN_SCAN_ACTIVE, .scan_duration = 4, .options = 0, .tmout = TMO_FEVR, }; static udp6_cep_t dst; static udp6_cep_t cep; ID cepid; INT len; static UB buf[16]; /* 6LoWPAN プロトコルスタックを初期化する */ utkn_6ln_init(¶m); /* UDP 通信端点をオープンする */ cep.addr = ip6_addr_unspec; cep.port = htons(9000); /* UDP サーバのポート番号 */ cepid = udp6_open(&cep); init_sw(); /* スイッチから入力するように設定する */ init_led(); /* LED に出力するように設定する */ for (;;) { /* UDP 受信する */ len = udp6_recv(cepid, buf, sizeof(buf), &dst, NULL, NULL, TMO_FEVR); if (len < 0) continue; tm_printf((UB*)"%.*s\n", len, buf); if (len == 3 && buf[0] == 's' && buf[1] == 'w' && '3' <= buf[2] && buf[2] <= '4') { /* スイッチの状態を返す */ /* sw3 : SW3 の状態を返す */ /* sw4 : SW4 の状態を返す */ len = 1; buf[0] = get_sw(buf[2] - '0') + '0'; } else if (len == 4 && buf[0] == 'd' && '1' <= buf[1] && buf[1] <= '2' && buf[2] == '=' && '0' <= buf[3] && buf[3] <= '1') { /* LED の状態を設定する */ /* d1=0,1 : D1 の状態を設定する */ /* d2=0,1 : D2 の状態を設定する */ set_led(buf[1] - '0', buf[3] - '0'); len = 2; memcpy(buf, "ok", len); } else { /* エラーを返す */ len = 5; memcpy(buf, "error", len); } /* UDP 送信する */ udp6_send(cepid, buf, len, &dst, 5000); } /* このタスクは終了しない */ } /* 初期化処理 */ EXPORT INT usermain(void) { T_CTSK ct; /* タスク A を生成する */ ct.exinf = (void*)('t' | 's' << 8 | 'k' << 16 | 'A' << 24); /* 拡張情報 */ ct.tskatr = TA_HLNG | TA_RNG0; /* タスク属性 */ ct.task = taskA; /* タスク起動アドレス */ ct.itskpri = 1; /* タスク起動時優先度 */ ct.stksz = 1024; /* スタックサイズ */ tidA = tk_cre_tsk(&ct); /* タスク A を生成 */ if (tidA < E_OK) return tidA; /* タスク生成失敗時 */ tk_sta_tsk(tidA, 0); /* タスク A を起動 */ return E_OK; }