serial.c

シリアルインタフェースドライバ [詳細]

#include <t_services.h>
#include <serial.h>
#include <hw_serial.h>
#include "kernel_id.h"

serial.cのインクルード依存関係図

ソースコードを見る。

データ構造

struct  serial_port_initialization_block
struct  serial_port_control_block

マクロ定義

#define SERIAL_BUFSZ   256
#define FC_STOP   '\023'
#define FC_START   '\021'
#define BUFCNT_STOP   (SERIAL_BUFSZ - 64)
#define BUFCNT_START   (SERIAL_BUFSZ - 128)
#define MAX_FLUSH_WAIT   1000
#define INDEX_PORT(portid)   ((UINT)((portid) - 1))
#define get_spcb(portid)   (&(spcb_table[INDEX_PORT(portid)]))
#define INC_PTR(ptr)   { if (++ptr == SERIAL_BUFSZ) ptr = 0; }
 ポインタのインクリメント

型定義

typedef serial_port_initialization_block SPINIB
typedef serial_port_control_block SPCB

関数

void serial_initialize (VP_INT exinf)
ER serial_opn_por (ID portid)
ER serial_cls_por (ID portid)
Inline BOOL serial_snd_chr (SPCB *spcb, char c)
static BOOL serial_wri_chr (SPCB *spcb, char c)
ER_UINT serial_wri_dat (ID portid, char *buf, UINT len)
static BOOL serial_rea_chr (SPCB *spcb, char *c)
ER_UINT serial_rea_dat (ID portid, char *buf, UINT len)
ER serial_ctl_por (ID portid, UINT ioctl)
ER serial_ref_por (ID portid, T_SERIAL_RPOR *pk_rpor)
void sio_ierdy_snd (VP_INT exinf)
void sio_ierdy_rcv (VP_INT exinf)

変数

static const SPINIB spinib_table [TNUM_PORT]
static SPCB spcb_table [TNUM_PORT]


説明

シリアルインタフェースドライバ

serial.c で定義されています。


マクロ定義

#define BUFCNT_START   (SERIAL_BUFSZ - 128)
 

serial.c58 行で定義されています。

参照元 serial_rea_chr().

#define BUFCNT_STOP   (SERIAL_BUFSZ - 64)
 

serial.c57 行で定義されています。

参照元 sio_ierdy_rcv().

#define FC_START   '\021'
 

serial.c55 行で定義されています。

参照元 serial_rea_chr()sio_ierdy_rcv().

#define FC_STOP   '\023'
 

serial.c54 行で定義されています。

参照元 sio_ierdy_rcv().

#define get_spcb portid   )     (&(spcb_table[INDEX_PORT(portid)]))
 

serial.c113 行で定義されています。

参照元 serial_cls_por()serial_ctl_por()serial_opn_por()serial_rea_dat()serial_ref_por()serial_wri_dat().

#define INC_PTR ptr   )     { if (++ptr == SERIAL_BUFSZ) ptr = 0; }
 

ポインタのインクリメント

serial.c118 行で定義されています。

参照元 serial_rea_chr()serial_wri_chr()sio_ierdy_rcv()sio_ierdy_snd().

#define INDEX_PORT portid   )     ((UINT)((portid) - 1))
 

serial.c112 行で定義されています。

#define MAX_FLUSH_WAIT   1000
 

serial.c63 行で定義されています。

#define SERIAL_BUFSZ   256
 

serial.c52 行で定義されています。

参照元 serial_wri_chr()sio_ierdy_rcv()sio_ierdy_snd().


型定義

typedef struct serial_port_control_block SPCB
 

typedef struct serial_port_initialization_block SPINIB
 


関数

ER serial_cls_por ID  portid  ) 
 

serial.c194 行で定義されています。

参照先 _syscallE_CTXE_IDE_OBJE_OKFALSEget_spcbloc_cpu()serial_port_control_block::openflagsio_cls_por()serial_port_control_block::siopcbsns_ctx()TNUM_PORTunl_cpu().

