/* * TOPPERS ECHONET Lite Communication Middleware * * Copyright (C) 2014-2017 Cores Co., Ltd. Japan * * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー * スコード中に含まれていること. * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 * の無保証規定を掲載すること. * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ * と. * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 * 作権表示,この利用条件および下記の無保証規定を掲載すること. * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに * 報告すること. * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを * 免責すること. * * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ * の責任を負わない. * * @(#) $Id: main.c 279 2017-04-29 07:33:37Z coas-nagasima $ */ /* * サンプルプログラム(1)の本体 */ #include #include #include #include #include #include #include #include #include "syssvc/serial.h" #include "syssvc/syslog.h" #include "kernel_cfg.h" #include "main.h" #include "rza1.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "ffarch.h" #include "gpio_api.h" #include "ff.h" #include "websocket_fbs.h" #include "ntshell.h" #include "ntstdio.h" #include "usrcmd.h" #include "ntopt.h" #ifndef _MSC_VER void strcpy_s(char *dst, int size, const char *src); #endif ID ws_api_mailboxid = MAIN_DATAQUEUE; ID ws_mempoolid = MPF_NET_BUF_256; #define SIO_PORTID 1 char command[NTOPT_TEXT_MAXLEN]; ntstdio_t ntstdio; const uint8_t mac_addr[6] = {0x00, 0x30, 0x13, 0x06, 0x62, 0xC0}; const char host_name[] = "GR-PEACH"; static void netif_link_callback(T_IFNET *ether); extern int execute_command(int wait); enum main_state_t { main_state_start, main_state_idle, }; struct main_t { TMO timer; enum main_state_t state; SYSTIM prev, now; WS_FBS_ID rcvmsg; T_WS_FBS_QUEUE wbs_queue; WS_FBS_ID sndmsg; }; struct main_t main_obj; static void main_initialize(); static TMO main_get_timer(); static void main_progress(TMO interval); static void main_timeout(); int uart_read(char *buf, int cnt, void *extobj) { return serial_rea_dat(SIO_PORTID, (char *)buf, cnt); #if 0 int result = cnt; ER ret; bool_t tmo = false; while (cnt > 0) { /* タイムアウト処理 */ if (tmo) { tmo = false; main_timeout(); } if (main_obj.rcvmsg.ptr == NULL) { ER ret2; TMO timer; WS_FBS_ID msg; main_obj.prev = main_obj.now; timer = main_get_timer(); ret = trcv_dtq(MAIN_DATAQUEUE, (intptr_t *)&msg, timer); if ((ret != E_OK) && (ret != E_TMOUT)) { syslog(LOG_ERROR, "trcv_dtq => %d", ret); ext_tsk(); return 0; } ret2 = get_tim(&main_obj.now); if (ret2 != E_OK) { syslog(LOG_ERROR, "get_tim"); ext_tsk(); return 0; } /* 時間経過 */ main_progress(main_obj.now - main_obj.prev); if (ret == E_OK) { /* メッセージ受信処理 */ if (main_obj.rcvmsg.ptr == NULL) { main_obj.rcvmsg = msg; } else { ws_fbs_enqueue(&main_obj.wbs_queue, msg.ptr); } } tmo = true; } else { WS_FBS_SSIZE_T len, slen; len = _ws_fbs_get_datalen(main_obj.rcvmsg); if (len > cnt) len = cnt; ret = _ws_fbs_get_data(main_obj.rcvmsg, buf, len, &slen); if (ret != E_OK) { syslog(LOG_ERROR, "_ws_fbs_get_data msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret); ext_tsk(); } cnt -= slen; /* データが空の場合 */ if (!_ws_fbs_exist_data(main_obj.rcvmsg)) { ret = _ws_fbs_del(main_obj.rcvmsg); if (ret != E_OK) { syslog(LOG_ERROR, "trcv_dtq msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret); ext_tsk(); } main_obj.rcvmsg.ptr = NULL; /* キューからデータを取得 */ ret = ws_fbs_dequeue(&main_obj.wbs_queue, &main_obj.rcvmsg.ptr); } } } return result; #endif } int uart_write(const char *buf, int cnt, void *extobj) { return serial_wri_dat(SIO_PORTID, buf, cnt); #if 0 int result = cnt; ER ret; while (cnt > 0) { _ws_fbs_cre(cnt, &main_obj.sndmsg); //((ID *)main_obj.sndmsg.ptr->_gap)[0] = wbsid; _ws_fbs_add_data(main_obj.sndmsg, buf, cnt); ret = psnd_dtq(WEBSOCKET_MBXID, (intptr_t)main_obj.sndmsg.ptr); if (ret != E_OK) { syslog(LOG_ERROR, "psnd_dtq(WEBSOCKET_MBXID) : result=%d", ret); _ws_fbs_del(main_obj.sndmsg); return ret; } } return result; #endif } unsigned char ntstdio_xi(struct ntstdio_t *handle) { char buf[1]; if(serial_rea_dat(SIO_PORTID, buf, 1) != 1) return -1; return buf[0]; } void ntstdio_xo(struct ntstdio_t *handle, unsigned char c) { char buf[1]; buf[0] = c; serial_wri_dat(SIO_PORTID, buf, 1); } ntshell_t ntshell; static int cmd_execute(const char *text, void *extobj); /* * メインタスク */ void main_task(intptr_t exinf) { main_initialize(); ntshell_init(&ntshell, uart_read, uart_write, cmd_execute, NULL); ntshell_set_prompt(&ntshell, "NTShell>"); ntshell_execute(&ntshell); } /* * 初期化 */ static void main_initialize() { FILINFO fno; #if _USE_LFN char lfn[_MAX_LFN + 1]; fno.lfname = lfn; fno.lfsize = _MAX_LFN + 1; #endif ER ret2; ntstdio_init(&ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, ntstdio_xi, ntstdio_xo); main_obj.timer = TMO_FEVR; main_obj.state = main_state_start; gpio_t led_blue, led_green, led_red, sw; gpio_init_out(&led_blue, LED_BLUE); gpio_init_out(&led_green, LED_GREEN); gpio_init_out(&led_red, LED_RED); gpio_init_in(&sw, USER_BUTTON0); bool_t exec = gpio_read(&sw) == 1; gpio_write(&led_blue, 1); gpio_write(&led_green, exec ? 1 : 0); gpio_write(&led_red, 0); ether_set_link_callback(netif_link_callback); /* 初期化 */ if (mruby_arduino_init() == 0) { gpio_write(&led_blue, 0); } else { gpio_write(&led_blue, 0); gpio_write(&led_red, 1); } gpio_write(&led_green, 0); act_tsk(HTTPD1_TASK); act_tsk(HTTPD2_TASK); if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) { exec = false; } if (exec) { strcpy_s(command, sizeof(command), "mruby -b 1:/upload/main.mrb"); execute_command(1); } ret2 = get_tim(&main_obj.now); if (ret2 != E_OK) { syslog(LOG_ERROR, "get_tim"); ext_tsk(); return; } } /* * タイマー取得 */ static TMO main_get_timer() { TMO timer = main_obj.timer; return timer; } /* * 時間経過 */ static void main_progress(TMO interval) { if (main_obj.timer != TMO_FEVR) { main_obj.timer -= interval; if (main_obj.timer < 0) { main_obj.timer = 0; } } } /* * タイムアウト処理 */ static void main_timeout() { //if (main_obj.timer == 0) { //} } /* MACアドレスの設定時に呼ばれる */ void mbed_mac_address(char *mac) { memcpy(mac, mac_addr, 6); } static void netif_link_callback(T_IFNET *ether) { FLGPTN flgptn; T_RTSK rtsk; ER ret; ret = ref_tsk(MRUBY_TASK, &rtsk); if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT)) return; FD_SET(0, (fd_set *)&flgptn); set_flg(FLG_SELECT_WAIT, flgptn); } int gethostname(char *name, size_t len) { return strlcpy(name, host_name, len); } static int usrcmd_ntopt_callback(int argc, char **argv, void *extobj); int mruby_exit_code; volatile int mruby_state; typedef void (*PowerOn_Reset_t)(int argc, char **argv); jmp_buf process_exit; /* * mruby実行タスク */ void mruby_task(intptr_t exinf) { mruby_state = 1; mruby_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL); mruby_state = 2; } static int usrcmd_ntopt_callback(int argc, char **argv, void *extobj) { if (setjmp(process_exit) == 0) { (*((PowerOn_Reset_t *)0x18200000))(argc, argv); } clean_fd(); return 0; } void shellif_into() { /* メインタスクの優先度より高くする */ chg_pri(MRUBY_PRIORITY, MAIN_PRIORITY + 1); } void shellif_outof() { /* mruby実行タスクの優先度に戻す */ chg_pri(MRUBY_PRIORITY, MRUBY_PRIORITY); } void shell_abort() { asm("bkpt #0"); mruby_exit_code = -1; longjmp(process_exit, 1); } void shell_exit(int exitcd) { mruby_exit_code = exitcd; longjmp(process_exit, 1); } int execute_command(int wait) { ER ret; ret = ter_tsk(MRUBY_TASK); if ((ret != E_OK) && (ret != E_OBJ)) { syslog(LOG_ERROR, "ter_tsk => %d", ret); } tslp_tsk(100000); clean_fd(); mruby_state = 0; ret = act_tsk(MRUBY_TASK); if (ret != E_OK) { syslog(LOG_ERROR, "act_tsk => %d", ret); } if (wait == 0) return 0; do { tslp_tsk(100000); } while(mruby_state == 1); return mruby_exit_code; } static int cmd_execute(const char *text, void *extobj) { strlcpy(command, text, sizeof(command)); return execute_command(1); } int stdio_close(struct _IO_FILE *fp) { return -1; } size_t stdio_read(struct _IO_FILE *fp, unsigned char *data, size_t len) { return -1; } size_t stdio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len) { return -1; } size_t stdin_read(struct _IO_FILE *fp, unsigned char *data, size_t len) { int i = 0; while (i < len) { int c = ntstdio_getc(&ntstdio); data[i++] = c; if ((c == EOF) || (c == '\n')) break; } return i; } size_t stdout_write(struct _IO_FILE *fp, const unsigned char *data, size_t len) { for (int i = 0; i < len; i++) { ntstdio_putc(&ntstdio, data[i]); } return len; } size_t stderr_write(struct _IO_FILE *fp, const unsigned char *data, size_t len) { for (int i = 0; i < len; i++) { ntstdio_putc(&ntstdio, data[i]); } return len; } int sio_close(struct _IO_FILE *fp) { return -1; } size_t sio_read(struct _IO_FILE *fp, unsigned char *data, size_t len) { return -1; } size_t sio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len) { return -1; }