source: syssvc/serial.c @ 7

このファイルの 7 以降における最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 18.6 KB
Rev 
[7]1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      Advanced Standard Profile Kernel
5 *
6 *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 *                              Toyohashi Univ. of Technology, JAPAN
8 *  Copyright (C) 2006-2013 by Embedded and Real-Time Systems Laboratory
9 *              Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
12 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
13 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
14 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
15 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
16 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
17 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
18 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
20 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
21 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
22 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
23 *      €È¡¥
24 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
25 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
26 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
27 *        Êó¹ð€¹€ë€³€È¡¥
28 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
29 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
30 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
31 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
32 *      ÌÈÀÕ€¹€ë€³€È¡¥
33 *
34 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
35 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
36 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
37 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
38 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
39 *
40 *  @(#) $Id$
41 */
42
43/*
44 *              ¥·¥ê¥¢¥ë¥€¥ó¥¿¥Õ¥§¡Œ¥¹¥É¥é¥€¥Ð
45 */
46
47#include <kernel.h>
48#include <t_syslog.h>
49#include "target_syssvc.h"
50#include "target_serial.h"
51#include "serial.h"
52#include "kernel_cfg.h"
53
54/*
55 *  ¥Ð¥Ã¥Õ¥¡¥µ¥€¥º€Î¥Ç¥Õ¥©¥ë¥ÈÃ̀ȥХåե¡€ÎÄêµÁ
56 */
57#ifndef SERIAL_RCV_BUFSZ1
58#define SERIAL_RCV_BUFSZ1       256                     /* ¥Ý¡Œ¥È1€ÎŒõ¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
59#endif /* SERIAL_RCV_BUFSZ1 */
60
61#ifndef SERIAL_SND_BUFSZ1
62#define SERIAL_SND_BUFSZ1       256                     /* ¥Ý¡Œ¥È1€ÎÁ÷¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
63#endif /* SERIAL_SND_BUFSZ1 */
64
65static char     rcv_buffer1[SERIAL_RCV_BUFSZ1];
66static char     snd_buffer1[SERIAL_SND_BUFSZ1];
67
68#if TNUM_PORT >= 2                                              /* ¥Ý¡Œ¥È2€ËŽØ€¹€ëÄêµÁ */
69
70#ifndef SERIAL_RCV_BUFSZ2
71#define SERIAL_RCV_BUFSZ2       256                     /* ¥Ý¡Œ¥È2€ÎŒõ¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
72#endif /* SERIAL_RCV_BUFSZ2 */
73
74#ifndef SERIAL_SND_BUFSZ2
75#define SERIAL_SND_BUFSZ2       256                     /* ¥Ý¡Œ¥È2€ÎÁ÷¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
76#endif /* SERIAL_SND_BUFSZ2 */
77
78static char     rcv_buffer2[SERIAL_RCV_BUFSZ2];
79static char     snd_buffer2[SERIAL_SND_BUFSZ2];
80
81#endif /* TNUM_PORT >= 2 */
82
83#if TNUM_PORT >= 3                                              /* ¥Ý¡Œ¥È3€ËŽØ€¹€ëÄêµÁ */
84
85#ifndef SERIAL_RCV_BUFSZ3
86#define SERIAL_RCV_BUFSZ3       256                     /* ¥Ý¡Œ¥È3€ÎŒõ¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
87#endif /* SERIAL_RCV_BUFSZ3 */
88
89#ifndef SERIAL_SND_BUFSZ3
90#define SERIAL_SND_BUFSZ3       256                     /* ¥Ý¡Œ¥È3€ÎÁ÷¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
91#endif /* SERIAL_SND_BUFSZ3 */
92
93static char     rcv_buffer3[SERIAL_RCV_BUFSZ3];
94static char     snd_buffer3[SERIAL_SND_BUFSZ3];
95
96#endif /* TNUM_PORT >= 3 */
97
98#if TNUM_PORT >= 4                                              /* ¥Ý¡Œ¥È4€ËŽØ€¹€ëÄêµÁ */
99
100#ifndef SERIAL_RCV_BUFSZ4
101#define SERIAL_RCV_BUFSZ4       256                     /* ¥Ý¡Œ¥È4€ÎŒõ¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
102#endif /* SERIAL_RCV_BUFSZ4 */
103
104#ifndef SERIAL_SND_BUFSZ4
105#define SERIAL_SND_BUFSZ4       256                     /* ¥Ý¡Œ¥È4€ÎÁ÷¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
106#endif /* SERIAL_SND_BUFSZ4 */
107
108static char     rcv_buffer4[SERIAL_RCV_BUFSZ4];
109static char     snd_buffer4[SERIAL_SND_BUFSZ4];
110
111#endif /* TNUM_PORT >= 4 */
112
113#if TNUM_PORT >= 5
114#error Serial interface driver supports up to 4 ports.
115#endif /* TNUM_PORT >= 5 */
116
117/*
118 *  ¥Õ¥í¡ŒÀ©žæ€ËŽØÏ¢€¹€ëÄê¿ô€È¥Þ¥¯¥í
119 */
120#define FC_STOP                 '\023'          /* ¥³¥ó¥È¥í¡Œ¥ë-S */
121#define FC_START                '\021'          /* ¥³¥ó¥È¥í¡Œ¥ë-Q */
122
123#define BUFCNT_STOP(bufsz)              ((bufsz) * 3 / 4)       /* STOP€òÁ÷€ëŽðœàÊž»ú¿ô */
124#define BUFCNT_START(bufsz)             ((bufsz) / 2)           /* START€òÁ÷€ëŽðœàÊž»ú¿ô */
125
126/*
127 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈœéŽü²œ¥Ö¥í¥Ã¥¯
128 */
129typedef struct serial_port_initialization_block {
130        ID              rcv_semid;              /* Œõ¿®¥Ð¥Ã¥Õ¥¡ŽÉÍýÍÑ¥»¥Þ¥Õ¥©€ÎID */
131        ID              snd_semid;              /* Á÷¿®¥Ð¥Ã¥Õ¥¡ŽÉÍýÍÑ¥»¥Þ¥Õ¥©€ÎID */
132        uint_t  rcv_bufsz;              /* Œõ¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
133        char    *rcv_buffer;    /* Œõ¿®¥Ð¥Ã¥Õ¥¡ */
134        uint_t  snd_bufsz;              /* Á÷¿®¥Ð¥Ã¥Õ¥¡¥µ¥€¥º */
135        char    *snd_buffer;    /* Á÷¿®¥Ð¥Ã¥Õ¥¡ */
136} SPINIB;
137
138static const SPINIB spinib_table[TNUM_PORT] = {
139        { SERIAL_RCV_SEM1, SERIAL_SND_SEM1,
140          SERIAL_RCV_BUFSZ1, rcv_buffer1,
141          SERIAL_SND_BUFSZ1, snd_buffer1 },
142#if TNUM_PORT >= 2
143        { SERIAL_RCV_SEM2, SERIAL_SND_SEM2,
144          SERIAL_RCV_BUFSZ2, rcv_buffer2,
145          SERIAL_SND_BUFSZ2, snd_buffer2 },
146#endif /* TNUM_PORT >= 2 */
147#if TNUM_PORT >= 3
148        { SERIAL_RCV_SEM3, SERIAL_SND_SEM3,
149          SERIAL_RCV_BUFSZ3, rcv_buffer3,
150          SERIAL_SND_BUFSZ3, snd_buffer3 },
151#endif /* TNUM_PORT >= 3 */
152#if TNUM_PORT >= 4
153        { SERIAL_RCV_SEM4, SERIAL_SND_SEM4,
154          SERIAL_RCV_BUFSZ4, rcv_buffer4,
155          SERIAL_SND_BUFSZ4, snd_buffer4 },
156#endif /* TNUM_PORT >= 4 */
157};
158
159/*
160 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈŽÉÍý¥Ö¥í¥Ã¥¯
161 */
162typedef struct serial_port_control_block {
163        const SPINIB *p_spinib;         /* ¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈœéŽü²œ¥Ö¥í¥Ã¥¯ */
164        SIOPCB  *p_siopcb;                      /* ¥·¥ê¥¢¥ëI/O¥Ý¡Œ¥ÈŽÉÍý¥Ö¥í¥Ã¥¯ */
165        bool_t  openflag;                       /* ¥ª¡Œ¥×¥óºÑ€ß¥Õ¥é¥° */
166        bool_t  errorflag;                      /* ¥š¥é¡Œ¥Õ¥é¥° */
167        uint_t  ioctl;                          /* ưºîÀ©žæ€ÎÀßÄêÃÍ */
168
169        uint_t  rcv_read_ptr;           /* Œõ¿®¥Ð¥Ã¥Õ¥¡ÆÉœÐ€·¥Ý¥€¥ó¥¿ */
170        uint_t  rcv_write_ptr;          /* Œõ¿®¥Ð¥Ã¥Õ¥¡œñ¹þ€ß¥Ý¥€¥ó¥¿ */
171        uint_t  rcv_count;                      /* Œõ¿®¥Ð¥Ã¥Õ¥¡Ãæ€ÎÊž»ú¿ô */
172        char    rcv_fc_chr;                     /* Á÷€ë€Ù€­START/STOP */
173        bool_t  rcv_stopped;            /* STOP€òÁ÷€Ã€¿ŸõÂÖ€«¡© */
174
175        uint_t  snd_read_ptr;           /* Á÷¿®¥Ð¥Ã¥Õ¥¡ÆÉœÐ€·¥Ý¥€¥ó¥¿ */
176        uint_t  snd_write_ptr;          /* Á÷¿®¥Ð¥Ã¥Õ¥¡œñ¹þ€ß¥Ý¥€¥ó¥¿ */
177        uint_t  snd_count;                      /* Á÷¿®¥Ð¥Ã¥Õ¥¡Ãæ€ÎÊž»ú¿ô */
178        bool_t  snd_stopped;            /* STOP€òŒõ€±Œè€Ã€¿ŸõÂÖ€«¡© */
179} SPCB;
180
181static SPCB     spcb_table[TNUM_PORT];
182
183/*
184 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈID€«€é¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯¥í
185 */
186#define INDEX_PORT(portid)      ((uint_t)((portid) - 1))
187#define get_spcb(portid)        (&(spcb_table[INDEX_PORT(portid)]))
188
189/*
190 *  ¥Ý¥€¥ó¥¿€Î¥€¥ó¥¯¥ê¥á¥ó¥È
191 */
192#define INC_PTR(ptr, bufsz) do {        \
193        if (++(ptr) == (bufsz)) {               \
194                (ptr) = 0;                                      \
195         }                                                              \
196} while (false)
197
198/*
199 *  ¥µ¡Œ¥Ó¥¹¥³¡Œ¥ëžÆœÐ€·¥Þ¥¯¥í
200 *
201 *  ¥µ¡Œ¥Ó¥¹¥³¡Œ¥ëžÆœÐ€·€òŽÞ€àŒ°exp€òÉŸ²Á€·¡€ÊÖÃÍ€¬¥š¥é¡Œ¡ÊÉé€ÎÃ͡ˀΟì
202 *  ¹ç€Ë€Ï¡€erc€Ëercd_exp€òÉŸ²Á€·€¿ÃÍ€òÂåÆþ€·¡€error_exit€Ëgoto€¹€ë¡¥
203 */
204#define SVC(exp, ercd_exp) do {         \
205        if ((exp) < 0) {                                \
206                ercd = (ercd_exp);                      \
207                goto error_exit;                        \
208        }                                                               \
209} while (false)
210
211/*
212 *  E_SYS¥š¥é¡Œ€ÎÀžÀ®
213 */
214static ER
215gen_ercd_sys(SPCB *p_spcb)
216{
217        p_spcb->errorflag = true;
218        return(E_SYS);
219}
220
221/*
222 *  ÂÔ€Á€ËÆþ€ë¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë€«€é€Î¥š¥é¡Œ€ÎÊÑŽ¹
223 */
224static ER
225gen_ercd_wait(ER rercd, SPCB *p_spcb)
226{
227        switch (MERCD(rercd)) {
228        case E_RLWAI:
229        case E_DLT:
230                return(rercd);
231        default:
232                p_spcb->errorflag = true;
233                return(E_SYS);
234        }
235}
236
237/*
238 *  ¥·¥ê¥¢¥ë¥€¥ó¥¿¥Õ¥§¡Œ¥¹¥É¥é¥€¥Ð€ÎœéŽü²œ¥ë¡Œ¥Á¥ó
239 */
240void
241serial_initialize(intptr_t exinf)
242{
243        uint_t  i;
244        SPCB    *p_spcb;
245
246        for (i = 0; i < TNUM_PORT; i++) {
247                p_spcb = &(spcb_table[i]);
248                p_spcb->p_spinib = &(spinib_table[i]);
249                p_spcb->openflag = false;
250        }
251}
252
253/*
254 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€Î¥ª¡Œ¥×¥ó¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
255 */
256ER
257serial_opn_por(ID portid)
258{
259        SPCB    *p_spcb;
260        ER              ercd;
261
262        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
263                return(E_CTX);
264        }
265        if (!(1 <= portid && portid <= TNUM_PORT)) {
266                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
267        }
268        p_spcb = get_spcb(portid);
269
270        SVC(dis_dsp(), gen_ercd_sys(p_spcb));
271        if (p_spcb->openflag) {                 /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
272                ercd = E_OBJ;
273        }
274        else {
275                /*
276                 *  ÊÑ¿ô€ÎœéŽü²œ
277                 */
278                p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
279
280                p_spcb->rcv_read_ptr = 0U;
281                p_spcb->rcv_write_ptr = 0U;
282                p_spcb->rcv_count = 0U;
283                p_spcb->rcv_fc_chr = '\0';
284                p_spcb->rcv_stopped = false;
285
286                p_spcb->snd_read_ptr = 0U;
287                p_spcb->snd_write_ptr = 0U;
288                p_spcb->snd_count = 0U;
289                p_spcb->snd_stopped = false;
290
291                /*
292                 *  €³€ì°Ê¹ß¡€³ä¹þ€ß€ò¶Ø»ß€¹€ë¡¥
293                 */
294                if (loc_cpu() < 0) {
295                        ercd = E_SYS;
296                        goto error_exit_enadsp;
297                }
298
299                /*
300                 *  ¥Ï¡Œ¥É¥Š¥§¥¢°Íž€Î¥ª¡Œ¥×¥óœèÍý
301                 */
302                p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
303
304                /*
305                 *  Œõ¿®ÄÌÃÎ¥³¡Œ¥ë¥Ð¥Ã¥¯€òµö²Ä€¹€ë¡¥
306                 */
307                sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
308                p_spcb->openflag = true;
309                p_spcb->errorflag = false;
310
311                if (unl_cpu() < 0) {
312                        p_spcb->errorflag = true;
313                        ercd = E_SYS;
314                        goto error_exit_enadsp;
315                }
316                ercd = E_OK;
317        }
318
319  error_exit_enadsp:
320        SVC(ena_dsp(), gen_ercd_sys(p_spcb));
321
322  error_exit:
323        return(ercd);
324}
325
326/*
327 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€Î¥¯¥í¡Œ¥º¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
328 */
329ER
330serial_cls_por(ID portid)
331{
332        SPCB    *p_spcb;
333        ER              ercd;
334        bool_t  eflag = false;
335
336        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
337                return(E_CTX);
338        }
339        if (!(1 <= portid && portid <= TNUM_PORT)) {
340                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
341        }
342        p_spcb = get_spcb(portid);
343
344        SVC(dis_dsp(), gen_ercd_sys(p_spcb));
345        if (!(p_spcb->openflag)) {              /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
346                ercd = E_OBJ;
347        }
348        else {
349                /*
350                 *  ¥Ï¡Œ¥É¥Š¥§¥¢°Íž€Î¥¯¥í¡Œ¥ºœèÍý
351                 */
352                if (loc_cpu() < 0) {
353                        eflag = true;
354                }
355                sio_cls_por(p_spcb->p_siopcb);
356                p_spcb->openflag = false;
357                if (unl_cpu() < 0) {
358                        eflag = true;
359                }
360
361                /*
362                 *  ¥»¥Þ¥Õ¥©€ÎœéŽü²œ
363                 */
364                if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
365                        eflag = true;
366                }
367                if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
368                        eflag = true;
369                }
370
371                /*
372                 *  ¥š¥é¡Œ¥³¡Œ¥É€ÎÀßÄê
373                 */
374                if (eflag) {
375                        ercd = gen_ercd_sys(p_spcb);
376                }
377                else {
378                        ercd = E_OK;
379                }
380        }
381        SVC(ena_dsp(), gen_ercd_sys(p_spcb));
382
383  error_exit:
384        return(ercd);
385}
386
387/*
388 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€Ø€ÎÊž»úÁ÷¿®
389 *
390 *  p_spcb€Ç»ØÄꀵ€ì€ë¥·¥ê¥¢¥ëI/O¥Ý¡Œ¥È€ËÂЀ·€Æ¡€Êž»úc€òÁ÷¿®€¹€ë¡¥Êž»ú
391 *  €òÁ÷¿®¥ì¥ž¥¹¥¿€Ë€€€ì€¿Ÿì¹ç€Ë€Ïtrue€òÊÖ€¹¡¥€œ€Š€Ç€Ê€€Ÿì¹ç€Ë€Ï¡€Á÷¿®
392 *  ¥ì¥ž¥¹¥¿€¬¶õ€€€¿€³€È€òÄÌÃ΀¹€ë¥³¡Œ¥ë¥Ð¥Ã¥¯ŽØ¿ô€òµö²Ä€·¡€false€òÊÖ€¹¡¥
393 *  €³€ÎŽØ¿ô€Ï¡€CPU¥í¥Ã¥¯ŸõÂրǞƀӜЀµ€ì€ë¡¥
394 */
395Inline bool_t
396serial_snd_chr(SPCB *p_spcb, char c)
397{
398        if (sio_snd_chr(p_spcb->p_siopcb, c)) {
399                return(true);
400        }
401        else {
402                sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
403                return(false);
404        }
405}
406
407/*
408 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€Ø€Î1Êž»úÁ÷¿®
409 */
410static ER_BOOL
411serial_wri_chr(SPCB *p_spcb, char c)
412{
413        bool_t  buffer_full;
414        ER              ercd, rercd;
415
416        /*
417         *  LF€ÎÁ°€ËCR€òÁ÷¿®€¹€ë¡¥
418         */
419        if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
420                /*
421                 *  °Ê²Œ€Î¥³¡Œ¥É€ÏºÆµ¢žÆœÐ€·€Ë€Ê€Ã€Æ€€€ë€¬¡€°ú¿ôc€¬'\n'€ÎŸì¹ç€Ë
422                 *  °ú¿ôc€ò'\r'€È€·€ÆžÆ€ÓœÐ€¹€³€È€«€é¡€€³€ÎºÆµ¢žÆœÐ€·€Ï2²óÌÜ€Î
423                 *  žÆ€ÓœÐ€·€Çɬ€º»ß€Þ€ë¡¥
424                 */
425                SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
426                if ((bool_t) rercd) {
427                        SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
428                                                                                gen_ercd_wait(rercd, p_spcb));
429                }
430        }
431
432        SVC(loc_cpu(), gen_ercd_sys(p_spcb));
433        if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
434                                                                && serial_snd_chr(p_spcb, c)) {
435                /*
436                 *  ¥·¥ê¥¢¥ëI/O¥Ç¥Ð¥€¥¹€ÎÁ÷¿®¥ì¥ž¥¹¥¿€ËÊž»ú€òÆþ€ì€ë€³€È€ËÀ®žù€·
437                 *  €¿Ÿì¹ç¡¥
438                 */
439                buffer_full = false;
440        }
441        else {
442                /*
443                 *  Á÷¿®¥Ð¥Ã¥Õ¥¡€ËÊž»ú€òÆþ€ì€ë¡¥
444                 */
445                p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
446                INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
447                p_spcb->snd_count++;
448                buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
449        }
450
451        SVC(unl_cpu(), gen_ercd_sys(p_spcb));
452        ercd = (ER_BOOL) buffer_full;
453
454  error_exit:
455        return(ercd);
456}
457
458/*
459 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€Ø€ÎÊž»úÎóÁ÷¿®¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
460 */
461ER_UINT
462serial_wri_dat(ID portid, const char *buf, uint_t len)
463{
464        SPCB    *p_spcb;
465        bool_t  buffer_full;
466        uint_t  wricnt = 0U;
467        ER              ercd, rercd;
468
469        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
470                return(E_CTX);
471        }
472        if (!(1 <= portid && portid <= TNUM_PORT)) {
473                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
474        }
475
476        p_spcb = get_spcb(portid);
477        if (!(p_spcb->openflag)) {              /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
478                return(E_OBJ);
479        }
480        if (p_spcb->errorflag) {                /* ¥š¥é¡ŒŸõÂÖ€«€Î¥Á¥§¥Ã¥¯ */
481                return(E_SYS);
482        }
483
484        buffer_full = true;                             /* ¥ë¡Œ¥×€Î1²ó€á€Ïwai_sem€¹€ë */
485        while (wricnt < len) {
486                if (buffer_full) {
487                        SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
488                                                                                gen_ercd_wait(rercd, p_spcb));
489                }
490                SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
491                wricnt++;
492                buffer_full = (bool_t) rercd;
493        }
494        if (!buffer_full) {
495                SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
496        }
497        ercd = E_OK;
498
499  error_exit:
500        return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
501}
502
503/*
504 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€«€é€Î1Êž»úŒõ¿®
505 */
506static bool_t
507serial_rea_chr(SPCB *p_spcb, char *p_c)
508{
509        bool_t  buffer_empty;
510        ER              ercd;
511
512        SVC(loc_cpu(), gen_ercd_sys(p_spcb));
513
514        /*
515         *  Œõ¿®¥Ð¥Ã¥Õ¥¡€«€éÊž»ú€òŒè€êœÐ€¹¡¥
516         */
517        *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
518        INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
519        p_spcb->rcv_count--;
520        buffer_empty = (p_spcb->rcv_count == 0U);
521
522        /*
523         *  START€òÁ÷¿®€¹€ë¡¥
524         */
525        if (p_spcb->rcv_stopped && p_spcb->rcv_count
526                                                                <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
527                if (!serial_snd_chr(p_spcb, FC_START)) {
528                        p_spcb->rcv_fc_chr = FC_START;
529                }
530                p_spcb->rcv_stopped = false;
531        }
532
533        SVC(unl_cpu(), gen_ercd_sys(p_spcb));
534        ercd = (ER_BOOL) buffer_empty;
535
536  error_exit:
537        return(ercd);
538}
539
540/*
541 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€«€é€ÎÊž»úÎóŒõ¿®¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
542 */
543ER_UINT
544serial_rea_dat(ID portid, char *buf, uint_t len)
545{
546        SPCB    *p_spcb;
547        bool_t  buffer_empty;
548        uint_t  reacnt = 0U;
549        char    c = '\0';               /* ¥³¥ó¥Ñ¥€¥é€Î·Ù¹ð€òÍ޻߀¹€ë€¿€á€ËœéŽü²œ€¹€ë */
550        ER              ercd, rercd;
551
552        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
553                return(E_CTX);
554        }
555        if (!(1 <= portid && portid <= TNUM_PORT)) {
556                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
557        }
558
559        p_spcb = get_spcb(portid);
560        if (!(p_spcb->openflag)) {              /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
561                return(E_OBJ);
562        }
563        if (p_spcb->errorflag) {                /* ¥š¥é¡ŒŸõÂÖ€«€Î¥Á¥§¥Ã¥¯ */
564                return(E_SYS);
565        }
566
567        buffer_empty = true;                    /* ¥ë¡Œ¥×€Î1²ó€á€Ïwai_sem€¹€ë */
568        while (reacnt < len) {
569                if (buffer_empty) {
570                        SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
571                                                                                gen_ercd_wait(rercd, p_spcb));
572                }
573                SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
574                *buf++ = c;
575                reacnt++;
576                buffer_empty = (bool_t) rercd;
577
578                /*
579                 *  ¥š¥³¡Œ¥Ð¥Ã¥¯œèÍý¡¥
580                 */
581                if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
582                        SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
583                                                                                gen_ercd_wait(rercd, p_spcb));
584                        SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
585                        if (!((bool_t) rercd)) {
586                                SVC(sig_sem(p_spcb->p_spinib->snd_semid),
587                                                                                gen_ercd_sys(p_spcb));
588                        }
589                }
590        }
591        if (!buffer_empty) {
592                SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
593        }
594        ercd = E_OK;
595
596  error_exit:
597        return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
598}
599
600/*
601 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€ÎÀ©žæ¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
602 */
603ER
604serial_ctl_por(ID portid, uint_t ioctl)
605{
606        SPCB    *p_spcb;
607
608        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
609                return(E_CTX);
610        }
611        if (!(1 <= portid && portid <= TNUM_PORT)) {
612                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
613        }
614
615        p_spcb = get_spcb(portid);
616        if (!(p_spcb->openflag)) {              /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
617                return(E_OBJ);
618        }
619        if (p_spcb->errorflag) {                /* ¥š¥é¡ŒŸõÂÖ€«€Î¥Á¥§¥Ã¥¯ */
620                return(E_SYS);
621        }
622
623        p_spcb->ioctl = ioctl;
624        return(E_OK);
625}
626
627/*
628 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥ÈŸõÂրλ²ŸÈ¡Ê¥µ¡Œ¥Ó¥¹¥³¡Œ¥ë¡Ë
629 */
630ER
631serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
632{
633        SPCB    *p_spcb;
634
635        if (sns_dpn()) {                                /* ¥³¥ó¥Æ¥­¥¹¥È€Î¥Á¥§¥Ã¥¯ */
636                return(E_CTX);
637        }
638        if (!(1 <= portid && portid <= TNUM_PORT)) {
639                return(E_ID);                           /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
640        }
641
642        p_spcb = get_spcb(portid);
643        if (!(p_spcb->openflag)) {              /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
644                return(E_OBJ);
645        }
646        if (p_spcb->errorflag) {                /* ¥š¥é¡ŒŸõÂÖ€«€Î¥Á¥§¥Ã¥¯ */
647                return(E_SYS);
648        }
649
650        pk_rpor->reacnt = p_spcb->rcv_count;
651        pk_rpor->wricnt = p_spcb->snd_count;
652        return(E_OK);
653}
654
655/*
656 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€«€é€ÎÁ÷¿®²ÄÇœ¥³¡Œ¥ë¥Ð¥Ã¥¯
657 */
658void
659sio_irdy_snd(intptr_t exinf)
660{
661        SPCB    *p_spcb;
662
663        p_spcb = (SPCB *) exinf;
664        if (p_spcb->rcv_fc_chr != '\0') {
665                /*
666                 *  START/STOP €òÁ÷¿®€¹€ë¡¥
667                 */
668                (void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
669                p_spcb->rcv_fc_chr = '\0';
670        }
671        else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
672                /*
673                 *  Á÷¿®¥Ð¥Ã¥Õ¥¡Ã怫€éÊž»ú€òŒè€êœÐ€·€ÆÁ÷¿®€¹€ë¡¥
674                 */
675                (void) sio_snd_chr(p_spcb->p_siopcb,
676                                        p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
677                INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
678                if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
679                        if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
680                                p_spcb->errorflag = true;
681                        }
682                }
683                p_spcb->snd_count--;
684        }
685        else {
686                /*
687                 *  Á÷¿®€¹€Ù€­Êž»ú€¬€Ê€€Ÿì¹ç€Ï¡€Á÷¿®²ÄÇœ¥³¡Œ¥ë¥Ð¥Ã¥¯€ò¶Ø»ß€¹€ë¡¥
688                 */
689                sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
690        }
691}
692
693/*
694 *  ¥·¥ê¥¢¥ë¥Ý¡Œ¥È€«€é€ÎŒõ¿®ÄÌÃÎ¥³¡Œ¥ë¥Ð¥Ã¥¯
695 */
696void
697sio_irdy_rcv(intptr_t exinf)
698{
699        SPCB    *p_spcb;
700        char    c;
701
702        p_spcb = (SPCB *) exinf;
703        c = (char) sio_rcv_chr(p_spcb->p_siopcb);
704        if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
705                /*
706                 *  Á÷¿®€ò°ì»þÄä»ß€¹€ë¡¥Á÷¿®Ãæ€ÎÊž»ú€Ï€œ€Î€Þ€ÞÁ÷¿®€¹€ë¡¥
707                 */
708                p_spcb->snd_stopped = true;
709        }
710        else if (p_spcb->snd_stopped && (c == FC_START
711                                || (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
712                /*
713                 *  Á÷¿®€òºÆ³«€¹€ë¡¥
714                 */
715                p_spcb->snd_stopped = false;
716                if (p_spcb->snd_count > 0U) {
717                        c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
718                        if (serial_snd_chr(p_spcb, c)) {
719                                INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
720                                if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
721                                        if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
722                                                p_spcb->errorflag = true;
723                                        }
724                                }
725                                p_spcb->snd_count--;
726                        }
727                }
728        }
729        else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
730                /*
731                 *  Á÷¿®€ËÂЀ·€Æ¥Õ¥í¡ŒÀ©žæ€·€Æ€€€ëŸì¹ç¡€START €ÏŒÎ€Æ€ë¡¥
732                 */
733        }
734        else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
735                /*
736                 *  ¥Ð¥Ã¥Õ¥¡¥Õ¥ë€ÎŸì¹ç¡€Œõ¿®€·€¿Êž»ú€òŒÎ€Æ€ë¡¥
737                 */
738        }
739        else {
740                /*
741                 *  Œõ¿®€·€¿Êž»ú€òŒõ¿®¥Ð¥Ã¥Õ¥¡€ËÆþ€ì€ë¡¥
742                 */
743                p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
744                INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
745                if (p_spcb->rcv_count == 0U) {
746                        if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
747                                p_spcb->errorflag = true;
748                        }
749                }
750                p_spcb->rcv_count++;
751
752                /*
753                 *  STOP€òÁ÷¿®€¹€ë¡¥
754                 */
755                if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
756                                                && p_spcb->rcv_count
757                                                        >= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
758                        if (!serial_snd_chr(p_spcb, FC_STOP)) {
759                                p_spcb->rcv_fc_chr = FC_STOP;
760                        }
761                        p_spcb->rcv_stopped = true;
762                }
763        }
764}
765
766/*
767 *  ¥·¥ê¥¢¥ë¥€¥ó¥¿¥Õ¥§¡Œ¥¹¥É¥é¥€¥Ð€«€é€ÎÌ€Á÷¿®Êž»ú€ÎŒèœÐ€·
768 */
769bool_t
770serial_get_chr(ID portid, char *p_c)
771{
772        SPCB    *p_spcb;
773
774        if (1 <= portid && portid <= TNUM_PORT) {       /* ¥Ý¡Œ¥ÈÈÖ¹æ€Î¥Á¥§¥Ã¥¯ */
775                p_spcb = get_spcb(portid);
776                if (p_spcb->openflag) {                                 /* ¥ª¡Œ¥×¥óºÑ€ß€«€Î¥Á¥§¥Ã¥¯ */
777                        if (p_spcb->snd_count > 0U) {
778                                *p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
779                                INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
780                                p_spcb->snd_count--;
781                                return(true);
782                        }
783                }
784        }
785        return(false);
786}
詳しい使い方は TracBrowser を参照してください。