00195 {
00196     SPCB    *spcb;
00197     ER  ercd;
00198 
00199     if (sns_ctx()) {        /* コンテキストのチェック */
00200         return(E_CTX);
00201     }
00202     if (!(1 <= portid && portid <= TNUM_PORT)) {
00203         return(E_ID);       /* ポート番号のチェック */
00204     }
00205     spcb = get_spcb(portid);
00206 
00207     _syscall(loc_cpu());
00208     if (!(spcb->openflag)) {    /* オープン済みかのチェック */
00209         ercd = E_OBJ;
00210     }
00211     else {
00212         /*
00213          *  ハードウェア依存のクローズ処理
00214          */
00215         sio_cls_por(spcb->siopcb);
00216         spcb->openflag = FALSE;
00217         ercd = E_OK;
00218     }
00219     _syscall(unl_cpu());
00220     return(ercd);
00221 }

関数の呼び出しグラフ:

ER serial_ctl_por ID  portid,
UINT  ioctl
 

serial.c386 行で定義されています。

参照先 E_CTXE_IDE_OBJE_OKget_spcbserial_port_control_block::ioctlserial_port_control_block::openflagsns_ctx()TNUM_PORT.

参照元 main_task().

00387 {
00388     SPCB    *spcb;
00389 
00390     if (sns_ctx()) {        /* コンテキストのチェック */
00391         return(E_CTX);
00392     }
00393     if (!(1 <= portid && portid <= TNUM_PORT)) {
00394         return(E_ID);       /* ポート番号のチェック */
00395     }
00396 
00397     spcb = get_spcb(portid);
00398     if (!(spcb->openflag)) {    /* オープン済みかのチェック */
00399         return(E_OBJ);
00400     }
00401 
00402     spcb->ioctl = ioctl;
00403     return(E_OK);
00404 }

関数の呼び出しグラフ:

void serial_initialize VP_INT  exinf  ) 
 

serial.c124 行で定義されています。

参照先 FALSEserial_port_control_block::openflagsio_initializespcb_tableserial_port_control_block::spinibspinib_tableTNUM_PORT.

00125 {
00126     SPCB    *spcb;
00127     UINT    i;
00128 
00129     sio_initialize();
00130     for (spcb = spcb_table, i = 0; i < TNUM_PORT; spcb++, i++) {
00131         spcb->spinib = &(spinib_table[i]);
00132         spcb->openflag = FALSE;
00133     }
00134 }

ER serial_opn_por ID  portid  ) 
 

serial.c140 行で定義されています。

参照先 _syscallE_CTXE_IDE_OBJE_OKFALSEget_spcbserial_port_control_block::ioctlIOCTL_CRLFIOCTL_ECHOIOCTL_FCRCVIOCTL_FCSNDloc_cpu()serial_port_control_block::openflagserial_port_control_block::rcv_countserial_port_control_block::rcv_fc_chrserial_port_control_block::rcv_read_ptrserial_port_control_block::rcv_stoppedserial_port_control_block::rcv_write_ptrsio_ena_cbrSIO_ERDY_RCVsio_opn_por()serial_port_control_block::siopcbserial_port_control_block::snd_countserial_port_control_block::snd_read_ptrserial_port_control_block::snd_stoppedserial_port_control_block::snd_write_ptrsns_ctx()TNUM_PORTTRUEunl_cpu().

参照元 logtask().

