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

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

ntshellのコードを整理

  • 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 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
82unsigned char ntstdio_xi(struct ntstdio_t *handle)
83{
84 char buf[1];
85 if(serial_rea_dat(SIO_PORTID, buf, 1) != 1)
86 return -EIO;
87 return buf[0];
88}
89
90void ntstdio_xo(struct ntstdio_t *handle, unsigned char c)
91{
92 char buf[1];
93 buf[0] = c;
94 serial_wri_dat(SIO_PORTID, buf, 1);
95}
96
97const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
98const struct utsname host_name = {
99 "TOPPERS/ASP3",
100 "GR-PEACH",
101 "3.1.0",
102 "3.1.0",
103 "GR-PEACH",
104 "toppers.jp"
105};
106
107int shell_uname(struct utsname *uts)
108{
109 memcpy(uts, &host_name, sizeof(host_name));
110 return 0;
111}
112
113enum main_state_t {
114 main_state_start,
115 main_state_idle,
116};
117
118struct main_obj_t {
119 ntshell_t ntshell;
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 main_change_netif_link(T_IFNET *ether);
130static void main_initialize(struct main_obj_t *obj);
131static TMO main_get_timer(struct main_obj_t *obj);
132static void main_progress(struct main_obj_t *obj, TMO elapse);
133static void main_timeout(struct main_obj_t *obj);
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}
146
147int uart_write(const char *buf, int cnt, void *extobj)
148{
149 return serial_wri_dat(SIO_PORTID, buf, cnt);
150}
151
152int cmd_execute(const char *text, void *extobj)
153{
154 if (text != NULL) {
155 ntlibc_strlcpy(command, text, sizeof(command));
156 }
157 ER ret;
158 ID tskid = 0;
159
160 ret = get_tid(&tskid);
161 if (ret != E_OK) {
162 syslog(LOG_ERROR, "get_tid %d", ret);
163 }
164
165 return execute_command(tskid == MAIN_TASK);
166}
167
168/*
169 * メインタスク
170 */
171void main_task(intptr_t exinf)
172{
173 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
174
175 main_initialize(obj);
176
177 ntshell_init(&obj->ntshell, uart_read, uart_write, cmd_execute, obj);
178 ntshell_set_prompt(&obj->ntshell, "NTShell>");
179 ntshell_execute(&obj->ntshell);
180}
181
182/*
183 * 初期化
184 */
185static void main_initialize(struct main_obj_t *obj)
186{
187 FILINFO fno;
188#if _USE_LFN
189 char lfn[_MAX_LFN + 1];
190 fno.lfname = lfn;
191 fno.lfsize = _MAX_LFN + 1;
192#endif
193 ER ret;
194
195 ntstdio_init(&ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, ntstdio_xi, ntstdio_xo);
196
197 obj->timer = TMO_FEVR;
198 obj->state = main_state_start;
199
200 gpio_t led_blue, led_green, led_red, sw;
201 gpio_init_out(&led_blue, LED_BLUE);
202 gpio_init_out(&led_green, LED_GREEN);
203 gpio_init_out(&led_red, LED_RED);
204 gpio_init_in(&sw, USER_BUTTON0);
205
206 bool_t exec = gpio_read(&sw) == 1;
207
208 gpio_write(&led_blue, 1);
209 gpio_write(&led_green, exec ? 1 : 0);
210 gpio_write(&led_red, 0);
211
212 ether_set_link_callback(main_change_netif_link);
213
214 /* 初期化 */
215 if (mruby_arduino_init() == 0) {
216 gpio_write(&led_blue, 0);
217 }
218 else {
219 gpio_write(&led_blue, 0);
220 gpio_write(&led_red, 1);
221 }
222
223 gpio_write(&led_green, 0);
224
225 act_tsk(HTTPD1_TASK);
226 act_tsk(HTTPD2_TASK);
227
228 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
229 exec = false;
230 }
231
232 if (exec) {
233 ntlibc_strlcpy(command, "mruby -b 1:/upload/main.mrb", sizeof(command));
234
235 execute_command(1);
236 }
237
238 ret = get_tim(&obj->now);
239 if (ret != E_OK) {
240 syslog(LOG_ERROR, "get_tim");
241 ext_tsk();
242 return;
243 }
244}
245
246/*
247 * タイマー取得
248 */
249static TMO main_get_timer(struct main_obj_t *obj)
250{
251 TMO timer = obj->timer;
252
253 return timer;
254}
255
256/*
257 * 時間経過
258 */
259static void main_progress(struct main_obj_t *obj, TMO elapse)
260{
261 if (obj->timer != TMO_FEVR) {
262 obj->timer -= elapse;
263 if (obj->timer < 0) {
264 obj->timer = 0;
265 }
266 }
267}
268
269/*
270 * タイムアウト処理
271 */
272static void main_timeout(struct main_obj_t *obj)
273{
274 //if (obj->timer == 0) {
275 //}
276}
277
278/* MACアドレスの設定時に呼ばれる */
279void mbed_mac_address(char *mac)
280{
281 memcpy(mac, mac_addr, 6);
282}
283
284static void main_change_netif_link(T_IFNET *ether)
285{
286 FLGPTN flgptn;
287 T_RTSK rtsk;
288 ER ret;
289
290 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
291 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
292 return;
293
294 FD_SET(0, (fd_set *)&flgptn);
295
296 set_flg(FLG_SELECT_WAIT, flgptn);
297}
298
299/*
300 * shellcmdタスク
301 */
302void shellcmd_task(intptr_t exinf)
303{
304 shellcmd_state = 1;
305 shellcmd_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
306 shellcmd_state = 2;
307}
308
309static const cmd_table_t cmdlist[] = {
310 {"cd", "change directory", usrcmd_cd },
311 {"ls", "list files", usrcmd_ls },
312 {"cp", "copy file", usrcmd_cp },
313 {"rm", "remove file", usrcmd_rm },
314 {"mv", "move file", usrcmd_mv },
315 {"mkdir", "Make directory", usrcmd_mkdir},
316 {"hexdump", "Hex dump", usrcmd_hexdump},
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.