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

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

タスク名などを変更、定義場所の移動など

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.1 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;
81ntshell_t ntshell;
82
83unsigned char ntstdio_xi(struct ntstdio_t *handle)
84{
85 char buf[1];
86 if(serial_rea_dat(SIO_PORTID, buf, 1) != 1)
87 return -EIO;
88 return buf[0];
89}
90
91void ntstdio_xo(struct ntstdio_t *handle, unsigned char c)
92{
93 char buf[1];
94 buf[0] = c;
95 serial_wri_dat(SIO_PORTID, buf, 1);
96}
97
98const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
99const struct utsname host_name = {
100 "TOPPERS/ASP3",
101 "GR-PEACH",
102 "3.1.0",
103 "3.1.0",
104 "GR-PEACH",
105 "toppers.jp"
106};
107
108int shell_uname(struct utsname *uts)
109{
110 memcpy(uts, &host_name, sizeof(host_name));
111 return 0;
112}
113
114enum main_state_t {
115 main_state_start,
116 main_state_idle,
117};
118
119struct main_obj_t {
120 TMO timer;
121 enum main_state_t state;
122 SYSTIM prev, now;
123 WS_FBS_ID rcvmsg;
124 T_WS_FBS_QUEUE wbs_queue;
125 WS_FBS_ID sndmsg;
126};
127struct main_obj_t main_obj;
128
129static void netif_link_callback(T_IFNET *ether);
130static void main_initialize();
131static TMO main_get_timer();
132static void main_progress(TMO interval);
133static void main_timeout();
134extern int execute_command(int wait);
135static int usrcmd_ntopt_callback(long *args, void *extobj);
136
137int shellcmd_exit_code;
138volatile int shellcmd_state;
139typedef void (*PowerOn_Reset_t)(long *args);
140jmp_buf shellcmd_exit;
141
142int uart_read(char *buf, int cnt, void *extobj)
143{
144 return serial_rea_dat(SIO_PORTID, (char *)buf, cnt);
145#if 0
146 int result = cnt;
147 ER ret;
148 bool_t tmo = false;
149
150 while (cnt > 0) {
151 /* タイムアウト処理 */
152 if (tmo) {
153 tmo = false;
154 main_timeout();
155 }
156
157 if (main_obj.rcvmsg.ptr == NULL) {
158 ER ret2;
159 TMO timer;
160 WS_FBS_ID msg;
161
162 main_obj.prev = main_obj.now;
163
164 timer = main_get_timer();
165
166 ret = trcv_dtq(MAIN_DATAQUEUE, (intptr_t *)&msg, timer);
167 if ((ret != E_OK) && (ret != E_TMOUT)) {
168 syslog(LOG_ERROR, "trcv_dtq => %d", ret);
169 ext_tsk();
170 return 0;
171 }
172
173 ret2 = get_tim(&main_obj.now);
174 if (ret2 != E_OK) {
175 syslog(LOG_ERROR, "get_tim");
176 ext_tsk();
177 return 0;
178 }
179
180 /* 時間経過 */
181 main_progress(main_obj.now - main_obj.prev);
182
183 if (ret == E_OK) {
184 /* メッセージ受信処理 */
185 if (main_obj.rcvmsg.ptr == NULL) {
186 main_obj.rcvmsg = msg;
187 }
188 else {
189 ws_fbs_enqueue(&main_obj.wbs_queue, msg.ptr);
190 }
191 }
192
193 tmo = true;
194 }
195 else {
196 WS_FBS_SSIZE_T len, slen;
197
198 len = _ws_fbs_get_datalen(main_obj.rcvmsg);
199 if (len > cnt)
200 len = cnt;
201
202 ret = _ws_fbs_get_data(main_obj.rcvmsg, buf, len, &slen);
203 if (ret != E_OK) {
204 syslog(LOG_ERROR, "_ws_fbs_get_data msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret);
205 ext_tsk();
206 }
207 cnt -= slen;
208
209 /* データが空の場合 */
210 if (!_ws_fbs_exist_data(main_obj.rcvmsg)) {
211 ret = _ws_fbs_del(main_obj.rcvmsg);
212 if (ret != E_OK) {
213 syslog(LOG_ERROR, "trcv_dtq msg = %p, type = %d, result = %d", main_obj.rcvmsg.ptr, main_obj.rcvmsg.ptr->hdr.type, ret);
214 ext_tsk();
215 }
216
217 main_obj.rcvmsg.ptr = NULL;
218
219 /* キューからデータを取得 */
220 ret = ws_fbs_dequeue(&main_obj.wbs_queue, &main_obj.rcvmsg.ptr);
221 }
222 }
223 }
224
225 return result;
226#endif
227}
228
229int uart_write(const char *buf, int cnt, void *extobj)
230{
231 return serial_wri_dat(SIO_PORTID, buf, cnt);
232#if 0
233 int result = cnt;
234 ER ret;
235
236 while (cnt > 0) {
237 _ws_fbs_cre(cnt, &main_obj.sndmsg);
238
239 //((ID *)main_obj.sndmsg.ptr->_gap)[0] = wbsid;
240 _ws_fbs_add_data(main_obj.sndmsg, buf, cnt);
241
242 ret = psnd_dtq(WEBSOCKET_MBXID, (intptr_t)main_obj.sndmsg.ptr);
243 if (ret != E_OK) {
244 syslog(LOG_ERROR, "psnd_dtq(WEBSOCKET_MBXID) : result=%d", ret);
245 _ws_fbs_del(main_obj.sndmsg);
246 return ret;
247 }
248 }
249
250 return result;
251#endif
252}
253
254static int cmd_execute(const char *text, void *extobj)
255{
256 if (text != NULL) {
257 ntlibc_strlcpy(command, text, sizeof(command));
258 }
259 ER ret;
260 ID tskid = 0;
261
262 ret = get_tid(&tskid);
263 if (ret != E_OK) {
264 syslog(LOG_ERROR, "get_tid %d", ret);
265 }
266
267 return execute_command(tskid == MAIN_TASK);
268}
269
270/*
271 * メインタスク
272 */
273void main_task(intptr_t exinf)
274{
275 main_initialize();
276
277 ntshell_init(&ntshell, uart_read, uart_write, cmd_execute, NULL);
278 ntshell_set_prompt(&ntshell, "NTShell>");
279 ntshell_execute(&ntshell);
280}
281
282/*
283 * 初期化
284 */
285static void main_initialize()
286{
287 FILINFO fno;
288#if _USE_LFN
289 char lfn[_MAX_LFN + 1];
290 fno.lfname = lfn;
291 fno.lfsize = _MAX_LFN + 1;
292#endif
293 ER ret2;
294
295 ntstdio_init(&ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, ntstdio_xi, ntstdio_xo);
296
297 main_obj.timer = TMO_FEVR;
298 main_obj.state = main_state_start;
299
300 gpio_t led_blue, led_green, led_red, sw;
301 gpio_init_out(&led_blue, LED_BLUE);
302 gpio_init_out(&led_green, LED_GREEN);
303 gpio_init_out(&led_red, LED_RED);
304 gpio_init_in(&sw, USER_BUTTON0);
305
306 bool_t exec = gpio_read(&sw) == 1;
307
308 gpio_write(&led_blue, 1);
309 gpio_write(&led_green, exec ? 1 : 0);
310 gpio_write(&led_red, 0);
311
312 ether_set_link_callback(netif_link_callback);
313
314 /* 初期化 */
315 if (mruby_arduino_init() == 0) {
316 gpio_write(&led_blue, 0);
317 }
318 else {
319 gpio_write(&led_blue, 0);
320 gpio_write(&led_red, 1);
321 }
322
323 gpio_write(&led_green, 0);
324
325 act_tsk(HTTPD1_TASK);
326 act_tsk(HTTPD2_TASK);
327
328 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
329 exec = false;
330 }
331
332 if (exec) {
333 ntlibc_strlcpy(command, "mruby -b 1:/upload/main.mrb", sizeof(command));
334
335 execute_command(1);
336 }
337
338 ret2 = get_tim(&main_obj.now);
339 if (ret2 != E_OK) {
340 syslog(LOG_ERROR, "get_tim");
341 ext_tsk();
342 return;
343 }
344}
345
346/*
347 * タイマー取得
348 */
349static TMO main_get_timer()
350{
351 TMO timer = main_obj.timer;
352
353 return timer;
354}
355
356/*
357 * 時間経過
358 */
359static void main_progress(TMO interval)
360{
361 if (main_obj.timer != TMO_FEVR) {
362 main_obj.timer -= interval;
363 if (main_obj.timer < 0) {
364 main_obj.timer = 0;
365 }
366 }
367}
368
369/*
370 * タイムアウト処理
371 */
372static void main_timeout()
373{
374 //if (main_obj.timer == 0) {
375 //}
376}
377
378/* MACアドレスの設定時に呼ばれる */
379void mbed_mac_address(char *mac)
380{
381 memcpy(mac, mac_addr, 6);
382}
383
384static void netif_link_callback(T_IFNET *ether)
385{
386 FLGPTN flgptn;
387 T_RTSK rtsk;
388 ER ret;
389
390 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
391 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
392 return;
393
394 FD_SET(0, (fd_set *)&flgptn);
395
396 set_flg(FLG_SELECT_WAIT, flgptn);
397}
398
399/*
400 * shellcmdタスク
401 */
402void shellcmd_task(intptr_t exinf)
403{
404 shellcmd_state = 1;
405 shellcmd_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
406 shellcmd_state = 2;
407}
408
409typedef struct
410{
411 const cmd_table_t *table;
412 int count;
413} cmd_table_info_t;
414
415static const cmd_table_t cmdlist[] = {
416 {"cd", "change directory", usrcmd_cd },
417 {"ls", "list files", usrcmd_ls },
418 {"cp", "copy file", usrcmd_cp },
419 {"rm", "remove file", usrcmd_rm },
420 {"mv", "move file", usrcmd_mv },
421 {"mkdir", "Make directory", usrcmd_mkdir},
422 {"hexdump", "Hex dump", usrcmd_hexdump},
423 {"info", "This is a description text string for info command.", usrcmd_info},
424 {"exit", "Exit Natural Tiny Shell", usrcmd_exit},
425};
426cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
427
428static int usrcmd_ntopt_callback(long *args, void *extobj)
429{
430 const cmd_table_t *p = cmd_table_info.table;
431 if (ntlibc_strcmp((const char *)args[1], "help") == 0) {
432 usrcmd_help(args[0], (char **)&args[1]);
433 }
434 else for (int i = 0; i < cmd_table_info.count; i++) {
435 if (ntlibc_strcmp((const char *)args[1], p->cmd) == 0) {
436 return p->func(args[0], (char **)&args[1]);
437 }
438 p++;
439 }
440 if (setjmp(shellcmd_exit) == 0) {
441 (*((PowerOn_Reset_t *)0x18220000))(args);
442 }
443 clean_fd();
444 return 0;
445}
446
447int usrcmd_help(int argc, char **argv)
448{
449 const cmd_table_t *p = cmd_table_info.table;
450 for (int i = 0; i < cmd_table_info.count; i++) {
451 ntstdio_puts(&ntstdio, p->cmd);
452 ntstdio_puts(&ntstdio, "\t:");
453 ntstdio_puts(&ntstdio, p->desc);
454 ntstdio_puts(&ntstdio, "\n");
455 p++;
456 }
457 return 0;
458}
459
460void shellif_into()
461{
462 /* メインタスクの優先度より高くする */
463 chg_pri(SHELLCMD_PRIORITY, MAIN_PRIORITY + 1);
464}
465
466void shellif_outof()
467{
468 /* shellcmdタスクの優先度に戻す */
469 chg_pri(SHELLCMD_PRIORITY, SHELLCMD_PRIORITY);
470}
471
472void shell_abort()
473{
474 asm("bkpt #0");
475
476 shellcmd_exit_code = -1;
477 longjmp(shellcmd_exit, 1);
478}
479
480void shell_exit(int exitcd)
481{
482 shellcmd_exit_code = exitcd;
483 longjmp(shellcmd_exit, 1);
484}
485
486void shell_exit_group(int exitcd)
487{
488 shellcmd_exit_code = exitcd;
489 longjmp(shellcmd_exit, 1);
490}
491
492int execute_command(int wait)
493{
494 ER ret;
495
496 ret = ter_tsk(SHELLCMD_TASK);
497 if ((ret != E_OK) && (ret != E_OBJ)) {
498 syslog(LOG_ERROR, "ter_tsk => %d", ret);
499 }
500
501 tslp_tsk(100000);
502
503 clean_fd();
504
505 shellcmd_state = 0;
506 ret = act_tsk(SHELLCMD_TASK);
507 if (ret != E_OK) {
508 syslog(LOG_ERROR, "act_tsk => %d", ret);
509 }
510
511 if (wait == 0)
512 return 0;
513
514 do {
515 tslp_tsk(100000);
516 } while(shellcmd_state == 1);
517
518 return shellcmd_exit_code;
519}
520
521int shell_clock_getres(clockid_t clk_id, struct timespec *res)
522{
523 if (clk_id != CLOCK_REALTIME)
524 return -EINVAL;
525
526 memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec));
527 res->tv_nsec = 0;
528
529 return 0;
530}
531
532int shell_clock_gettime(clockid_t clk_id, struct timespec *tp)
533{
534 SYSTIM now = 0;
535
536 if (clk_id != CLOCK_REALTIME)
537 return -EINVAL;
538
539 get_tim(&now);
540 tp->tv_sec = now / 1000000;
541 tp->tv_nsec = (now % 1000000) * 1000;
542
543 return 0;
544}
545
546int shell_clock_settime(clockid_t clk_id, const struct timespec *tp)
547{
548 if (clk_id != CLOCK_REALTIME)
549 return -EINVAL;
550
551 rtc_write(tp->tv_sec);
552
553 return 0;
554}
555
556sigset_t g_sigmask;
557
558int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
559{
560 if (old != NULL)
561 memcpy(old, &g_sigmask, sizeof(sigset_t));
562
563 switch (how) {
564 case SIG_BLOCK:
565 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
566 g_sigmask.__bits[i] |= set->__bits[i];
567 }
568 break;
569 case SIG_UNBLOCK:
570 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
571 g_sigmask.__bits[i] &= ~set->__bits[i];
572 }
573 break;
574 case SIG_SETMASK:
575 memcpy(&g_sigmask, set, sizeof(sigset_t));
576 break;
577 default:
578 return -EINVAL;
579 }
580
581 return 0;
582}
583
584struct sigaction sigtable[6];
585
586int shell_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
587{
588 struct sigaction *sat;
589
590 switch(sig){
591 case SIGALRM:
592 sat = &sigtable[0];
593 break;
594 case SIGFPE:
595 sat = &sigtable[1];
596 break;
597 case SIGILL:
598 sat = &sigtable[2];
599 break;
600 case SIGSEGV:
601 sat = &sigtable[3];
602 break;
603 case SIGBUS:
604 sat = &sigtable[4];
605 break;
606 case SIGABRT:
607 sat = &sigtable[5];
608 break;
609 default:
610 return -EINVAL;
611 }
612
613 if (old != NULL)
614 memcpy(old, sat, sizeof(struct sigaction));
615
616 memcpy(sat, sa, sizeof(struct sigaction));
617
618 return 0;
619}
620
621int shell_madvise(void *a, size_t b, int c)
622{
623 return 0;
624}
625
626int stdio_close(struct _IO_FILE *fp)
627{
628 return -EPERM;
629}
630
631size_t stdio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
632{
633 return -EPERM;
634}
635
636size_t stdio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
637{
638 return -EPERM;
639}
640
641size_t stdin_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
642{
643 int i = 0;
644 while (i < len) {
645 int c = ntstdio_getc(&ntstdio);
646 data[i++] = c;
647 if ((c == EOF) || (c == '\n'))
648 break;
649 }
650 return i;
651}
652
653size_t stdout_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
654{
655 for (int i = 0; i < len; i++) {
656 ntstdio_putc(&ntstdio, data[i]);
657 }
658 return len;
659}
660
661size_t stderr_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
662{
663 for (int i = 0; i < len; i++) {
664 ntstdio_putc(&ntstdio, data[i]);
665 }
666 return len;
667}
668
669int sio_close(struct _IO_FILE *fp)
670{
671 return -EPERM;
672}
673
674size_t sio_read(struct _IO_FILE *fp, unsigned char *data, size_t len)
675{
676 return -EPERM;
677}
678
679size_t sio_write(struct _IO_FILE *fp, const unsigned char *data, size_t len)
680{
681 return -EPERM;
682}
683
684off_t sio_seek(struct _IO_FILE *fp, off_t ofs, int org)
685{
686 return -EPERM;
687}
688
689int sio_ioctl(struct _IO_FILE *fp, int request, void *arg)
690{
691 switch (request) {
692 case TIOCGWINSZ:
693 return 0;
694 case TCGETS:
695 return sio_tcgetattr(fp->fd, (struct termios *)arg);
696 case TCSETS + TCSANOW:
697 case TCSETS + TCSADRAIN:
698 case TCSETS + TCSAFLUSH:
699 return sio_tcsetattr(fp->fd, request - TCSETS, (const struct termios *)arg);
700 }
701
702 return -EINVAL;
703}
704
Note: See TracBrowser for help on using the repository browser.