00141 {
00142     SPCB    *spcb;
00143     ER  ercd;
00144 
00145     if (sns_ctx()) {        /* コンテキストのチェック */
00146         return(E_CTX);
00147     }
00148     if (!(1 <= portid && portid <= TNUM_PORT)) {
00149         return(E_ID);       /* ポート番号のチェック */
00150     }
00151     spcb = get_spcb(portid);
00152 
00153     _syscall(loc_cpu());
00154     if (spcb->openflag) {       /* オープン済みかのチェック */
00155         ercd = E_OBJ;
00156     }
00157     else {
00158         /*
00159          *  変数の初期化
00160          */
00161         spcb->ioctl = (IOCTL_ECHO | IOCTL_CRLF
00162                     | IOCTL_FCSND | IOCTL_FCRCV);
00163 
00164 
00165         spcb->rcv_read_ptr = spcb->rcv_write_ptr = 0;
00166         spcb->rcv_count = 0;
00167         spcb->rcv_fc_chr = '\0';
00168         spcb->rcv_stopped = FALSE;
00169 
00170         spcb->snd_read_ptr = spcb->snd_write_ptr = 0;
00171         spcb->snd_count = 0;
00172         spcb->snd_stopped = FALSE;
00173 
00174         /*
00175          *  ハードウェア依存のオープン処理
00176          */
00177         spcb->siopcb = sio_opn_por(portid, (VP_INT) spcb);
00178 
00179         /*
00180          *  受信通知コールバックを許可する.
00181          */
00182         sio_ena_cbr(spcb->siopcb, SIO_ERDY_RCV);
00183         spcb->openflag = TRUE;
00184         ercd = E_OK;
00185     }
00186     _syscall(unl_cpu());
00187     return(ercd);
00188 }

関数の呼び出しグラフ:

static BOOL serial_rea_chr SPCB spcb,
char *  c
[static]
 

serial.c313 行で定義されています。

参照先 _syscallBUFCNT_STARTFALSEFC_STARTINC_PTRserial_port_control_block::ioctlIOCTL_ECHOloc_cpu()serial_port_control_block::rcv_bufferserial_port_control_block::rcv_countserial_port_control_block::rcv_fc_chrserial_port_control_block::rcv_read_ptrserial_port_control_block::rcv_stoppedserial_snd_chr()serial_wri_chr()sig_sem()serial_port_initialization_block::snd_semidserial_port_control_block::spinibunl_cpu()wai_sem().

00314 {
00315     BOOL    buffer_empty;
00316 
00317     _syscall(loc_cpu());
00318 
00319     /*
00320      *  受信バッファから文字を取り出す.
00321      */
00322     *c = spcb->rcv_buffer[spcb->rcv_read_ptr];
00323     INC_PTR(spcb->rcv_read_ptr);
00324     spcb->rcv_count--;
00325     buffer_empty = (spcb->rcv_count == 0);
00326 
00327     /*
00328      *  START を送信する.
00329      */
00330     if (spcb->rcv_stopped && spcb->rcv_count <= BUFCNT_START) {
00331         if (!serial_snd_chr(spcb, FC_START)) {
00332             spcb->rcv_fc_chr = FC_START;
00333         }
00334         spcb->rcv_stopped = FALSE;
00335     }
00336     _syscall(unl_cpu());
00337 
00338     /*
00339      *  エコーバック処理.
00340      */
00341     if ((spcb->ioctl & IOCTL_ECHO) != 0) {
00342         _syscall(wai_sem(spcb->spinib->snd_semid));
00343         if (!serial_wri_chr(spcb, *c)) {
00344             _syscall(sig_sem(spcb->spinib->snd_semid));
00345         }
00346     }
00347     return(buffer_empty);
00348 }

関数の呼び出しグラフ:

ER_UINT serial_rea_dat ID  portid,
char *  buf,
UINT  len
 

serial.c351 行で定義されています。

参照先 _syscallE_CTXE_IDE_OBJget_spcbserial_port_control_block::openflagserial_port_initialization_block::rcv_semidsns_dpn()serial_port_control_block::spinibTNUM_PORTTRUEwai_sem().

参照元 main_task().

