ER_UINT serial_rea_dat(ID portid, char *buf, UINT len) { SPCB *spcb; BOOL buffer_empty; UINT i; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); if (!(spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } buffer_empty = TRUE; /* ループの1回めは wai_sem する */ for (i = 0; i < len; i++) { if (buffer_empty) { _syscall(wai_sem(spcb->spinib->rcv_semid)); } buffer_empty = serial_rea_chr(spcb, buf++); } if (!buffer_empty) { _syscall(sig_sem(spcb->spinib->rcv_semid)); } return((ER_UINT) len); }
/* * シリアルポートのクローズ */ ER serial_cls_por(ID portid) { SPCB *spcb; ER ercd; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); _syscall(loc_cpu()); if (!(spcb->openflag)) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * ハードウェア依存のクローズ処理 */ sio_cls_por(spcb->siopcb); spcb->openflag = FALSE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd); }
/* * シリアルポートのクローズ(サービスコール) */ ER serial_cls_por(ID portid) { SPCB *p_spcb; ER ercd; bool_t eflag = false; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); SVC(dis_dsp(), gen_ercd_sys(p_spcb)); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * ハードウェア依存のクローズ処理 */ if (loc_cpu() < 0) { eflag = true; } sio_cls_por(p_spcb->p_siopcb); p_spcb->openflag = false; if (unl_cpu() < 0) { eflag = true; } /* * セマフォの初期化 */ if (ini_sem(p_spcb->p_spinib->snd_semid) < 0) { eflag = true; } if (ini_sem(p_spcb->p_spinib->rcv_semid) < 0) { eflag = true; } /* * エラーコードの設定 */ if (eflag) { ercd = gen_ercd_sys(p_spcb); } else { ercd = E_OK; } } SVC(ena_dsp(), gen_ercd_sys(p_spcb)); error_exit: return(ercd); }
/* * シリアルポートからの文字列受信(サービスコール) */ ER_UINT serial_rea_dat(ID portid, char *buf, uint_t len) { SPCB *p_spcb; bool_t buffer_empty; uint_t reacnt = 0U; char c = '\0'; /* コンパイラの警告を抑止するために初期化する */ ER ercd, rercd; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } if (p_spcb->errorflag) { /* エラー状態かのチェック */ return(E_SYS); } buffer_empty = true; /* ループの1回めはwai_semする */ while (reacnt < len) { if (buffer_empty) { SVC(rercd = wai_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_wait(rercd, p_spcb)); } SVC(rercd = serial_rea_chr(p_spcb, &c), rercd); *buf++ = c; reacnt++; buffer_empty = (bool_t) rercd; /* * エコーバック処理. */ if ((p_spcb->ioctl & IOCTL_ECHO) != 0U) { SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid), gen_ercd_wait(rercd, p_spcb)); SVC(rercd = serial_wri_chr(p_spcb, c), rercd); if (!((bool_t) rercd)) { SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb)); } } } if (!buffer_empty) { SVC(sig_sem(p_spcb->p_spinib->rcv_semid), gen_ercd_sys(p_spcb)); } ercd = E_OK; error_exit: return(reacnt > 0U ? (ER_UINT) reacnt : ercd); }
/* * シリアルポートのオープン */ ER serial_opn_por(ID portid) { SPCB *spcb; ER ercd; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); _syscall(loc_cpu()); if (spcb->openflag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * 変数の初期化 */ spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV); spcb->rcv_read_ptr = spcb->rcv_write_ptr = 0; spcb->rcv_count = 0; spcb->rcv_fc_chr = '\0'; spcb->rcv_stopped = FALSE; spcb->snd_read_ptr = spcb->snd_write_ptr = 0; spcb->snd_count = 0; spcb->snd_stopped = FALSE; /* * ハードウェア依存のオープン処理 */ spcb->siopcb = sio_opn_por(portid, (VP_INT) spcb); /* * 受信通知コールバックを許可する. */ sio_ena_cbr(spcb->siopcb, SIO_ERDY_RCV); spcb->openflag = TRUE; ercd = E_OK; } _syscall(unl_cpu()); return(ercd); }
/* * シリアルインタフェースドライバからの未送信文字の取出し */ bool_t serial_get_chr(ID portid, char *p_c) { SPCB *p_spcb; if (1 <= portid && portid <= TNUM_PORT) { /* ポート番号のチェック */ p_spcb = get_spcb(portid); if (p_spcb->openflag) { /* オープン済みかのチェック */ if (p_spcb->snd_count > 0U) { *p_c = p_spcb->p_spinib->snd_buffer[p_spcb->snd_read_ptr]; INC_PTR(p_spcb->snd_read_ptr, p_spcb->p_spinib->snd_bufsz); p_spcb->snd_count--; return(true); } } } return(false); }
/* * シリアルポートの制御 */ ER serial_ctl_por(ID portid, UINT ioctl) { SPCB *spcb; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); if (!(spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } spcb->ioctl = ioctl; return(E_OK); }
/* * シリアルポートへの文字列送信(サービスコール) */ ER_UINT serial_wri_dat(ID portid, const char *buf, uint_t len) { SPCB *p_spcb; bool_t buffer_full; uint_t wricnt = 0U; ER ercd, rercd; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } if (p_spcb->errorflag) { /* エラー状態かのチェック */ return(E_SYS); } buffer_full = true; /* ループの1回めはwai_semする */ while (wricnt < len) { if (buffer_full) { SVC(rercd = wai_sem(p_spcb->p_spinib->snd_semid), gen_ercd_wait(rercd, p_spcb)); } SVC(rercd = serial_wri_chr(p_spcb, *buf++), rercd); wricnt++; buffer_full = (bool_t) rercd; } if (!buffer_full) { SVC(sig_sem(p_spcb->p_spinib->snd_semid), gen_ercd_sys(p_spcb)); } ercd = E_OK; error_exit: return(wricnt > 0U ? (ER_UINT) wricnt : ercd); }
/* * シリアルポート状態の参照 */ ER serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor) { SPCB *spcb; if (sns_ctx()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } spcb = get_spcb(portid); if (!(spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } pk_rpor->reacnt = spcb->rcv_count; pk_rpor->wricnt = spcb->snd_count; return(E_OK); }
/* * シリアルポートの制御(サービスコール) */ ER serial_ctl_por(ID portid, uint_t ioctl) { SPCB *p_spcb; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } if (p_spcb->errorflag) { /* エラー状態かのチェック */ return(E_SYS); } p_spcb->ioctl = ioctl; return(E_OK); }
/* * シリアルポート状態の参照(サービスコール) */ ER _serial_ref_por(ID portid, T_SERIAL_RPOR *pk_rpor) { SPCB *p_spcb; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!VALID_PORTID(portid)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); if (!(p_spcb->openflag)) { /* オープン済みかのチェック */ return(E_OBJ); } if (p_spcb->errorflag) { /* エラー状態かのチェック */ return(E_SYS); } pk_rpor->reacnt = p_spcb->rcv_count; pk_rpor->wricnt = p_spcb->snd_count; return(E_OK); }
/* * シリアルポートのオープン(サービスコール) */ ER serial_opn_por(ID portid) { SPCB *p_spcb; ER ercd; if (sns_dpn()) { /* コンテキストのチェック */ return(E_CTX); } if (!(1 <= portid && portid <= TNUM_PORT)) { return(E_ID); /* ポート番号のチェック */ } p_spcb = get_spcb(portid); SVC(dis_dsp(), gen_ercd_sys(p_spcb)); if (p_spcb->openflag) { /* オープン済みかのチェック */ ercd = E_OBJ; } else { /* * 変数の初期化 */ p_spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV); p_spcb->rcv_read_ptr = 0U; p_spcb->rcv_write_ptr = 0U; p_spcb->rcv_count = 0U; p_spcb->rcv_fc_chr = '\0'; p_spcb->rcv_stopped = false; p_spcb->snd_read_ptr = 0U; p_spcb->snd_write_ptr = 0U; p_spcb->snd_count = 0U; p_spcb->snd_stopped = false; /* * これ以降,割込みを禁止する. */ if (loc_cpu() < 0) { ercd = E_SYS; goto error_exit_enadsp; } /* * ハードウェア依存のオープン処理 */ p_spcb->p_siopcb = sio_opn_por(portid, (intptr_t) p_spcb); /* * 受信通知コールバックを許可する. */ sio_ena_cbr(p_spcb->p_siopcb, SIO_RDY_RCV); p_spcb->openflag = true; p_spcb->errorflag = false; if (unl_cpu() < 0) { p_spcb->errorflag = true; ercd = E_SYS; goto error_exit_enadsp; } ercd = E_OK; } error_exit_enadsp: SVC(ena_dsp(), gen_ercd_sys(p_spcb)); error_exit: return(ercd); }