source: azure_iot_hub/trunk/ntshell/src/stdio_stub.c@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 15.9 KB
Line 
1/*
2 * TOPPERS ECHONET Lite Communication Middleware
3 *
4 * Copyright (C) 2017-2019 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者
7は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
8 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9 * 変・再é…
10å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再é…
16å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
17å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
18 * 者
19マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
24 * と.
25 * (a) 再é…
26å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
27マニュアルなど)に,上記の著
28 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
29 * (b) 再é…
30å¸ƒã®å½¢æ…
31‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
32 * 報告すること.
33 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34 * 害からも,上記著作権者
35およびTOPPERSプロジェクトをå…
36è²¬ã™ã‚‹ã“と.
37 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
38 * 由に基づく請求からも,上記著作権者
39およびTOPPERSプロジェクトを
40 * å…
41è²¬ã™ã‚‹ã“と.
42 *
43 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
44お
45 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
46 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
47 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
48 * の責任を負わない.
49 *
50 * @(#) $Id: stdio_stub.c 388 2019-05-22 11:25:18Z coas-nagasima $
51 */
52#include "shellif.h"
53#include <stdint.h>
54#include <kernel.h>
55#include <t_syslog.h>
56#include <t_stdlib.h>
57#include <sil.h>
58#include "syssvc/serial.h"
59#include "syssvc/syslog.h"
60#include "target_syssvc.h"
61#include "target_serial.h"
62#include "fdtable.h"
63#include "kernel_cfg.h"
64#include <string.h>
65#include <errno.h>
66#include "util/ntstdio.h"
67#include "hal/serial_api.h"
68#include "target_rename.h"
69#include "target_kernel_impl.h"
70#include "syssvc/siofd.h"
71
72#ifdef _DEBUG
73static const char THIS_FILE[] = __FILE__;
74#endif
75
76static unsigned char stdio_xi(struct ntstdio_t *handle);
77static void stdio_xo(struct ntstdio_t *handle, unsigned char c);
78static void stdio_serial_irq_handler(uint32_t id, SerialIrq event);
79
80static int stdio_close(struct SHELL_FILE *fp);
81static size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
82static size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
83static void stdio_delete(struct SHELL_FILE *fp);
84
85static unsigned char sio_xi(struct ntstdio_t *handle);
86static void sio_xo(struct ntstdio_t *handle, unsigned char c);
87static void sio_serial_irq_handler(uint32_t id, SerialIrq event);
88
89static int sio_close(struct SHELL_FILE *fp);
90static size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len);
91static size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len);
92static off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org);
93static int sio_ioctl(struct SHELL_FILE *fp, int req, void *arg);
94static bool_t sio_readable(struct SHELL_FILE *fp);
95static bool_t sio_writable(struct SHELL_FILE *fp);
96static void sio_delete(struct SHELL_FILE *fp);
97
98IO_TYPE IO_TYPE_STDIN = { stdio_close, sio_read, stdio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
99IO_TYPE IO_TYPE_STDOUT = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
100IO_TYPE IO_TYPE_STDERR = { stdio_close, stdio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, stdio_delete };
101IO_TYPE IO_TYPE_SIO = { sio_close, sio_read, sio_write, sio_seek, sio_ioctl, sio_readable, sio_writable, sio_delete };
102
103#define STDIO_UART_BUF_SZ 256
104
105typedef struct stdio_sio_t {
106 serial_t serial;
107 ntstdio_t ntstdio;
108 struct SHELL_FILE *fp;
109 unsigned char tx_buf[STDIO_UART_BUF_SZ];
110 int tx_pos_w;
111 int tx_pos_r;
112 unsigned char rx_buf[STDIO_UART_BUF_SZ];
113 int rx_pos_w;
114 int rx_pos_r;
115} stdio_sio_t;
116
117stdio_sio_t stdio_sio;
118
119void sys_init(intptr_t exinf)
120{
121 serial_t *serial = &stdio_sio.serial;
122 ntstdio_t *ntstdio = &stdio_sio.ntstdio;
123
124 serial_init(serial, STDIO_UART_TX, STDIO_UART_RX);
125 serial_baud(serial, UART_BAUDRATE);
126 serial_format(serial, 8, ParityNone, 1);
127
128 ntstdio_init(ntstdio, NTSTDIO_OPTION_LINE_ECHO | NTSTDIO_OPTION_CANON | NTSTDIO_OPTION_LF_CRLF | NTSTDIO_OPTION_LF_CR, stdio_xi, stdio_xo);
129 ntstdio->exinf = (void *)&stdio_sio;
130
131 struct SHELL_FILE *fp;
132
133 fp = fd_to_fp(STDIN_FILENO);
134 fp->handle = SIO_PORTID;
135 fp->exinf = (void *)ntstdio;
136
137 fp = fd_to_fp(STDOUT_FILENO);
138 fp->handle = SIO_PORTID;
139 fp->exinf = (void *)ntstdio;
140
141 fp = fd_to_fp(STDERR_FILENO);
142 fp->handle = SIO_PORTID;
143 fp->exinf = (void *)ntstdio;
144
145 serial_irq_handler(&stdio_sio.serial, stdio_serial_irq_handler, 0);
146
147 serial_irq_set(serial, RxIrq, true);
148}
149
150ID serial_portid;
151
152void stdio_open(ID portid)
153{
154 struct SHELL_FILE *fp;
155
156 serial_portid = portid;
157 serial_ctl_por(portid, IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
158
159 fp = fd_to_fp(STDIN_FILENO);
160 fp->handle = portid;
161
162 fp = fd_to_fp(STDOUT_FILENO);
163 fp->handle = portid;
164
165 fp = fd_to_fp(STDERR_FILENO);
166 fp->handle = portid;
167}
168
169int stdio_close(struct SHELL_FILE *fp)
170{
171 return -EPERM;
172}
173
174size_t stdio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
175{
176 return -EPERM;
177}
178
179size_t stdio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
180{
181 return -EPERM;
182}
183
184void stdio_delete(struct SHELL_FILE *fp)
185{
186}
187
188int sio_close(struct SHELL_FILE *fp)
189{
190 return -EPERM;
191}
192
193size_t sio_read(struct SHELL_FILE *fp, unsigned char *data, size_t len)
194{
195 int i = 0;
196 while (i < len) {
197 int c = ntstdio_getc((struct ntstdio_t *)fp->exinf);
198 data[i++] = c;
199 if ((c == EOF) || (c == '\n'))
200 break;
201 }
202 return i;
203}
204
205size_t sio_write(struct SHELL_FILE *fp, const unsigned char *data, size_t len)
206{
207 for (int i = 0; i < len; i++) {
208 ntstdio_putc((struct ntstdio_t *)fp->exinf, data[i]);
209 }
210 return len;
211}
212
213off_t sio_seek(struct SHELL_FILE *fp, off_t ofs, int org)
214{
215 return -EPERM;
216}
217
218int sio_tcgetattr(struct SHELL_FILE *fp, struct termios *termios)
219{
220 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
221
222 memset(termios, 0, sizeof(*termios));
223
224 if (ntstdio->option & NTSTDIO_OPTION_LINE_ECHO) {
225 termios->c_lflag |= ECHO;
226 }
227 else {
228 termios->c_lflag &= ~ECHO;
229 }
230 if (ntstdio->option & NTSTDIO_OPTION_CANON) {
231 termios->c_lflag |= ICANON;
232 }
233 else {
234 termios->c_lflag &= ~ICANON;
235 }
236 if (ntstdio->option & NTSTDIO_OPTION_LF_CR) {
237 termios->c_iflag |= INLCR;
238 }
239 else {
240 termios->c_iflag &= ~INLCR;
241 }
242 if (ntstdio->option & NTSTDIO_OPTION_LF_CRLF) {
243 termios->c_oflag |= ONLCR;
244 }
245 else {
246 termios->c_oflag &= ~ONLCR;
247 }
248
249 return 0;
250}
251
252int sio_tcsetattr(struct SHELL_FILE *fp, int optional_actions, const struct termios *termios)
253{
254 ntstdio_t *ntstdio = (ntstdio_t *)fp->exinf;
255
256 if (optional_actions == TCSANOW) {
257 if (termios->c_lflag & ECHO) {
258 ntstdio->option |= NTSTDIO_OPTION_LINE_ECHO;
259 }
260 else {
261 ntstdio->option &= ~NTSTDIO_OPTION_LINE_ECHO;
262 }
263 if (termios->c_lflag & ICANON) {
264 ntstdio->option |= NTSTDIO_OPTION_CANON;
265 }
266 else {
267 ntstdio->option &= ~NTSTDIO_OPTION_CANON;
268 }
269 if (termios->c_iflag & INLCR) {
270 ntstdio->option |= NTSTDIO_OPTION_LF_CR;
271 }
272 else {
273 ntstdio->option &= ~NTSTDIO_OPTION_LF_CR;
274 }
275 if (termios->c_oflag & ONLCR) {
276 ntstdio->option |= NTSTDIO_OPTION_LF_CRLF;
277 }
278 else {
279 ntstdio->option &= ~NTSTDIO_OPTION_LF_CRLF;
280 }
281 return 0;
282 }
283
284 //shell_abort();
285 return 0;
286}
287
288int sio_ioctl(struct SHELL_FILE *fp, int request, void *arg)
289{
290 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
291 return -EBADF;
292
293 switch (request) {
294 case TIOCGWINSZ:
295 return 0;
296 case TCGETS:
297 return sio_tcgetattr(fp, (struct termios *)arg);
298 case TCSETS + TCSANOW:
299 case TCSETS + TCSADRAIN:
300 case TCSETS + TCSAFLUSH:
301 return sio_tcsetattr(fp, request - TCSETS, (const struct termios *)arg);
302 }
303
304 return -EINVAL;
305}
306
307bool_t sio_readable(struct SHELL_FILE *fp)
308{
309 return fp->readevt_w != fp->readevt_r;
310}
311
312bool_t sio_writable(struct SHELL_FILE *fp)
313{
314 return fp->writable && (fp->writeevt_w == fp->writeevt_r);
315}
316
317void sio_delete(struct SHELL_FILE *fp)
318{
319 free((stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf);
320 ((struct ntstdio_t *)fp->exinf)->exinf = NULL;
321 free((struct ntstdio_t *)fp->exinf);
322 fp->exinf = NULL;
323}
324
325static unsigned char ntstdio_xi(struct ntstdio_t *handle, struct SHELL_FILE *fp)
326{
327 stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
328 ER ret;
329 unsigned char c;
330
331 bool_t lock = sense_lock();
332 if (lock)
333 unl_cpu();
334
335 while (uart->rx_pos_w == uart->rx_pos_r) {
336 FLGPTN flgptn = 0, waitptn = 0;
337 FD_SET(fp->fd, (fd_set *)&waitptn);
338
339 ret = wai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn);
340 if (ret != E_OK) {
341 if (lock)
342 loc_cpu();
343 syslog(LOG_ERROR, "wai_flg => %d", ret);
344 return 0;
345 }
346
347 ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
348 if (ret != E_OK) {
349 syslog(LOG_ERROR, "clr_flg => %d", ret);
350 }
351 }
352
353 if (lock)
354 unl_cpu();
355
356 if (fp->readevt_w != fp->readevt_r) fp->readevt_r++;
357
358 c = uart->rx_buf[uart->rx_pos_r++];
359 if (uart->rx_pos_r >= sizeof(uart->rx_buf))
360 uart->rx_pos_r = 0;
361
362 return c;
363}
364
365extern volatile int ntshell_state;
366extern ID serial_portid;
367
368static void serial_rx_irq_handler(int fd)
369{
370 struct SHELL_FILE *fp = fd_to_fp(fd);
371 stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
372 serial_t *serial = (serial_t *)&uart->serial;
373
374 if (serial_readable(serial)) {
375 unsigned char c = (unsigned char)serial_getc(serial);
376
377 if (ntshell_state == 1) {
378 ER ret;
379 FLGPTN flgptn = 0;
380
381 uart->rx_buf[uart->rx_pos_w++] = c;
382 if (uart->rx_pos_w >= sizeof(uart->rx_buf))
383 uart->rx_pos_w = 0;
384
385 if (fp->readevt_w == fp->readevt_r) fp->readevt_w++;
386
387 FD_SET(fd, (fd_set *)&flgptn);
388
389 ret = set_flg(FLG_SELECT_WAIT, flgptn);
390 if (ret != E_OK) {
391 syslog(LOG_ERROR, "set_flg => %d", ret);
392 }
393 }
394 else
395 sio_isr_rcv(fp->handle, c);
396 }
397}
398
399static void ntstdio_xo(struct ntstdio_t *handle, struct SHELL_FILE *fp, unsigned char c)
400{
401 stdio_sio_t *uart = (stdio_sio_t *)handle->exinf;
402 serial_t *serial = (serial_t *)&uart->serial;
403 ER ret;
404
405 // タスクコンテキストでない場合
406 if (sense_context()) {
407 // 送信可能になるまで待
408ち
409 while (!serial_writable(serial));
410 // 送信する
411 serial_putc(serial, c);
412 return;
413 }
414
415 // 送信バッファが空で
416 if (uart->tx_pos_w == uart->tx_pos_r) {
417 // 送信可能なら
418 if (serial_writable(serial)) {
419 // 送信する
420 serial_putc(serial, c);
421 return;
422 }
423 }
424
425 // 送信バッファに追加する
426 uart->tx_buf[uart->tx_pos_w++] = c;
427 if (uart->tx_pos_w >= sizeof(uart->tx_buf))
428 uart->tx_pos_w = 0;
429
430 // 送信可能になったら割り込みをもらうよう設定
431 serial_irq_set(serial, TxIrq, true);
432
433 bool_t lock = sense_lock();
434 if (lock)
435 unl_cpu();
436
437 do {
438 FLGPTN flgptn = 0, waitptn = 0;
439 FD_SET(fp->fd, (fd_set *)&waitptn);
440
441 ret = wai_flg(FLG_SELECT_WAIT, waitptn, TWF_ORW, &flgptn);
442 if (ret != E_OK) {
443 syslog(LOG_ERROR, "wai_flg => %d", ret);
444 break;
445 }
446
447 ret = clr_flg(FLG_SELECT_WAIT, ~(flgptn & waitptn));
448 if (ret != E_OK) {
449 syslog(LOG_ERROR, "clr_flg => %d", ret);
450 }
451 } while (fp->writeevt_w == fp->writeevt_r);
452
453 fp->writeevt_r++;
454
455 if (lock)
456 loc_cpu();
457}
458
459static void serial_tx_irq_handler(int fd)
460{
461 struct SHELL_FILE *fp = fd_to_fp(fd);
462 stdio_sio_t *uart = (stdio_sio_t *)((struct ntstdio_t *)fp->exinf)->exinf;
463 serial_t *serial = (serial_t *)&uart->serial;
464 ER ret;
465 unsigned char c;
466
467 if (fp->writeevt_w == fp->writeevt_r) fp->writeevt_w++;
468
469 FLGPTN flgptn = 0;
470 FD_SET(fd, (fd_set *)&flgptn);
471
472 ret = set_flg(FLG_SELECT_WAIT, flgptn);
473 if (ret != E_OK) {
474 syslog(LOG_ERROR, "set_flg => %d", ret);
475 }
476
477 // 送信バッファが空なら
478 if (uart->tx_pos_w == uart->tx_pos_r) {
479 // SIOドライバの送信
480 sio_isr_snd(fp->handle);
481 // やっぱり送信バッファが空なら
482 if (uart->tx_pos_w == uart->tx_pos_r) {
483 // 送信割り込み停止
484 serial_irq_set(serial, TxIrq, false);
485 return;
486 }
487 }
488
489 c = uart->tx_buf[uart->tx_pos_r++];
490 if (uart->tx_pos_r >= sizeof(uart->tx_buf))
491 uart->tx_pos_r = 0;
492
493 // 送信する
494 serial_putc(serial, c);
495}
496
497void stdio_serial_irq_handler(uint32_t id, SerialIrq event)
498{
499 switch (event) {
500 case RxIrq:
501 serial_rx_irq_handler(STDIN_FILENO);
502 break;
503 case TxIrq:
504 serial_tx_irq_handler(STDOUT_FILENO);
505 break;
506 }
507}
508
509void sio_serial_irq_handler(uint32_t id, SerialIrq event)
510{
511 struct SHELL_FILE *fp = fd_to_fp(id);
512 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO))
513 return;
514
515 switch (event) {
516 case RxIrq:
517 serial_rx_irq_handler(id);
518 break;
519 case TxIrq:
520 serial_tx_irq_handler(id);
521 break;
522 }
523}
524
525unsigned char stdio_xi(struct ntstdio_t *handle)
526{
527 return ntstdio_xi(handle, fd_to_fp(STDIN_FILENO));
528}
529
530void stdio_xo(struct ntstdio_t *handle, unsigned char c)
531{
532 ntstdio_xo(handle, fd_to_fp(STDOUT_FILENO), c);
533}
534
535unsigned char sio_xi(struct ntstdio_t *handle)
536{
537 return ntstdio_xi(handle, ((stdio_sio_t *)handle->exinf)->fp);
538}
539
540void sio_xo(struct ntstdio_t *handle, unsigned char c)
541{
542 ntstdio_xo(handle, ((stdio_sio_t *)handle->exinf)->fp, c);
543}
544
545int siofd_open(const char *path, int flags, ...)
546{
547 return -1;
548}
549
550int siofd_close(int fd)
551{
552 struct SHELL_FILE *fp = fd_to_fp(fd);
553 if ((fp == NULL) || (fp->type != &IO_TYPE_SIO)) {
554 errno = EBADF;
555 return -1;
556 }
557
558 errno = sio_close(fp);
559 if (errno != 0)
560 return 1;
561 return 0;
562}
563
564ssize_t siofd_read(int fd, void *data, size_t len)
565{
566 struct SHELL_FILE *fp = fd_to_fp(fd);
567 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_SIO))) {
568 errno = EBADF;
569 return -1;
570 }
571 char *pos, *end;
572
573 for (pos = (char *)data, end = &pos[len]; pos < end; pos++) {
574 *pos = ntstdio_xi((struct ntstdio_t *)fp->exinf, fp);
575 }
576
577 return pos - (char *)data;
578}
579
580ssize_t siofd_write(int fd, const void *data, size_t len)
581{
582 struct SHELL_FILE *fp = fd_to_fp(fd);
583 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDOUT) && (fp->type != &IO_TYPE_STDERR)
584 && (fp->type != &IO_TYPE_SIO))) {
585 errno = EBADF;
586 return -1;
587 }
588 const char *pos, *end;
589
590 for (pos = (const char *)data, end = &pos[len]; pos < end; pos++) {
591 ntstdio_xo((struct ntstdio_t *)fp->exinf, fp, *pos);
592 }
593
594 return pos - (char *)data;
595}
596
597int siofd_tcsetattr(int fd, int act, const struct termios *tio)
598{
599 struct SHELL_FILE *fp = fd_to_fp(fd);
600 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
601 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
602 errno = EBADF;
603 return -1;
604 }
605
606 errno = sio_tcsetattr(fp, act, tio);
607 if (errno != 0)
608 return 1;
609 return 0;
610}
611
612int siofd_tcgetattr(int fd, struct termios *tio)
613{
614 struct SHELL_FILE *fp = fd_to_fp(fd);
615 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
616 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
617 errno = EBADF;
618 return -1;
619 }
620
621 errno = sio_tcgetattr(fp, tio);
622 if (errno != 0)
623 return 1;
624 return 0;
625}
626
627int siofd_fcntl(int fd, int cmd, ...)
628{
629 struct SHELL_FILE *fp = fd_to_fp(fd);
630 if ((fp == NULL) || ((fp->type != &IO_TYPE_STDIN) && (fp->type != &IO_TYPE_STDOUT)
631 && (fp->type != &IO_TYPE_STDERR) && (fp->type != &IO_TYPE_SIO))) {
632 errno = EBADF;
633 return -1;
634 }
635 void *arg;
636 va_list ap;
637 va_start(ap, cmd);
638 arg = va_arg(ap, void *);
639 va_end(ap);
640
641 errno = sio_ioctl(fp, cmd, arg);
642 if (errno != 0)
643 return 1;
644 return 0;
645}
Note: See TracBrowser for help on using the repository browser.