00352 {
00353     SPCB    *spcb;
00354     BOOL    buffer_empty;
00355     UINT    i;
00356 
00357     if (sns_dpn()) {        /* コンテキストのチェック */
00358         return(E_CTX);
00359     }
00360     if (!(1 <= portid && portid <= TNUM_PORT)) {
00361         return(E_ID);       /* ポート番号のチェック */
00362     }
00363 
00364     spcb = get_spcb(portid);
00365     if (!(spcb->openflag)) {    /* オープン済みかのチェック */
00366         return(E_OBJ);
00367     }
00368 
00369     buffer_empty = TRUE;        /* ループの1回めは wai_sem する */
00370     for (i = 0; i < len; i++) {
00371         if (buffer_empty) {
00372             _syscall(wai_sem(spcb->spinib->rcv_semid));
00373         }
00374         buffer_empty = serial_rea_chr(spcb, buf++);
00375     }
00376     if (!buffer_empty) {
00377         _syscall(sig_sem(spcb->spinib->rcv_semid));
00378     }
00379     return(len);
00380 }

関数の呼び出しグラフ:

ER serial_ref_por ID  portid,
T_SERIAL_RPOR pk_rpor
 

serial.c410 行で定義されています。

参照先 E_CTXE_IDE_OBJE_OKget_spcbserial_port_control_block::openflagserial_port_control_block::rcv_countT_SERIAL_RPOR::reacntserial_port_control_block::snd_countsns_ctx()TNUM_PORTT_SERIAL_RPOR::wricnt.

00411 {
00412     SPCB    *spcb;
00413 
00414     if (sns_ctx()) {        /* コンテキストのチェック */
00415         return(E_CTX);
00416     }
00417     if (!(1 <= portid && portid <= TNUM_PORT)) {
00418         return(E_ID);       /* ポート番号のチェック */
00419     }
00420 
00421     spcb = get_spcb(portid);
00422     if (!(spcb->openflag)) {    /* オープン済みかのチェック */
00423         return(E_OBJ);
00424     }
00425 
00426     pk_rpor->reacnt = spcb->rcv_count;
00427     pk_rpor->wricnt = spcb->snd_count;
00428     return(E_OK);
00429 }

関数の呼び出しグラフ:

Inline BOOL serial_snd_chr SPCB spcb,
char  c
 

serial.c227 行で定義されています。

参照先 FALSEsio_ena_cbrSIO_ERDY_SNDsio_snd_chrserial_port_control_block::siopcbTRUE.

参照元 serial_rea_chr()serial_wri_chr()sio_ierdy_rcv().

00228 {
00229     if (sio_snd_chr(spcb->siopcb, c)) {
00230         return(TRUE);
00231     }
00232     else {
00233         sio_ena_cbr(spcb->siopcb, SIO_ERDY_SND);
00234         return(FALSE);
00235     }
00236 }

static BOOL serial_wri_chr SPCB spcb,
char  c
[static]
 

serial.c242 行で定義されています。

参照先 _syscallFALSEINC_PTRserial_port_control_block::ioctlIOCTL_CRLFloc_cpu()SERIAL_BUFSZserial_snd_chr()serial_port_control_block::snd_bufferserial_port_control_block::snd_countserial_port_initialization_block::snd_semidserial_port_control_block::snd_stoppedserial_port_control_block::snd_write_ptrserial_port_control_block::spinibunl_cpu()wai_sem().

参照元 serial_rea_chr().

00243 {
00244     BOOL    buffer_full;
00245 
00246     /*
00247      *  LF の前に CR を送信する.
00248      */
00249     if (c == '\n' && (spcb->ioctl & IOCTL_CRLF) != 0) {
00250         if (serial_wri_chr(spcb, '\r')) {
00251             _syscall(wai_sem(spcb->spinib->snd_semid));
00252         }
00253     }
00254 
00255     _syscall(loc_cpu());
00256     if (spcb->snd_count == 0 && !(spcb->snd_stopped)
00257                 && serial_snd_chr(spcb, c)) {
00258         /*
00259          *  シリアルI/Oデバイスの送信レジスタに文字を入れるこ
00260          *  とに成功した場合.
00261          */
00262         buffer_full = FALSE;
00263     }
00264     else {
00265         /*
00266          *  送信バッファに文字を入れる.
00267          */
00268         spcb->snd_buffer[spcb->snd_write_ptr] = c;
00269         INC_PTR(spcb->snd_write_ptr);
00270         spcb->snd_count++;
00271         buffer_full = (spcb->snd_count == SERIAL_BUFSZ);
00272     }
00273     _syscall(unl_cpu());
00274     return(buffer_full);
00275 }

