source: asp_ewarm/asp-1.7.0/syssvc/serial.c@ 61

Last change on this file since 61 was 61, checked in by ertl-honda, 11 years ago

ASP for EWARM のコミット.

File size: 19.1 KB
Line 
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-2011 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
12 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
13 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
14 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
15 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
16 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
17 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
18 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
19ƒƒ“ƒgi—˜—p
20 * ŽÒƒ}ƒjƒ…
21ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
22 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
23 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
24 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
25 * ‚ƁD
26 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
27ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
28ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
29 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
30 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
31 * •ñ‚·‚邱‚ƁD
32 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
33 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
34 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
35 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
36 * –Ɛӂ·‚邱‚ƁD
37 *
38 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
39 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
40 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
41 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
42 * ‚̐ӔC‚𕉂í‚È‚¢D
43 *
44 * @(#) $Id: serial.c 2055 2011-04-10 11:36:13Z ertl-hiro $
45 */
46
47/*
48 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo
49 */
50
51#include <kernel.h>
52#include <t_syslog.h>
53#include "target_syssvc.h"
54#include "target_serial.h"
55#include "serial.h"
56#include "kernel_cfg.h"
57
58/*
59 * ƒoƒbƒtƒ@ƒTƒCƒY‚̃fƒtƒHƒ‹ƒg’l‚ƃoƒbƒtƒ@‚Ì’è‹`
60 */
61#ifndef SERIAL_RCV_BUFSZ1
62#define SERIAL_RCV_BUFSZ1 256 /* ƒ|[ƒg1‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
63#endif /* SERIAL_RCV_BUFSZ1 */
64
65#ifndef SERIAL_SND_BUFSZ1
66#define SERIAL_SND_BUFSZ1 256 /* ƒ|[ƒg1‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
67#endif /* SERIAL_SND_BUFSZ1 */
68
69static char_t rcv_buffer1[SERIAL_RCV_BUFSZ1];
70static char_t snd_buffer1[SERIAL_SND_BUFSZ1];
71
72#if TNUM_PORT >= 2 /* ƒ|[ƒg2‚ÉŠÖ‚·‚é’è‹` */
73
74#ifndef SERIAL_RCV_BUFSZ2
75#define SERIAL_RCV_BUFSZ2 256 /* ƒ|[ƒg2‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
76#endif /* SERIAL_RCV_BUFSZ2 */
77
78#ifndef SERIAL_SND_BUFSZ2
79#define SERIAL_SND_BUFSZ2 256 /* ƒ|[ƒg2‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
80#endif /* SERIAL_SND_BUFSZ2 */
81
82static char_t rcv_buffer2[SERIAL_RCV_BUFSZ2];
83static char_t snd_buffer2[SERIAL_SND_BUFSZ2];
84
85#endif /* TNUM_PORT >= 2 */
86
87#if TNUM_PORT >= 3 /* ƒ|[ƒg3‚ÉŠÖ‚·‚é’è‹` */
88
89#ifndef SERIAL_RCV_BUFSZ3
90#define SERIAL_RCV_BUFSZ3 256 /* ƒ|[ƒg3‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
91#endif /* SERIAL_RCV_BUFSZ3 */
92
93#ifndef SERIAL_SND_BUFSZ3
94#define SERIAL_SND_BUFSZ3 256 /* ƒ|[ƒg3‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
95#endif /* SERIAL_SND_BUFSZ3 */
96
97static char_t rcv_buffer3[SERIAL_RCV_BUFSZ3];
98static char_t snd_buffer3[SERIAL_SND_BUFSZ3];
99
100#endif /* TNUM_PORT >= 3 */
101
102#if TNUM_PORT >= 4 /* ƒ|[ƒg4‚ÉŠÖ‚·‚é’è‹` */
103
104#ifndef SERIAL_RCV_BUFSZ4
105#define SERIAL_RCV_BUFSZ4 256 /* ƒ|[ƒg4‚ÌŽóMƒoƒbƒtƒ@ƒTƒCƒY */
106#endif /* SERIAL_RCV_BUFSZ4 */
107
108#ifndef SERIAL_SND_BUFSZ4
109#define SERIAL_SND_BUFSZ4 256 /* ƒ|[ƒg4‚Ì‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
110#endif /* SERIAL_SND_BUFSZ4 */
111
112static char_t rcv_buffer4[SERIAL_RCV_BUFSZ4];
113static char_t snd_buffer4[SERIAL_SND_BUFSZ4];
114
115#endif /* TNUM_PORT >= 4 */
116
117/*
118 * ƒtƒ[§Œä‚ÉŠÖ˜A‚·‚é’萔‚ƃ}ƒNƒ
119 */
120#define FC_STOP '\023' /* ƒRƒ“ƒgƒ[ƒ‹-S */
121#define FC_START '\021' /* ƒRƒ“ƒgƒ[ƒ‹-Q */
122
123#define BUFCNT_STOP(bufsz) ((bufsz) * 3 / 4) /* STOP‚ð‘—‚éŠî€•¶Žš” */
124#define BUFCNT_START(bufsz) ((bufsz) / 2) /* START‚ð‘—‚éŠî€•¶Žš” */
125
126/*
127 * ƒVƒŠƒAƒ‹ƒ|[ƒg‰Šú‰»ƒuƒƒbƒN
128 */
129typedef struct serial_port_initialization_block {
130 ID rcv_semid; /* ŽóMƒoƒbƒtƒ@ŠÇ——pƒZƒ}ƒtƒH‚ÌID */
131 ID snd_semid; /* ‘—Mƒoƒbƒtƒ@ŠÇ——pƒZƒ}ƒtƒH‚ÌID */
132 uint_t rcv_bufsz; /* ŽóMƒoƒbƒtƒ@ƒTƒCƒY */
133 char_t *rcv_buffer; /* ŽóMƒoƒbƒtƒ@ */
134 uint_t snd_bufsz; /* ‘—Mƒoƒbƒtƒ@ƒTƒCƒY */
135 char_t *snd_buffer; /* ‘—Mƒoƒbƒtƒ@ */
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 * ƒVƒŠƒAƒ‹ƒ|[ƒgŠÇ—ƒuƒƒbƒN
161 */
162typedef struct serial_port_control_block {
163 const SPINIB *p_spinib; /* ƒVƒŠƒAƒ‹ƒ|[ƒg‰Šú‰»ƒuƒƒbƒN */
164 SIOPCB *p_siopcb; /* ƒVƒŠƒAƒ‹I/Oƒ|[ƒgŠÇ—ƒuƒƒbƒN */
165 bool_t openflag; /* ƒI[ƒvƒ“Ï‚݃tƒ‰ƒO */
166 bool_t errorflag; /* ƒGƒ‰[ƒtƒ‰ƒO */
167 uint_t ioctl; /* “®ì§Œä‚̐ݒè’l */
168
169 uint_t rcv_read_ptr; /* ŽóMƒoƒbƒtƒ@“Ǐo‚µƒ|ƒCƒ“ƒ^ */
170 uint_t rcv_write_ptr; /* ŽóMƒoƒbƒtƒ@‘ž‚݃|ƒCƒ“ƒ^ */
171 uint_t rcv_count; /* ŽóMƒoƒbƒtƒ@’†‚Ì•¶Žš” */
172 char_t rcv_fc_chr; /* ‘—‚é‚ׂ«START/STOP */
173 bool_t rcv_stopped; /* STOP‚ð‘—‚Á‚½ó‘Ô‚©H */
174
175 uint_t snd_read_ptr; /* ‘—Mƒoƒbƒtƒ@“Ǐo‚µƒ|ƒCƒ“ƒ^ */
176 uint_t snd_write_ptr; /* ‘—Mƒoƒbƒtƒ@‘ž‚݃|ƒCƒ“ƒ^ */
177 uint_t snd_count; /* ‘—Mƒoƒbƒtƒ@’†‚Ì•¶Žš” */
178 bool_t snd_stopped; /* STOP‚ðŽó‚¯Žæ‚Á‚½ó‘Ô‚©H */
179} SPCB;
180
181static SPCB spcb_table[TNUM_PORT];
182
183/*
184 * ƒVƒŠƒAƒ‹ƒ|[ƒgID‚©‚çƒVƒŠƒAƒ‹ƒ|[ƒgŠÇ—ƒuƒƒbƒN‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
185 */
186#define INDEX_PORT(portid) ((uint_t)((portid) - 1))
187#define get_spcb(portid) (&(spcb_table[INDEX_PORT(portid)]))
188
189/*
190 * ƒ|ƒCƒ“ƒ^‚̃Cƒ“ƒNƒŠƒƒ“ƒg
191 */
192#define INC_PTR(ptr, bufsz) { if (++(ptr) == (bufsz)) { (ptr) = 0; }}
193
194/*
195 * ƒT[ƒrƒXƒR[ƒ‹ŒÄo‚µƒ}ƒNƒ
196 *
197 * ƒT[ƒrƒXƒR[ƒ‹ŒÄo‚µ‚ðŠÜ‚ÞŽ®exp‚ð•]‰¿‚µC•Ô’l‚ªƒGƒ‰[i•‰‚Ì’lj‚̏ê
198 * ‡‚ɂ́Cerc‚Éercd_exp‚ð•]‰¿‚µ‚½’l‚ð‘ã“ü‚µCerror_exit‚Égoto‚·‚éD
199 */
200#define SVC(exp, ercd_exp) \
201 { if ((exp) < 0) { ercd = (ercd_exp); goto error_exit; }}
202
203/*
204 * E_SYSƒGƒ‰[‚̐¶¬
205 */
206static ER
207gen_ercd_sys(SPCB *p_spcb)
208{
209 p_spcb->errorflag = true;
210 return(E_SYS);
211}
212
213/*
214 * ‘Ò‚¿‚É“ü‚éƒT[ƒrƒXƒR[ƒ‹‚©‚ç‚̃Gƒ‰[‚Ì•ÏŠ·
215 */
216static ER
217gen_ercd_wait(ER rercd, SPCB *p_spcb)
218{
219 switch (MERCD(rercd)) {
220 case E_RLWAI:
221 case E_DLT:
222 return(rercd);
223 default:
224 p_spcb->errorflag = true;
225 return(E_SYS);
226 }
227}
228
229/*
230 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo‚̏‰Šú‰»ƒ‹[ƒ`ƒ“
231 */
232void
233serial_initialize(intptr_t exinf)
234{
235 uint_t i;
236 SPCB *p_spcb;
237
238 for (p_spcb = spcb_table, i = 0; i < TNUM_PORT; p_spcb++, i++) {
239 p_spcb->p_spinib = &(spinib_table[i]);
240 p_spcb->openflag = false;
241 }
242}
243
244/*
245 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̃I[ƒvƒ“iƒT[ƒrƒXƒR[ƒ‹j
246 */
247ER
248serial_opn_por(ID portid)
249{
250 SPCB *p_spcb;
251 ER ercd;
252
253 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
254 return(E_CTX);
255 }
256 if (!(1 <= portid && portid <= TNUM_PORT)) {
257 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
258 }
259 p_spcb = get_spcb(portid);
260
261 SVC(dis_dsp(), gen_ercd_sys(p_spcb));
262 if (p_spcb->openflag) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
263 ercd = E_OBJ;
264 }
265 else {
266 /*
267 * •Ï”‚̏‰Šú‰»
268 */
269 p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV);
270
271 p_spcb->rcv_read_ptr = p_spcb->rcv_write_ptr = 0U;
272 p_spcb->rcv_count = 0U;
273 p_spcb->rcv_fc_chr = '\0';
274 p_spcb->rcv_stopped = false;
275
276 p_spcb->snd_read_ptr = p_spcb->snd_write_ptr = 0U;
277 p_spcb->snd_count = 0U;
278 p_spcb->snd_stopped = false;
279
280 /*
281 * ‚±‚êˆÈ~CŠ„ž‚Ý‚ð‹ÖŽ~‚·‚éD
282 */
283 if (loc_cpu() < 0) {
284 ercd = E_SYS;
285 goto error_exit_enadsp;
286 }
287
288 /*
289 * ƒn[ƒhƒEƒFƒAˆË‘¶‚̃I[ƒvƒ“ˆ—
290 */
291 p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb);
292
293 /*
294 * ŽóM’Ê’mƒR[ƒ‹ƒoƒbƒN‚ð‹–‰Â‚·‚éD
295 */
296 sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV);
297 p_spcb->openflag = true;
298 p_spcb->errorflag = false;
299
300 if (unl_cpu() < 0) {
301 p_spcb->errorflag = true;
302 ercd = E_SYS;
303 goto error_exit_enadsp;
304 }
305 ercd = E_OK;
306 }
307
308 error_exit_enadsp:
309 SVC(ena_dsp(), gen_ercd_sys(p_spcb));
310
311 error_exit:
312 return(ercd);
313}
314
315/*
316 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̃Nƒ[ƒYiƒT[ƒrƒXƒR[ƒ‹j
317 */
318ER
319serial_cls_por(ID portid)
320{
321 SPCB *p_spcb;
322 ER ercd;
323 bool_t eflag = false;
324
325 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
326 return(E_CTX);
327 }
328 if (!(1 <= portid && portid <= TNUM_PORT)) {
329 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
330 }
331 p_spcb = get_spcb(portid);
332
333 SVC(dis_dsp(), gen_ercd_sys(p_spcb));
334 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
335 ercd = E_OBJ;
336 }
337 else {
338 /*
339 * ƒn[ƒhƒEƒFƒAˆË‘¶‚̃Nƒ[ƒYˆ—
340 */
341 if (loc_cpu() < 0) {
342 eflag = true;
343 }
344 sio_cls_por(p_spcb->p_siopcb);
345 p_spcb->openflag = false;
346 if (unl_cpu() < 0) {
347 eflag = true;
348 }
349
350 /*
351 * ƒZƒ}ƒtƒH‚̏‰Šú‰»
352 */
353 if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) {
354 eflag = true;
355 }
356 if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) {
357 eflag = true;
358 }
359
360 /*
361 * ƒGƒ‰[ƒR[ƒh‚̐ݒè
362 */
363 if (eflag) {
364 ercd = gen_ercd_sys(p_spcb);
365 }
366 else {
367 ercd = E_OK;
368 }
369 }
370 SVC(ena_dsp(), gen_ercd_sys(p_spcb));
371
372 error_exit:
373 return(ercd);
374}
375
376/*
377 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì•¶Žš‘—M
378 *
379 * p_spcb‚ÅŽw’肳‚ê‚éƒVƒŠƒAƒ‹I/Oƒ|[ƒg‚ɑ΂µ‚āC•¶Žšc‚𑗐M‚·‚éD•¶Žš
380 * ‚𑗐MƒŒƒWƒXƒ^‚É‚¢‚ꂽê‡‚É‚Ítrue‚ð•Ô‚·D‚»‚¤‚Å‚È‚¢ê‡‚ɂ́C‘—M
381 * ƒŒƒWƒXƒ^‚ª‹ó‚¢‚½‚±‚Æ‚ð’Ê’m‚·‚éƒR[ƒ‹ƒoƒbƒNŠÖ”‚ð‹–‰Â‚µCfalse‚ð•Ô‚·D
382 * ‚±‚̊֐”‚́CCPUƒƒbƒNó‘ԂŌĂяo‚³‚ê‚éD
383 */
384Inline bool_t
385serial_snd_chr(SPCB *p_spcb, char_t c)
386{
387 if (sio_snd_chr(p_spcb->p_siopcb, c)) {
388 return(true);
389 }
390 else {
391 sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
392 return(false);
393 }
394}
395
396/*
397 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì1•¶Žš‘—M
398 */
399static ER_BOOL
400serial_wri_chr(SPCB *p_spcb, char_t c)
401{
402 bool_t buffer_full;
403 ER ercd, rercd;
404
405 /*
406 * LF‚Ì‘O‚ÉCR‚𑗐M‚·‚éD
407 */
408 if (c == '\n' && (p_spcb->ioctl & IOCTL_CRLF) != 0U) {
409 SVC(rercd = serial_wri_chr(p_spcb, '\r'), rercd);
410 if ((bool_t) rercd) {
411 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
412 gen_ercd_wait(rercd, p_spcb));
413 }
414 }
415
416 SVC(loc_cpu(), gen_ercd_sys(p_spcb));
417 if (p_spcb->snd_count == 0U && !(p_spcb->snd_stopped)
418 && serial_snd_chr(p_spcb, c)) {
419 /*
420 * ƒVƒŠƒAƒ‹I/OƒfƒoƒCƒX‚Ì‘—MƒŒƒWƒXƒ^‚É•¶Žš‚ð“ü‚ê‚邱‚Ƃɐ¬Œ÷‚µ
421 * ‚½ê‡D
422 */
423 buffer_full = false;
424 }
425 else {
426 /*
427 * ‘—Mƒoƒbƒtƒ@‚É•¶Žš‚ð“ü‚ê‚éD
428 */
429 p_spcb->p_spinib->snd_buffer[p_spcb->snd_write_ptr] = c;
430 INC_PTR(p_spcb->snd_write_ptr, p_spcb->p_spinib->snd_bufsz);
431 p_spcb->snd_count++;
432 buffer_full = (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz);
433 }
434
435 SVC(unl_cpu(), gen_ercd_sys(p_spcb));
436 ercd = (ER_BOOL) buffer_full;
437
438 error_exit:
439 return(ercd);
440}
441
442/*
443 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚Ö‚Ì•¶Žš—ñ‘—MiƒT[ƒrƒXƒR[ƒ‹j
444 */
445ER_UINT
446serial_wri_dat(ID portid, const char_t *buf, uint_t len)
447{
448 SPCB *p_spcb;
449 bool_t buffer_full;
450 uint_t wricnt = 0U;
451 ER ercd, rercd;
452
453 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
454 return(E_CTX);
455 }
456 if (!(1 <= portid && portid <= TNUM_PORT)) {
457 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
458 }
459
460 p_spcb = get_spcb(portid);
461 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
462 return(E_OBJ);
463 }
464 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
465 return(E_SYS);
466 }
467
468 buffer_full = true; /* ƒ‹[ƒv‚Ì1‰ñ‚ß‚Íwai_sem‚·‚é */
469 while (wricnt < len) {
470 if (buffer_full) {
471 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
472 gen_ercd_wait(rercd, p_spcb));
473 }
474 SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd);
475 wricnt++;
476 buffer_full = (bool_t) rercd;
477 }
478 if (!buffer_full) {
479 SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb));
480 }
481 ercd = E_OK;
482
483 error_exit:
484 return(wricnt > 0U ? (ER_UINT) wricnt : ercd);
485}
486
487/*
488 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì1•¶ŽšŽóM
489 */
490static bool_t
491serial_rea_chr(SPCB *p_spcb, char_t *p_c)
492{
493 bool_t buffer_empty;
494 ER ercd;
495
496 SVC(loc_cpu(), gen_ercd_sys(p_spcb));
497
498 /*
499 * ŽóMƒoƒbƒtƒ@‚©‚當Žš‚ðŽæ‚èo‚·D
500 */
501 *p_c = p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_read_ptr];
502 INC_PTR(p_spcb->rcv_read_ptr, p_spcb->p_spinib->rcv_bufsz);
503 p_spcb->rcv_count--;
504 buffer_empty = (p_spcb->rcv_count == 0U);
505
506 /*
507 * START‚𑗐M‚·‚éD
508 */
509 if (p_spcb->rcv_stopped && p_spcb->rcv_count
510 <= BUFCNT_START(p_spcb->p_spinib->rcv_bufsz)) {
511 if (!serial_snd_chr(p_spcb, FC_START)) {
512 p_spcb->rcv_fc_chr = FC_START;
513 }
514 p_spcb->rcv_stopped = false;
515 }
516
517 SVC(unl_cpu(), gen_ercd_sys(p_spcb));
518 ercd = (ER_BOOL) buffer_empty;
519
520 error_exit:
521 return(ercd);
522}
523
524/*
525 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì•¶Žš—ñŽóMiƒT[ƒrƒXƒR[ƒ‹j
526 */
527ER_UINT
528serial_rea_dat(ID portid, char_t *buf, uint_t len)
529{
530 SPCB *p_spcb;
531 bool_t buffer_empty;
532 uint_t reacnt = 0U;
533 char_t c = '\0'; /* ƒRƒ“ƒpƒCƒ‰‚ÌŒx‚ð—}Ž~‚·‚邽‚߂ɏ‰Šú‰»‚·‚é */
534 ER ercd, rercd;
535
536 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
537 return(E_CTX);
538 }
539 if (!(1 <= portid && portid <= TNUM_PORT)) {
540 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
541 }
542
543 p_spcb = get_spcb(portid);
544 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
545 return(E_OBJ);
546 }
547 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
548 return(E_SYS);
549 }
550
551 buffer_empty = true; /* ƒ‹[ƒv‚Ì1‰ñ‚ß‚Íwai_sem‚·‚é */
552 while (reacnt < len) {
553 if (buffer_empty) {
554 SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid),
555 gen_ercd_wait(rercd, p_spcb));
556 }
557 SVC(rercd = serial_rea_chr(p_spcb, &c), rercd);
558 *buf++ = c;
559 reacnt++;
560 buffer_empty = (bool_t) rercd;
561
562 /*
563 * ƒGƒR[ƒoƒbƒNˆ—D
564 */
565 if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) {
566 SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid),
567 gen_ercd_wait(rercd, p_spcb));
568 SVC(rercd = serial_wri_chr(p_spcb, c), rercd);
569 if (!((bool_t) rercd)) {
570 SVC(sig_sem(p_spcb->p_spinib->snd_semid),
571 gen_ercd_sys(p_spcb));
572 }
573 }
574 }
575 if (!buffer_empty) {
576 SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb));
577 }
578 ercd = E_OK;
579
580 error_exit:
581 return(reacnt > 0U ? (ER_UINT) reacnt : ercd);
582}
583
584/*
585 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚̐§ŒäiƒT[ƒrƒXƒR[ƒ‹j
586 */
587ER
588serial_ctl_por(ID portid, uint_t ioctl)
589{
590 SPCB *p_spcb;
591
592 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
593 return(E_CTX);
594 }
595 if (!(1 <= portid && portid <= TNUM_PORT)) {
596 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
597 }
598
599 p_spcb = get_spcb(portid);
600 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
601 return(E_OBJ);
602 }
603 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
604 return(E_SYS);
605 }
606
607 p_spcb->ioctl = ioctl;
608 return(E_OK);
609}
610
611/*
612 * ƒVƒŠƒAƒ‹ƒ|[ƒgó‘Ô‚ÌŽQÆiƒT[ƒrƒXƒR[ƒ‹j
613 */
614ER
615serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor)
616{
617 SPCB *p_spcb;
618
619 if (sns_dpn()) { /* ƒRƒ“ƒeƒLƒXƒg‚̃`ƒFƒbƒN */
620 return(E_CTX);
621 }
622 if (!(1 <= portid && portid <= TNUM_PORT)) {
623 return(E_ID); /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
624 }
625
626 p_spcb = get_spcb(portid);
627 if (!(p_spcb->openflag)) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
628 return(E_OBJ);
629 }
630 if (p_spcb->errorflag) { /* ƒGƒ‰[ó‘Ô‚©‚̃`ƒFƒbƒN */
631 return(E_SYS);
632 }
633
634 pk_rpor->reacnt = p_spcb->rcv_count;
635 pk_rpor->wricnt = p_spcb->snd_count;
636 return(E_OK);
637}
638
639/*
640 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚Ì‘—M‰Â”\ƒR[ƒ‹ƒoƒbƒN
641 */
642void
643sio_irdy_snd(intptr_t exinf)
644{
645 SPCB *p_spcb;
646
647 p_spcb = (SPCB *) exinf;
648 if (p_spcb->rcv_fc_chr != '\0') {
649 /*
650 * START/STOP ‚𑗐M‚·‚éD
651 */
652 (void) sio_snd_chr(p_spcb->p_siopcb, p_spcb->rcv_fc_chr);
653 p_spcb->rcv_fc_chr = '\0';
654 }
655 else if (!(p_spcb->snd_stopped) && p_spcb->snd_count > 0U) {
656 /*
657 * ‘—Mƒoƒbƒtƒ@’†‚©‚當Žš‚ðŽæ‚èo‚µ‚Ä‘—M‚·‚éD
658 */
659 (void) sio_snd_chr(p_spcb->p_siopcb,
660 p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]);
661 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
662 if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
663 if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
664 p_spcb->errorflag = true;
665 }
666 }
667 p_spcb->snd_count--;
668 }
669 else {
670 /*
671 * ‘—M‚·‚ׂ«•¶Žš‚ª‚È‚¢ê‡‚́C‘—M‰Â”\ƒR[ƒ‹ƒoƒbƒN‚ð‹ÖŽ~‚·‚éD
672 */
673 sio_dis_cbr(p_spcb->p_siopcb, SIO_RDY_SND);
674 }
675}
676
677/*
678 * ƒVƒŠƒAƒ‹ƒ|[ƒg‚©‚ç‚ÌŽóM’Ê’mƒR[ƒ‹ƒoƒbƒN
679 */
680void
681sio_irdy_rcv(intptr_t exinf)
682{
683 SPCB *p_spcb;
684 char_t c;
685
686 p_spcb = (SPCB *) exinf;
687 c = (char_t) sio_rcv_chr(p_spcb->p_siopcb);
688 if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_STOP) {
689 /*
690 * ‘—M‚ðˆêŽž’âŽ~‚·‚éD‘—M’†‚Ì•¶Žš‚Í‚»‚Ì‚Ü‚Ü‘—M‚·‚éD
691 */
692 p_spcb->snd_stopped = true;
693 }
694 else if (p_spcb->snd_stopped && (c == FC_START
695 || (p_spcb->ioctl & IOCTL_FCANY) != 0U)) {
696 /*
697 * ‘—M‚ðÄŠJ‚·‚éD
698 */
699 p_spcb->snd_stopped = false;
700 if (p_spcb->snd_count > 0U) {
701 c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
702 if (serial_snd_chr(p_spcb, c)) {
703 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
704 if (p_spcb->snd_count == p_spcb->p_spinib->snd_bufsz) {
705 if (isig_sem(p_spcb->p_spinib->snd_semid) < 0) {
706 p_spcb->errorflag = true;
707 }
708 }
709 p_spcb->snd_count--;
710 }
711 }
712 }
713 else if ((p_spcb->ioctl & IOCTL_FCSND) != 0U && c == FC_START) {
714 /*
715 * ‘—M‚ɑ΂µ‚ătƒ[§Œä‚µ‚Ä‚¢‚éê‡CSTART ‚ÍŽÌ‚Ä‚éD
716 */
717 }
718 else if (p_spcb->rcv_count == p_spcb->p_spinib->rcv_bufsz) {
719 /*
720 * ƒoƒbƒtƒ@ƒtƒ‹‚̏ꍇCŽóM‚µ‚½•¶Žš‚ðŽÌ‚Ä‚éD
721 */
722 }
723 else {
724 /*
725 * ŽóM‚µ‚½•¶Žš‚ðŽóMƒoƒbƒtƒ@‚É“ü‚ê‚éD
726 */
727 p_spcb->p_spinib->rcv_buffer[p_spcb->rcv_write_ptr] = c;
728 INC_PTR(p_spcb->rcv_write_ptr, p_spcb->p_spinib->rcv_bufsz);
729 if (p_spcb->rcv_count == 0U) {
730 if (isig_sem(p_spcb->p_spinib->rcv_semid) < 0) {
731 p_spcb->errorflag = true;
732 }
733 }
734 p_spcb->rcv_count++;
735
736 /*
737 * STOP‚𑗐M‚·‚éD
738 */
739 if ((p_spcb->ioctl & IOCTL_FCRCV) != 0U && !(p_spcb->rcv_stopped)
740 && p_spcb->rcv_count
741 >= BUFCNT_STOP(p_spcb->p_spinib->rcv_bufsz)) {
742 if (!serial_snd_chr(p_spcb, FC_STOP)) {
743 p_spcb->rcv_fc_chr = FC_STOP;
744 }
745 p_spcb->rcv_stopped = true;
746 }
747 }
748}
749
750/*
751 * ƒVƒŠƒAƒ‹ƒCƒ“ƒ^ƒtƒF[ƒXƒhƒ‰ƒCƒo‚©‚ç‚Ì–¢‘—M•¶Žš‚ÌŽæo‚µ
752 */
753bool_t
754serial_get_chr(ID portid, char_t *p_c)
755{
756 SPCB *p_spcb;
757
758 if (1 <= portid && portid <= TNUM_PORT) { /* ƒ|[ƒg”ԍ†‚̃`ƒFƒbƒN */
759 p_spcb = get_spcb(portid);
760 if (p_spcb->openflag) { /* ƒI[ƒvƒ“Ï‚Ý‚©‚̃`ƒFƒbƒN */
761 if (p_spcb->snd_count > 0U) {
762 *p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr];
763 INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz);
764 p_spcb->snd_count--;
765 return(true);
766 }
767 }
768 }
769 return(false);
770}
Note: See TracBrowser for help on using the repository browser.