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

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

dateコマンド追加
コードの整理

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