関数の呼び出しグラフ:

ER_UINT serial_wri_dat ID  portid,
char *  buf,
UINT  len
 

serial.c278 行で定義されています。

参照先 _syscallE_CTXE_IDE_OBJget_spcbserial_port_control_block::openflagserial_port_initialization_block::snd_semidsns_dpn()serial_port_control_block::spinibTNUM_PORTTRUEwai_sem().

参照元 logtask_putc().

00279 {
00280     SPCB    *spcb;
00281     BOOL    buffer_full;
00282     UINT    i;
00283 
00284     if (sns_dpn()) {        /* コンテキストのチェック */
00285         return(E_CTX);
00286     }
00287     if (!(1 <= portid && portid <= TNUM_PORT)) {
00288         return(E_ID);       /* ポート番号のチェック */
00289     }
00290 
00291     spcb = get_spcb(portid);
00292     if (!(spcb->openflag)) {    /* オープン済みかのチェック */
00293         return(E_OBJ);
00294     }
00295 
00296     buffer_full = TRUE;     /* ループの1回めは wai_sem する */
00297     for (i = 0; i < len; i++) {
00298         if (buffer_full) {
00299             _syscall(wai_sem(spcb->spinib->snd_semid));
00300         }
00301         buffer_full = serial_wri_chr(spcb, *buf++);
00302     }
00303     if (!buffer_full) {
00304         _syscall(sig_sem(spcb->spinib->snd_semid));
00305     }
00306     return(len);
00307 }

関数の呼び出しグラフ:

void sio_ierdy_rcv VP_INT  exinf  ) 
 

serial.c472 行で定義されています。

参照先 _syscallBUFCNT_STOPFALSEFC_STARTFC_STOPINC_PTRserial_port_control_block::ioctlIOCTL_FCANYIOCTL_FCRCVIOCTL_FCSNDisig_sem()serial_port_control_block::rcv_bufferserial_port_control_block::rcv_countserial_port_control_block::rcv_fc_chrserial_port_initialization_block::rcv_semidserial_port_control_block::rcv_stoppedserial_port_control_block::rcv_write_ptrSERIAL_BUFSZserial_snd_chr()sio_rcv_chrserial_port_control_block::siopcbserial_port_control_block::snd_bufferserial_port_control_block::snd_countserial_port_control_block::snd_read_ptrserial_port_initialization_block::snd_semidserial_port_control_block::snd_stoppedserial_port_control_block::spinibTRUE.

