source: EcnlProtoTool/trunk/ntshell/src/main.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.0 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2014-2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37
38/*
39 * サンプルプログラム(1)の本体
40 */
41
42#include "shellif.h"
43#include <kernel.h>
44#include <t_stdlib.h>
45#include <sil.h>
46#include <setjmp.h>
47#include <string.h>
48#include "syssvc/serial.h"
49#include "syssvc/syslog.h"
50#include "kernel_cfg.h"
51#include "main.h"
52#include "rza1.h"
53#include <tinet_config.h>
54#include <netinet/in.h>
55#include <netinet/in_itron.h>
56#include <tinet_nic_defs.h>
57#include <tinet_cfg.h>
58#include <netinet/in_var.h>
59#include <net/ethernet.h>
60#include <net/if6_var.h>
61#include <net/net.h>
62#include <net/if_var.h>
63#include <netinet/udp_var.h>
64#include "ffarch.h"
65#include "ff.h"
66#include "websocket_fbs.h"
67#include "core/ntshell.h"
68#include "core/ntlibc.h"
69#include "util/ntstdio.h"
70#include "usrcmd.h"
71#include "util/ntopt.h"
72#include "socket_stub.h"
73
74ID ws_api_mailboxid = MAIN_DATAQUEUE;
75ID ws_mempoolid = MPF_NET_BUF_256;
76
77#define SIO_PORTID 1
78
79char command[NTOPT_TEXT_MAXLEN];
80ntstdio_t ntstdio;
81
82const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
83const struct utsname host_name = {
84 "TOPPERS/ASP3",
85 "GR-PEACH",
86 "3.1.0",
87 "3.1.0",
88 "GR-PEACH",
89 "toppers.jp"
90};
91
92static void netif_link_callback(T_IFNET *ether);
93extern int execute_command(int wait);
94
95enum main_state_t {
96 main_state_start,
97 main_state_idle,
98};
99
100struct main_t {
101 TMO timer;
102 enum main_state_t state;
103 SYSTIM prev, now;
104 WS_FBS_ID rcvmsg;
105 T_WS_FBS_QUEUE wbs_queue;
106 WS_FBS_ID sndmsg;
107};
108struct main_t main_obj;
109
110static void main_initialize();
111static TMO main_get_timer();
112static void main_progress(TMO interval);
113static void main_timeout();
114
115int uart_read(char *buf, int cnt, void *extobj)
116{
117 return serial_rea_dat(SIO_PORTID, (char *)buf, cnt);
118#if 0
119 int result = cnt;
120 ER ret;
121 bool_t tmo = false;
122
123 while (cnt > 0) {
124 /* タイムアウト処理 */
125 if (tmo) {
126 tmo = false;
127 main_timeout();
128 }
129
130 if (main_obj.rcvmsg.ptr == NULL) {
131 ER ret2;
132 TMO timer;
133 WS_FBS_ID msg;
134
135 main_obj.prev = main_obj.now;
136
137 timer = main_get_timer();
138
139 ret = trcv_dtq(MAIN_DATAQUEUE, (intptr_t *)&msg, timer);
140 if ((ret != E_OK) && (ret != E_TMOUT)) {
141 syslog(LOG_ERROR, "trcv_dtq => %d", ret);
142 ext_tsk();
143 return 0;
144 }
145
146 ret2 = get_tim(&main_obj.now);
147 if (ret2 != E_OK) {
148 syslog(LOG_ERROR, "get_tim");
149 ext_tsk();
150 return 0;
151 }
152
153 /* 時間経過 */
154 main_progress(main_obj.now - main_obj.prev);
155
156 if (ret == E_OK) {
157 /* メッセージ受信処理 */
158 if (main_obj.rcvmsg.ptr == NULL) {
159 main_obj.rcvmsg = msg;
160 }
161 else {
162 ws_fbs_enqueue(&main_obj.wbs_queue, msg.ptr);
163 }
164 }
165
166 tmo = true;
167 }
168 else {
169 WS_FBS_SSIZE_T len, slen;
170
171 len = _ws_fbs_get_datalen(main_obj.rcvmsg);
172 if (len > cnt)
173 len = cnt;
174
175 ret = _ws_fbs_get_data(main_obj.rcvmsg, buf, len, &slen);
176 if (ret != E_OK) {
177 syslog(LOG_ERROR, "_ws_fbs_get_data msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret);
178 ext_tsk();
179 }
180 cnt -= slen;
181
182 /* データが空の場合 */
183 if (!_ws_fbs_exist_data(main_obj.rcvmsg)) {
184 ret = _ws_fbs_del(main_obj.rcvmsg);
185 if (ret != E_OK) {
186 syslog(LOG_ERROR, "trcv_dtq msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret);
187 ext_tsk();
188 }
189
190 main_obj.rcvmsg.ptr = NULL;
191
192 /* キューからデータを取得 */
193 ret = ws_fbs_dequeue(&main_obj.wbs_queue, &main_obj.rcvmsg.ptr);
194 }
195 }
196 }
197
198 return result;
199#endif
200}
201
202int uart_write(const char *buf, int cnt, void *extobj)
203{
204 return serial_wri_dat(SIO_PORTID, buf, cnt);
205#if 0
206 int result = cnt;
207 ER ret;
208
209 while (cnt > 0) {
210 _ws_fbs_cre(cnt, &main_obj.sndmsg);
211
212 //((ID *)main_obj.sndmsg.ptr->_gap)[0] = wbsid;
213 _ws_fbs_add_data(main_obj.sndmsg, buf, cnt);
214
215 ret = psnd_dtq(WEBSOCKET_MBXID, (intptr_t)main_obj.sndmsg.ptr);
216 if (ret != E_OK) {
217 syslog(LOG_ERROR, "psnd_dtq(WEBSOCKET_MBXID) : result=%d", ret);
218 _ws_fbs_del(main_obj.sndmsg);
219 return ret;
220 }
221 }
222
223 return result;
224#endif
225}
226
227unsigned char ntstdio_xi(struct ntstdio_t *handle)
228{
229 char buf[1];
230 if(serial_rea_dat(SIO_PORTID, buf, 1) != 1)
231 return -EIO;
232 return buf[0];
233}
234
235void ntstdio_xo(struct ntstdio_t *handle, unsigned char c)
236{
237 char buf[1];
238 buf[0] = c;
239 serial_wri_dat(SIO_PORTID, buf, 1);
240}
241
242ntshell_t ntshell;
243static int cmd_execute(const char *text, void *extobj);
244
245/*
246 * メインタスク
247 */
248void main_task(intptr_t exinf)
249{
250 main_initialize();
251
252 ntshell_init(&ntshell, uart_read, uart_write, cmd_execute, NULL);
253 ntshell_set_prompt(&ntshell, "NTShell>");
254 ntshell_execute(&ntshell);
255}
256
257/*
258 * 初期化
259 */
260static void main_initialize()
261{
262 FILINFO fno;
263#if _USE_LFN
264 char lfn[_MAX_LFN + 1];
265 fno.lfname = lfn;
266 fno.lfsize = _MAX_LFN + 1;
267#endif
268 ER ret2;
269
270 ntstdio_init(&ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, ntstdio_xi, ntstdio_xo);
271
272 main_obj.timer = TMO_FEVR;
273 main_obj.state = main_state_start;
274
275 gpio_t led_blue, led_green, led_red, sw;
276 gpio_init_out(&led_blue, LED_BLUE);
277 gpio_init_out(&led_green, LED_GREEN);
278 gpio_init_out(&led_red, LED_RED);
279 gpio_init_in(&sw, USER_BUTTON0);
280
281 bool_t exec = gpio_read(&sw) == 1;
282
283 gpio_write(&led_blue, 1);
284 gpio_write(&led_green, exec ? 1 : 0);
285 gpio_write(&led_red, 0);
286
287 ether_set_link_callback(netif_link_callback);
288
289 /* 初期化 */
290 if (mruby_arduino_init() == 0) {
291 gpio_write(&led_blue, 0);
292 }
293 else {
294 gpio_write(&led_blue, 0);
295 gpio_write(&led_red, 1);
296 }
297
298 gpio_write(&led_green, 0);
299
300 act_tsk(HTTPD1_TASK);
301 act_tsk(HTTPD2_TASK);
302
303 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
304 exec = false;
305 }
306
307 if (exec) {
308 ntlibc_strlcpy(command, "mruby -b 1:/upload/main.mrb", sizeof(command));
309
310 execute_command(1);
311 }
312
313 ret2 = get_tim(&main_obj.now);
314 if (ret2 != E_OK) {
315 syslog(LOG_ERROR, "get_tim");
316 ext_tsk();
317 return;
318 }
319}
320
321/*
322 * タイマー取得
323 */
324static TMO main_get_timer()
325{
326 TMO timer = main_obj.timer;
327
328 return timer;
329}
330
331/*
332 * 時間経過
333 */
334static void main_progress(TMO interval)
335{
336 if (main_obj.timer != TMO_FEVR) {
337 main_obj.timer -= interval;
338 if (main_obj.timer < 0) {
339 main_obj.timer = 0;
340 }
341 }
342}
343
344/*
345 * タイムアウト処理
346 */
347static void main_timeout()
348{
349 //if (main_obj.timer == 0) {
350 //}
351}
352
353/* MACアドレスの設定時に呼ばれる */
354void mbed_mac_address(char *mac)
355{
356 memcpy(mac, mac_addr, 6);
357}
358
359static void netif_link_callback(T_IFNET *ether)
360{
361 FLGPTN flgptn;
362 T_RTSK rtsk;
363 ER ret;
364
365 ret = ref_tsk(MRUBY_TASK, &rtsk);
366 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
367 return;
368
369 FD_SET(0, (fd_set *)&flgptn);
370
371 set_flg(FLG_SELECT_WAIT, flgptn);
372}
373
374int shell_uname(struct utsname *uts)
375{
376 return memcpy(uts, &host_name, sizeof(host_name));
377}
378
379static int usrcmd_ntopt_callback(long *args, void *extobj);
380int mruby_exit_code;
381volatile int mruby_state;
382typedef void (*PowerOn_Reset_t)(long *args);
383jmp_buf process_exit;
384
385/*
386 * mruby実行タスク
387 */
388void mruby_task(intptr_t exinf)
389{
390 mruby_state = 1;
391 mruby_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
392 mruby_state = 2;
393}
394
395typedef struct
396{
397 const cmd_table_t *table;
398 int count;
399} cmd_table_info_t;
400
401static const cmd_table_t cmdlist[] = {
402 {"cd", "change directory", usrcmd_cd },
403 {"ls", "list files", usrcmd_ls },
404 {"cp", "copy file", usrcmd_cp },
405 {"rm", "remove file", usrcmd_rm },
406 {"mv", "move file", usrcmd_mv },
407 {"mkdir", "Make directory", usrcmd_mkdir},
408 {"hexdump", "Hex dump", usrcmd_hexdump},
409 {"info", "This is a description text string for info command.", usrcmd_info},
410 {"exit", "Exit Natural Tyny Shell", usrcmd_exit},
411};
412cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
413
414static int usrcmd_ntopt_callback(long *args, void *extobj)
415{
416 const cmd_table_t *p = cmd_table_info.table;
417 if (ntlibc_strcmp((const char *)args[1], "help") == 0) {
418 usrcmd_help(args[0], (char **)&args[1]);
419 }
420 else for (int i = 0; i < cmd_table_info.count; i++) {
421 if (ntlibc_strcmp((const char *)args[1], p->cmd) == 0) {
422 return p->func(args[0], (char **)&args[1]);
423 }
424 p++;
425 }
426 if (setjmp(process_exit) == 0) {
427 (*((PowerOn_Reset_t *)0x18200000))(args);
428 }
429 clean_fd();
430 return 0;
431}
432
433int usrcmd_help(int argc, char **argv)
434{
435 const cmd_table_t *p = cmd_table_info.table;
436 for (int i = 0; i < cmd_table_info.count; i++) {
437 ntstdio_puts(&ntstdio, p->cmd);
438 ntstdio_puts(&ntstdio, "\t:");
439 ntstdio_puts(&ntstdio, p->desc);
440 ntstdio_puts(&ntstdio, "\n");
441 p++;
442 }
443 return 0;
444}
445
446void shellif_into()
447{
448 /* メインタスクの優先度より高くする */
449 chg_pri(MRUBY_PRIORITY, MAIN_PRIORITY + 1);
450}
451
452void shellif_outof()
453{
454 /* mruby実行タスクの優先度に戻す */
455 chg_pri(MRUBY_PRIORITY, MRUBY_PRIORITY);
456}
457
458void shell_abort()
459{
460 asm("bkpt #0");
461
462 mruby_exit_code = -1;
463 longjmp(process_exit, 1);
464}
465
466void shell_exit(int exitcd)
467{
468 mruby_exit_code = exitcd;
469 longjmp(process_exit, 1);
470}
471
472void shell_exit_group(int exitcd)
473{
474 mruby_exit_code = exitcd;
475 longjmp(process_exit, 1);
476}
477
478int execute_command(int wait)
479{
480 ER ret;
481
482 ret = ter_tsk(MRUBY_TASK);
483 if ((ret != E_OK) && (ret != E_OBJ)) {
484 syslog(LOG_ERROR, "ter_tsk => %d", ret);
485 }
486
487 tslp_tsk(100000);
488
489 clean_fd();
490
491 mruby_state = 0;
492 ret = act_tsk(MRUBY_TASK);
493 if (ret != E_OK) {
494 syslog(LOG_ERROR, "act_tsk => %d", ret);
495 }
496
497 if (wait == 0)
498 return 0;
499
500 do {
501 tslp_tsk(100000);
502 } while(mruby_state == 1);
503
504 return mruby_exit_code;
505}
506
507static int cmd_execute(const char *text, void *extobj)
508{
509 ntlibc_strlcpy(command, text, sizeof(command));
510 return execute_command(1);
511}
512
513int stdio_close(struct _IO_FILE *fp)
514{
515 return -EPERM;
516}
517
518size_t stdio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
519{
520 return -EPERM;
521}
522
523size_t stdio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
524{
525 return -EPERM;
526}
527
528size_t stdin_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
529{
530 int i = 0;
531 while (i < len) {
532 int c = ntstdio_getc(&ntstdio);
533 data[i++] = c;
534 if ((c == EOF) || (c == '\n'))
535 break;
536 }
537 return i;
538}
539
540size_t stdout_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
541{
542 for (int i = 0; i < len; i++) {
543 ntstdio_putc(&ntstdio, data[i]);
544 }
545 return len;
546}
547
548size_t stderr_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
549{
550 for (int i = 0; i < len; i++) {
551 ntstdio_putc(&ntstdio, data[i]);
552 }
553 return len;
554}
555
556int sio_close(struct _IO_FILE *fp)
557{
558 return -EPERM;
559}
560
561size_t sio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
562{
563 return -EPERM;
564}
565
566size_t sio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
567{
568 return -EPERM;
569}
570
571off_t sio_seek(struct _IO_FILE *fp, off_t ofs, int org)
572{
573 return -EPERM;
574}
575
576int sio_ioctl(struct _IO_FILE *fp, int request, void *arg)
577{
578 switch (request) {
579 case TIOCGWINSZ:
580 return 0;
581 case TCGETS:
582 return sio_tcgetattr(fp->fd, (struct termios *)arg);
583 case TCSETS + TCSANOW:
584 case TCSETS + TCSADRAIN:
585 case TCSETS + TCSAFLUSH:
586 return sio_tcsetattr(fp->fd, request - TCSETS, (const struct termios *)arg);
587 }
588
589 return -EINVAL;
590}
591
592int shell_clock_getres(clockid_t clk_id, struct timespec *res)
593{
594 if (clk_id != CLOCK_REALTIME)
595 return -EINVAL;
596
597 memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec));
598 res->tv_nsec = 0;
599
600 return 0;
601}
602
603int shell_clock_gettime(clockid_t clk_id, struct timespec *tp)
604{
605 SYSTIM now = 0;
606
607 if (clk_id != CLOCK_REALTIME)
608 return -EINVAL;
609
610 get_tim(&now);
611 tp->tv_sec = now / 1000000;
612 tp->tv_nsec = (now % 1000000) * 1000;
613
614 return 0;
615}
616
617int shell_clock_settime(clockid_t clk_id, const struct timespec *tp)
618{
619 if (clk_id != CLOCK_REALTIME)
620 return -EINVAL;
621
622 rtc_write(tp->tv_sec);
623
624 return 0;
625}
626
627sigset_t g_sigmask;
628
629int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
630{
631 if (old != NULL)
632 memcpy(old, &g_sigmask, sizeof(sigset_t));
633
634 switch (how) {
635 case SIG_BLOCK:
636 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
637 g_sigmask.__bits[i] |= set->__bits[i];
638 }
639 break;
640 case SIG_UNBLOCK:
641 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
642 g_sigmask.__bits[i] &= ~set->__bits[i];
643 }
644 break;
645 case SIG_SETMASK:
646 memcpy(&g_sigmask, set, sizeof(sigset_t));
647 break;
648 default:
649 return -EINVAL;
650 }
651
652 return 0;
653}
654
655struct sigaction sigtable[6];
656
657int shell_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
658{
659 struct sigaction *sat;
660
661 switch(sig){
662 case SIGALRM:
663 sat = &sigtable[0];
664 break;
665 case SIGFPE:
666 sat = &sigtable[1];
667 break;
668 case SIGILL:
669 sat = &sigtable[2];
670 break;
671 case SIGSEGV:
672 sat = &sigtable[3];
673 break;
674 case SIGBUS:
675 sat = &sigtable[4];
676 break;
677 case SIGABRT:
678 sat = &sigtable[5];
679 break;
680 default:
681 return -EINVAL;
682 }
683
684 if (old != NULL)
685 memcpy(old, sat, sizeof(struct sigaction));
686
687 memcpy(sat, sa, sizeof(struct sigaction));
688
689 return 0;
690}
691
692int shell_madvise(void *a, size_t b, int c)
693{
694 return 0;
695}
696
Note: See TracBrowser for help on using the repository browser.