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

Last change on this file since 441 was 441, 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: 19.8 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 "target_syssvc.h"
51#include "kernel_cfg.h"
52#include "main.h"
53#include "fdtable.h"
54#ifndef NTSHELL_NO_SOCKET
55#include <tinet_config.h>
56#include <netinet/in.h>
57#include <netinet/in_itron.h>
58#include <tinet_nic_defs.h>
59#include <tinet_cfg.h>
60#include <netinet/in_var.h>
61#include <net/ethernet.h>
62#include <net/if6_var.h>
63#include <net/net.h>
64#include <net/if_var.h>
65#include <netinet/udp_var.h>
66#include "ffarch.h"
67#include "ff.h"
68#include "websocket_fbs.h"
69#include "core/ntshell.h"
70#include "core/ntlibc.h"
71#include "util/ntstdio.h"
72#include "usrcmd.h"
73#include "util/ntopt.h"
74#include "netapp/dhcp4_cli.h"
75#include "ntp_cli.h"
76#include "netcmd.h"
77#endif
78
79ID ws_api_mailboxid = MAIN_DATAQUEUE;
80ID ws_mempoolid = MPF_NET_BUF_256;
81extern ntstdio_t *ntstdio;
82
83char command[NTOPT_TEXT_MAXLEN];
84
85const uint8_t mac_addr[6] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC};
86const struct utsname host_name = {
87 "TOPPERS/ASP3",
88 TARGET_NAME,
89 "3.5.0",
90 "3.5.0",
91 TARGET_NAME,
92 "toppers.jp"
93};
94
95int shell_uname(struct utsname *uts)
96{
97 memcpy(uts, &host_name, sizeof(host_name));
98 return 0;
99}
100
101enum main_state_t {
102 main_state_start,
103 main_state_idle,
104#ifndef NTSHELL_NO_SOCKET
105 main_state_start_dhcp,
106#endif
107 main_state_servey_cmd,
108};
109
110struct main_obj_t {
111 ntshell_t ntshell;
112 int timer;
113 enum main_state_t state;
114 SYSTIM prev, now;
115 task_base_t **tasks;
116 int task_count;
117#ifndef NTSHELL_NO_SOCKET
118 uint8_t link;
119 uint8_t link_up;
120 uint8_t up;
121 uint8_t dhcp;
122 uint8_t ntp;
123 ntp_cli_state_t ntp_state;
124#endif
125 bool_t exec;
126 int event_req, event_res;
127};
128struct main_obj_t main_obj;
129
130#ifndef NTSHELL_NO_SOCKET
131static void netif_link_callback(T_IFNET *ether);
132static void main_change_netif_link(uint8_t link_up, uint8_t up);
133#endif
134static void main_initialize(struct main_obj_t *obj);
135static void main_finalize(struct main_obj_t *obj);
136static int main_get_timer(struct main_obj_t *obj);
137static void main_progress(struct main_obj_t *obj, int elapse);
138static void main_timeout(struct main_obj_t *obj, bool_t wakeup);
139static int execute_command(struct main_obj_t *obj, int wait);
140static int usrcmd_ntopt_callback(long *args, void *extobj);
141#ifndef NTSHELL_NO_SOCKET
142static void ntp_cli_state_changed(ntp_cli_state_t state);
143#endif
144
145void stdio_open(ID portid);
146void stdio_input(unsigned char c);
147
148bool_t dhcp_enable;
149int ntshell_exit;
150int shellcmd_exit_code;
151volatile int shellcmd_state;
152typedef void (*PowerOn_Reset_t)(long *args);
153jmp_buf shellcmd_exit;
154
155void main_task_init(task_base_t **tasks, int task_count)
156{
157 main_obj.tasks = tasks;
158 main_obj.task_count = task_count;
159}
160
161int uart_read(char *buf, int cnt, void *extobj)
162{
163 struct main_obj_t *obj = (struct main_obj_t *)extobj;
164 int result;
165 ER ret;
166 int timer;
167 bool_t wakeup = false;
168
169 obj->prev = obj->now;
170
171 if (obj->event_req != obj->event_res) {
172 obj->event_res = obj->event_req;
173 wakeup = true;
174#ifndef NTSHELL_NO_SOCKET
175 if (obj->dhcp) {
176 obj->dhcp = 0;
177 obj->state = main_state_start_dhcp;
178 }
179#endif
180 obj->timer = 0;
181 }
182
183 /* タイマー取得 */
184 timer = main_get_timer(obj);
185
186 /* 待ち */
187 ret = serial_trea_dat(SIO_PORTID, buf, cnt, timer);
188 if ((ret < 0) && (ret != E_OK) && (ret != E_TMOUT) && (ret != E_RLWAI)) {
189 syslog(LOG_NOTICE, "tslp_tsk ret: %s %d", itron_strerror(ret), timer);
190 ntshell_exit = 1;
191 return -1;
192 }
193 if (ret != E_TMOUT)
194 wakeup = true;
195 result = (int)ret;
196
197 ret = get_tim(&obj->now);
198 if (ret != E_OK) {
199 syslog(LOG_NOTICE, "get_tim ret: %s", itron_strerror(ret));
200 ntshell_exit = 1;
201 return -1;
202 }
203
204 /* 時間経過 */
205 int elapse = obj->now - obj->prev;
206 main_progress(obj, elapse);
207
208 /* タイムアウト処理 */
209 main_timeout(obj, wakeup);
210
211 return result;
212}
213
214int uart_write(const char *buf, int cnt, void *extobj)
215{
216 return serial_wri_dat(SIO_PORTID, buf, cnt);
217}
218
219int cmd_execute(const char *text, void *extobj)
220{
221 if (text != NULL) {
222 ntlibc_strlcpy(command, text, sizeof(command));
223 }
224 ER ret;
225 ID tskid = 0;
226
227 ret = get_tid(&tskid);
228 if (ret != E_OK) {
229 syslog(LOG_ERROR, "get_tid %d", ret);
230 }
231
232 return execute_command(&main_obj, tskid == MAIN_TASK);
233}
234
235gpio_t led_blue, led_green, led_red, sw;
236
237/*
238 * メインタスク
239 */
240void main_task(intptr_t exinf)
241{
242 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
243
244 gpio_init_out(&led_blue, LED_BLUE);
245 gpio_init_out(&led_green, LED_GREEN);
246 gpio_init_out(&led_red, LED_RED);
247 gpio_init_in(&sw, USER_BUTTON0);
248
249 obj->exec = gpio_read(&sw) == 1;
250
251 gpio_write(&led_blue, 1);
252 gpio_write(&led_green, obj->exec ? 1 : 0);
253 gpio_write(&led_red, 0);
254
255 ether_set_link_callback(main_change_netif_link);
256
257 /* 初期化 */
258 ffarch_init();
259
260 stdio_open(SIO_PORTID);
261
262#ifndef NTSHELL_NO_SOCKET
263 ntp_cli_set_state_changed_cb(ntp_cli_state_changed);
264#endif
265
266 main_initialize(obj);
267
268 ntshell_init(&obj->ntshell, uart_read, uart_write, cmd_execute, obj);
269 ntshell_set_prompt(&obj->ntshell, "NTShell>");
270 ntshell_execute(&obj->ntshell);
271
272 main_finalize(obj);
273}
274
275/*
276 * 初期化
277 */
278static void main_initialize(struct main_obj_t *obj)
279{
280 ER ret;
281 ID tskid = 0;
282
283 ret = get_tid(&tskid);
284 if (ret != E_OK) {
285 syslog(LOG_ERROR, "get_tid %d", ret);
286 return;
287 }
288
289 obj->timer = 100000;
290 obj->state = main_state_start;
291
292 for (int i = 0; i < obj->task_count; i++) {
293 task_base_t *task = obj->tasks[i];
294 task->on_start(task, tskid);
295 }
296
297 gpio_write(&led_blue, 0);
298 gpio_write(&led_green, 0);
299
300 act_tsk(HTTPD1_TASK);
301 act_tsk(HTTPD2_TASK);
302
303 ret = get_tim(&obj->now);
304 if (ret != E_OK) {
305 syslog(LOG_ERROR, "get_tim");
306 ext_tsk();
307 return;
308 }
309}
310
311static void main_finalize(struct main_obj_t *obj)
312{
313 for (int i = 0; i < obj->task_count; i++) {
314 task_base_t *task = obj->tasks[i];
315 task->on_end(task);
316 }
317}
318
319/*
320 * タイマー取得
321 */
322static int main_get_timer(struct main_obj_t *obj)
323{
324 int timer = obj->timer;
325
326 for (int i = 0; i < obj->task_count; i++) {
327 task_base_t *task = obj->tasks[i];
328 int timer2 = task->get_timer(task);
329 if ((timer == -1) || ((timer2 != -1) && (timer > timer2)))
330 timer = timer2;
331 }
332
333 return timer;
334}
335
336/*
337 * 時間経過
338 */
339static void main_progress(struct main_obj_t *obj, int elapse)
340{
341 if (obj->timer != TMO_FEVR) {
342 obj->timer -= elapse;
343 if (obj->timer < 0) {
344 obj->timer = 0;
345 }
346 }
347
348 for (int i = 0; i < obj->task_count; i++) {
349 task_base_t *task = obj->tasks[i];
350 task->progress(task, elapse);
351 }
352}
353
354/*
355 * タイムアウト処理
356 */
357static void main_timeout(struct main_obj_t *obj, bool_t wakeup)
358{
359 ER ret;
360 uint32_t event = wakeup ? MAIN_EVENT_WAKEUP : 0;
361
362 if (!wakeup && (obj->timer != 0))
363 return;
364
365 switch (obj->state) {
366 case main_state_start:
367#ifndef NTSHELL_NO_SOCKET
368 ether_set_link_callback(netif_link_callback);
369#endif
370 {
371 FILINFO fno;
372#if FF_USE_LFN
373 char lfn[FF_MAX_LFN + 1];
374 fno.lfname = lfn;
375 fno.lfsize = FF_MAX_LFN + 1;
376#endif
377 if (f_stat("1:/upload/main.mrb", &fno) != FR_OK) {
378 obj->exec = false;
379 }
380
381 if (obj->exec) {
382 cmd_execute("mruby -b 1:/upload/main.mrb", obj);
383 }
384 }
385 obj->state = main_state_idle;
386 obj->timer = TMO_FEVR;
387 break;
388#ifndef NTSHELL_NO_SOCKET
389 case main_state_start_dhcp:
390 ret = dhcp4c_renew_info();
391 if (ret == E_OK) {
392 obj->state = main_state_idle;
393 obj->timer = TMO_FEVR;
394 }
395 else {
396 obj->state = main_state_start_dhcp;
397 obj->timer = 1000000;
398 }
399 break;
400#endif
401 default:
402 obj->state = main_state_idle;
403 obj->timer = TMO_FEVR;
404 break;
405 }
406#ifndef NTSHELL_NO_SOCKET
407 if (obj->link) {
408 obj->link = 0;
409 event |= MAIN_EVENT_NETIF_CHANGED;
410 if (obj->link_up)
411 event |= MAIN_EVENT_LINK_UP;
412 if (obj->up)
413 event |= MAIN_EVENT_UP;
414
415 if (obj->link_up && obj->up)
416 ntp_cli_execute();
417
418 main_change_netif_link(obj->link_up, obj->up);
419 }
420 if (obj->ntp) {
421 obj->ntp = 0;
422 if (obj->ntp_state != NTP_CLI_STATE_SYNC)
423 event |= MAIN_EVENT_NTP_ASYNC;
424 else
425 event |= MAIN_EVENT_NTP_SYNC;
426 }
427#endif
428 for (int i = 0; i < obj->task_count; i++) {
429 task_base_t *task = obj->tasks[i];
430 task->process(task, event);
431 }
432}
433
434#ifndef NTSHELL_NO_SOCKET
435/* MACアドレスの設定時に呼ばれる */
436void mbed_mac_address(char *mac)
437{
438 memcpy(mac, mac_addr, 6);
439}
440
441void main_change_netif_link(uint8_t link_up, uint8_t up)
442{
443 FLGPTN flgptn;
444 T_RTSK rtsk;
445 ER ret;
446
447 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
448 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
449 return;
450
451 FD_SET(0, (fd_set *)&flgptn);
452
453 set_flg(FLG_SELECT_WAIT, flgptn);
454}
455
456void netif_link_callback(T_IFNET *ether)
457{
458 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
459 uint8_t link_up = (ether->flags & IF_FLAG_LINK_UP) != 0;
460 uint8_t up = (ether->flags & IF_FLAG_UP) != 0;
461 bool_t wake = false;
462
463 if (dhcp_enable) {
464 if (!link_up)
465 dhcp4c_rel_info();
466 else if (!up) {
467 wake = dhcp4c_renew_info() != E_OK;
468 if (wake) {
469 obj->dhcp = 1;
470 }
471 }
472 }
473 else {
474 up = link_up;
475 }
476
477 if ((obj->link_up != link_up) || (obj->up != up)) {
478 obj->link = 1;
479 wake = true;
480 }
481
482 obj->link_up = link_up;
483 obj->up = up;
484
485 if (wake && (obj->event_req == obj->event_res)) {
486 obj->event_req++;
487 rel_wai(MAIN_TASK);
488 }
489}
490
491void ntp_cli_state_changed(ntp_cli_state_t state)
492{
493 struct main_obj_t *obj = (struct main_obj_t *)&main_obj;
494 bool_t wake = obj->ntp_state != state;
495
496 if (wake) {
497 obj->ntp_state = state;
498 obj->ntp = 1;
499
500 if (obj->event_req == obj->event_res) {
501 obj->event_req++;
502 rel_wai(MAIN_TASK);
503 }
504 }
505}
506#endif
507
508/*
509 * shellcmdタスク
510 */
511void shellcmd_task(intptr_t exinf)
512{
513 shellcmd_state = 1;
514
515 if (setjmp(shellcmd_exit) == 0) {
516 shellcmd_exit_code = ntopt_parse(command, usrcmd_ntopt_callback, NULL);
517 }
518
519 //fflush(stdout);
520 clean_fd();
521
522 shellcmd_state = 2;
523}
524
525static const cmd_table_t cmdlist[] = {
526 {"cd", "change directory", usrcmd_cd },
527 {"ls", "list files", usrcmd_ls },
528 {"cp", "copy file", usrcmd_cp },
529 {"rm", "remove file", usrcmd_rm },
530 {"mv", "move file", usrcmd_mv },
531 {"mkdir", "Make directory", usrcmd_mkdir},
532 {"hexdump", "Hex dump", usrcmd_hexdump},
533 {"date", "print date and time", usrcmd_date},
534#ifndef NTSHELL_NO_SOCKET
535 {"ping", "ping", usrcmd_ping},
536 {"dhcpc", "DHCP Client rel/renew/info", usrcmd_dhcp4c},
537 {"dnsc", "DNS client", usrcmd_dnsc },
538 {"ntpc", "NTP client", usrcmd_ntpc },
539#endif
540 {"info", "This is a description text string for info command.", usrcmd_info},
541 {"exit", "Exit Natural Tiny Shell", usrcmd_exit},
542};
543cmd_table_info_t cmd_table_info = { cmdlist, sizeof(cmdlist) / sizeof(cmdlist[0]) };
544
545static int usrcmd_ntopt_callback(long *args, void *extobj)
546{
547 const cmd_table_t *p = cmd_table_info.table;
548 int result = 0;
549 int found = 0;
550
551 if (*args == 0)
552 return result;
553
554 if (ntlibc_strcmp((const char *)args[1], "help") == 0) {
555 found = 1;
556 result = usrcmd_help(args[0], (char **)&args[1]);
557 }
558 else for (int i = 0; i < cmd_table_info.count; i++) {
559 if (ntlibc_strcmp((const char *)args[1], p->cmd) == 0) {
560 found = 1;
561 result = p->func(args[0], (char **)&args[1]);
562 break;
563 }
564 p++;
565 }
566
567 if ((found == 0) && setjmp(shellcmd_exit) == 0) {
568 found = 1;
569 (*((PowerOn_Reset_t *)0x18200000))(args);
570 }
571
572 if ((found == 0) && (((const char *)args[1])[0] != '\0'))
573 ntstdio_printf(ntstdio, "Unknown command found. %s \n", (const char *)args[1]);
574
575 return result;
576}
577
578int usrcmd_help(int argc, char **argv)
579{
580 const cmd_table_t *p = cmd_table_info.table;
581 for (int i = 0; i < cmd_table_info.count; i++) {
582 ntstdio_puts(ntstdio, p->cmd);
583 ntstdio_puts(ntstdio, "\t:");
584 ntstdio_puts(ntstdio, p->desc);
585 ntstdio_puts(ntstdio, "\n");
586 p++;
587 }
588 return 0;
589}
590
591void shellif_into()
592{
593 /* メインタスクの優先度より高くする */
594 chg_pri(SHELLCMD_PRIORITY, MAIN_PRIORITY + 1);
595}
596
597void shellif_outof()
598{
599 /* shellcmdタスクの優先度に戻す */
600 chg_pri(SHELLCMD_PRIORITY, SHELLCMD_PRIORITY);
601}
602
603void shell_abort()
604{
605 shellcmd_exit_code = -1;
606 longjmp(shellcmd_exit, 1);
607}
608
609void shell_exit(int exitcd)
610{
611 shellcmd_exit_code = exitcd;
612 longjmp(shellcmd_exit, 1);
613}
614
615void shell_exit_group(int exitcd)
616{
617 shellcmd_exit_code = exitcd;
618 longjmp(shellcmd_exit, 1);
619}
620
621int execute_command(struct main_obj_t *obj, int wait)
622{
623 T_RTSK rtsk;
624 ER ret;
625
626 ret = ter_tsk(SHELLCMD_TASK);
627 if ((ret != E_OK) && (ret != E_OBJ)) {
628 syslog(LOG_ERROR, "ter_tsk => %d", ret);
629 }
630
631 if (ret == E_OK)
632 tslp_tsk(100000);
633
634 clean_fd();
635
636 shellcmd_state = 0;
637 ret = act_tsk(SHELLCMD_TASK);
638 if (ret != E_OK) {
639 syslog(LOG_ERROR, "act_tsk => %d", ret);
640 }
641
642 if (wait == 0)
643 return 0;
644
645 do {
646 obj->state = main_state_servey_cmd;
647 obj->timer = 100000;
648
649 char c;
650 if (obj->ntshell.func_read(&c, sizeof(c), obj->ntshell.extobj) == 1) {
651 // Ctrl+Cが押された場合
652 if (c == 0x03) {
653 // コマンドタスクを終了
654 ret = ter_tsk(SHELLCMD_TASK);
655 if (ret != E_OK) {
656 syslog(LOG_ERROR, "ter_tsk => %d", ret);
657 }
658 shellcmd_exit_code = -1;
659 shellcmd_state = 4;
660 if (ret == E_OK)
661 tslp_tsk(100000);
662 break;
663 }
664
665 stdio_input(c);
666 }
667
668 ret = ref_tsk(SHELLCMD_TASK, &rtsk);
669 if ((ret != E_OK) || (rtsk.tskstat == TTS_DMT))
670 shellcmd_state = 3;
671 } while(shellcmd_state == 1);
672
673 obj->state = main_state_idle;
674 obj->timer = TMO_FEVR;
675
676 clean_fd();
677
678 return shellcmd_exit_code;
679}
680
681int shell_clock_getres(clockid_t clk_id, struct timespec *res)
682{
683 if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
684 return -EINVAL;
685
686 memset(&res->tv_sec, 0xFF, sizeof(res->tv_sec));
687 res->tv_nsec = 0;
688
689 return 0;
690}
691
692int shell_clock_gettime(clockid_t clk_id, struct timespec *tp)
693{
694 SYSTIM now = 0;
695
696 if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
697 return -EINVAL;
698
699 get_tim(&now);
700 tp->tv_sec = now / 1000000;
701 tp->tv_nsec = (now % 1000000) * 1000;
702
703 return 0;
704}
705
706int shell_clock_settime(clockid_t clk_id, const struct timespec *tp)
707{
708 if ((clk_id != CLOCK_REALTIME) && (clk_id != CLOCK_MONOTONIC))
709 return -EINVAL;
710
711 SYSTIM time;
712 ER ret;
713
714 time = (tp->tv_sec * 1000000ll) + (tp->tv_nsec / 1000ll);
715
716 ret = set_tim(time);
717 if (ret != E_OK) {
718 return -EPERM;
719 }
720
721 return 0;
722}
723
724sigset_t g_sigmask;
725
726int shell_sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
727{
728 if (old != NULL)
729 memcpy(old, &g_sigmask, sizeof(sigset_t));
730
731 switch (how) {
732 case SIG_BLOCK:
733 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
734 g_sigmask.__bits[i] |= set->__bits[i];
735 }
736 break;
737 case SIG_UNBLOCK:
738 for (int i = 0; i < sizeof(g_sigmask.__bits) / sizeof(g_sigmask.__bits[0]); i++) {
739 g_sigmask.__bits[i] &= ~set->__bits[i];
740 }
741 break;
742 case SIG_SETMASK:
743 memcpy(&g_sigmask, set, sizeof(sigset_t));
744 break;
745 default:
746 return -EINVAL;
747 }
748
749 return 0;
750}
751
752// musl-1.1.18\src\internal\ksigaction.h
753struct k_sigaction {
754 void(*handler)(int);
755 unsigned long flags;
756 void(*restorer)(void);
757 unsigned mask[2];
758};
759
760struct k_sigaction sigtable[7];
761
762int shell_sigaction(int sig, const struct k_sigaction *restrict sa,
763 struct k_sigaction *restrict old, size_t size)
764{
765 struct k_sigaction *sat;
766
767 switch(sig){
768 case SIGALRM:
769 sat = &sigtable[0];
770 break;
771 case SIGFPE:
772 sat = &sigtable[1];
773 break;
774 case SIGILL:
775 sat = &sigtable[2];
776 break;
777 case SIGSEGV:
778 sat = &sigtable[3];
779 break;
780 case SIGBUS:
781 sat = &sigtable[4];
782 break;
783 case SIGABRT:
784 sat = &sigtable[5];
785 break;
786 case SIGPIPE:
787 sat = &sigtable[6];
788 break;
789 default:
790 return -EINVAL;
791 }
792
793 if (old != NULL)
794 memcpy(old, sat, offsetof(struct k_sigaction, mask) + size);
795
796 memcpy(sat, sa, offsetof(struct k_sigaction, mask) + size);
797
798 return 0;
799}
800
801int shell_madvise(void *a, size_t b, int c)
802{
803 return 0;
804}
805
806int shell_gettid()
807{
808 ID tskid;
809 ER ret;
810
811 ret = get_tid(&tskid);
812 if (ret != E_OK)
813 return -1;
814
815 return tskid;
816}
817
818int shell_tkill(int tid, int sig)
819{
820 if ((tid == SHELLCMD_TASK) && (sig == SIGABRT)) {
821 shell_abort();
822 }
823
824 no_implement("tkill");
825 return -1;
826}
827
828int shell_kill(int pid, int sig)
829{
830 DebugBreak();
831 return -1;
832}
833
834int shell_gettimeofday(struct timeval *tv, void *tzvp)
835{
836 SYSTIM time;
837 if (!tv) return 0;
838 get_tim(&time);
839 tv->tv_sec = time / 1000000;
840 tv->tv_usec = time - (tv->tv_sec * 1000000);
841 return 0;
842}
843
844int shell_nanosleep(const struct timespec *req, struct timespec *rem)
845{
846 ER ret;
847 TMO tmo;
848 SYSTIM prev, now, diff;
849
850 if ((req == NULL) || (req->tv_nsec < 0) || (req->tv_nsec >= 1000000000))
851 return -EINVAL;
852
853 get_tim(&prev);
854
855 tmo = req->tv_sec * 1000000 + req->tv_nsec / 1000;
856 ret = tslp_tsk(tmo);
857 if (ret == E_OK) {
858 if (rem != NULL) {
859 get_tim(&now);
860 diff = now - prev;
861 rem->tv_sec = diff / 1000000ll;
862 rem->tv_nsec = (diff - (rem->tv_sec * 1000000ll)) * 1000ll;
863 }
864 return 0;
865 }
866 else if (ret == E_TMOUT) {
867 if (rem != NULL) {
868 rem->tv_sec = 0;
869 rem->tv_nsec = 0;
870 }
871 return 0;
872 }
873
874 return -EFAULT;
875}
876
877ssize_t shell_getrandom(void *buf, size_t buflen, unsigned int flags)
878{
879 SYSTIM now;
880 int32_t i;
881 int *output = (int *)buf;
882 size_t sz = buflen / 4;
883
884 get_tim(&now);
885 srand(now);
886
887 for (i = 0; i < sz; i++)
888 output[i] = rand();
889
890 for (i = 4 * sz; i < buflen; i++)
891 ((char *)buf)[i] = rand();
892
893 return buflen;
894}
895
896extern uint32_t __CmdBase;
897extern uint32_t __CmdLimit;
898
899void *shell_brk(void *addr)
900{
901 if (addr == 0) {
902 return (void *)((intptr_t)&__CmdBase + 0x40000);
903 }
904 if ((addr >= (intptr_t)&__CmdBase + 0x40000) && (addr < &__CmdLimit)) {
905 return addr;
906 }
907 return (void *)-1;
908}
909
910void *shell_mmap2(void *start, size_t length, int prot, int flags, int fd, off_t pgoffset)
911{
912 if (fd != -1)
913 return -EINVAL;
914
915 if ((length >= 0) && (length <= (intptr_t)&__CmdLimit - ((intptr_t)&__CmdBase + 0x40000))) {
916 return &__CmdBase + 0x40000;
917 }
918 return (void *)-1;
919}
920
921int shell_mprotect(void *addr, size_t len, int prot)
922{
923 //if ((addr >= (intptr_t)&__CmdBase + 0x40000) && ((intptr_t)addr + len < &__CmdLimit)) {
924 return 0;
925 //}
926 //return -1;
927}
Note: See TracBrowser for help on using the repository browser.