00473 {
00474     SPCB    *spcb;
00475     char    c;
00476 
00477     spcb = (SPCB *) exinf;
00478     c = (char) sio_rcv_chr(spcb->siopcb);
00479     if ((spcb->ioctl & IOCTL_FCSND) != 0 && c == FC_STOP) {
00480         /*
00481          *  送信を一時停止する.送信中の文字はそのまま送信する.
00482          */
00483         spcb->snd_stopped = TRUE;
00484     }
00485     else if (spcb->snd_stopped && (c == FC_START
00486                 || (spcb->ioctl & IOCTL_FCANY) != 0)) {
00487         /*
00488          *  送信を再開する.
00489          */
00490         spcb->snd_stopped = FALSE;
00491         if (spcb->snd_count > 0) {
00492             c = spcb->snd_buffer[spcb->snd_read_ptr];
00493             if (serial_snd_chr(spcb, c)) {
00494                 INC_PTR(spcb->snd_read_ptr);
00495                 if (spcb->snd_count == SERIAL_BUFSZ) {
00496                     _syscall(isig_sem(spcb->spinib
00497                                 ->snd_semid));
00498                 }
00499                 spcb->snd_count--;
00500             }
00501         }
00502     }
00503     else if ((spcb->ioctl & IOCTL_FCSND) != 0 && c == FC_START) {
00504         /*
00505          *  送信に対してフロー制御している場合,START は捨てる.
00506          */
00507     }
00508     else if (spcb->rcv_count == SERIAL_BUFSZ) {
00509         /*
00510          *  バッファフルの場合,受信した文字を捨てる.
00511          */
00512     }
00513     else {
00514         /*
00515          *  受信した文字を受信バッファに入れる.
00516          */
00517         spcb->rcv_buffer[spcb->rcv_write_ptr] = c;
00518         INC_PTR(spcb->rcv_write_ptr);
00519         if (spcb->rcv_count == 0) {
00520             _syscall(isig_sem(spcb->spinib->rcv_semid));
00521         }
00522         spcb->rcv_count++;
00523 
00524         /*
00525          *  STOP を送信する.
00526          */
00527         if ((spcb->ioctl & IOCTL_FCRCV) != 0 && !(spcb->rcv_stopped)
00528                     && (spcb->rcv_count >= BUFCNT_STOP)) {
00529             if (!serial_snd_chr(spcb, FC_STOP)) {
00530                 spcb->rcv_fc_chr = FC_STOP;
00531             }
00532             spcb->rcv_stopped = TRUE;
00533         }
00534     }
00535 }

関数の呼び出しグラフ:

void sio_ierdy_snd VP_INT  exinf  ) 
 

serial.c435 行で定義されています。

参照先 _syscallINC_PTRisig_sem()serial_port_control_block::rcv_fc_chrSERIAL_BUFSZsio_dis_cbrSIO_ERDY_SNDsio_snd_chrserial_port_control_block::siopcbserial_port_control_block::snd_bufferserial_port_control_block::snd_countserial_port_control_block::snd_read_ptrserial_port_initialization_block::snd_semidserial_port_control_block::snd_stoppedserial_port_control_block::spinib.

00436 {
00437     SPCB    *spcb;
00438 
00439     spcb = (SPCB *) exinf;
00440     if (spcb->rcv_fc_chr != '\0') {
00441         /*
00442          *  START/STOP を送信する.
00443          */
00444         (void) sio_snd_chr(spcb->siopcb, spcb->rcv_fc_chr);
00445         spcb->rcv_fc_chr = '\0';
00446     }
00447     else if (!(spcb->snd_stopped) && spcb->snd_count > 0) {
00448         /*
00449          *  送信バッファ中から文字を取り出して送信する.
00450          */
00451         (void) sio_snd_chr(spcb->siopcb,
00452                 spcb->snd_buffer[spcb->snd_read_ptr]);
00453         INC_PTR(spcb->snd_read_ptr);
00454         if (spcb->snd_count == SERIAL_BUFSZ) {
00455             _syscall(isig_sem(spcb->spinib->snd_semid));
00456         }
00457         spcb->snd_count--;
00458     }
00459     else {
00460         /*
00461          *  送信すべき文字がない場合は,送信可能コールバックを
00462          *  禁止する.
00463          */
00464         sio_dis_cbr(spcb->siopcb, SIO_ERDY_SND);
00465     }
00466 }

関数の呼び出しグラフ:


変数

SPCB spcb_table[TNUM_PORT] [static]
 

serial.c107 行で定義されています。

参照元 serial_initialize().

const SPINIB spinib_table[TNUM_PORT] [static]
 

初期値:

 {
    { SERIAL_RCV_SEM1, SERIAL_SND_SEM1 }






}

serial.c73 行で定義されています。

参照元 serial_initialize().


Copyright © 2006 by TAKAGI Nobuhisa.
このページは Mon Apr 3 23:49:18 2006 に Doxygen によって生成されました。