Ignore:
Timestamp:
May 22, 2019, 4:09:18 PM (5 years ago)
Author:
coas-nagasima
Message:

ファイルディスクリプタ処理を更新

File:
1 edited

Legend:

Unmodified
Added
Removed
  • asp3_tinet_ecnl_rx/trunk/asp3_dcre/target/gr_citrus_gcc/target_serial.c

    r374 r387  
    33 *      Toyohashi Open Platform for Embedded Real-Time Systems/
    44 *      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) 2003-2004 by Naoki Saito
    9  *             Nagoya Municipal Industrial Research Institute, JAPAN
    10  *  Copyright (C) 2003-2004 by Platform Development Center
    11  *                                          RICOH COMPANY,LTD. JAPAN
    12  *  Copyright (C) 2008-2010 by Witz Corporation, JAPAN
    13  *  Copyright (C) 2013      by Mitsuhiro Matsuura
    14  *
     5 *
     6 *  Copyright (C) 2006-2018 by Embedded and Real-Time Systems Laboratory
     7 *              Graduate School of Information Science, Nagoya Univ., JAPAN
     8 *
    159 *  上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
    1610 *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
     
    3529 *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
    3630 *      免責すること.
    37  *
     31 * 
    3832 *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
    3933 *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
     
    4135 *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
    4236 *  の責任を負わない.
    43  *
     37 * 
    4438 *  @(#) $Id$
    4539 */
    4640
    4741/*
    48  *      RX630 UART用シリアルI/Oモジュール
    49  */
    50 #include "kernel_impl.h"
    51 #include <sil.h>
     42 *              シリアルインタフェースドライバのターゲット依存部(GR-CITRUS用)
     43 */
     44
     45#include "gr_citrus.h"
     46#include <t_stddef.h>
     47#include <t_syslog.h>
     48#include <errno.h>
     49#include <unistd.h>
     50#include <fcntl.h>
     51#include <termios.h>
    5252#include "target_serial.h"
    53 #include "hal/serial_api.h"
    54 #include "target_syssvc.h"
    55 #include "syssvc/serial.h"
    56 
    57 /*
    58  *  シリアルI/Oポート初期化ブロックの定義
     53#include "syssvc/siofd.h"
     54
     55/*
     56 *  SIOポート初期化ブロックの定義
    5957 */
    6058typedef struct sio_port_initialization_block {
    61         PinName tx;
    62         PinName rx;
     59        char            *path;                  /* ファイルのパス名 */
    6360} SIOPINIB;
    6461
    6562/*
    66  *  シリアルI/Oポート管理ブロックの定義
     63 *  SIOポート管理ブロックの定義
    6764 */
    6865struct sio_port_control_block {
    69         const SIOPINIB *p_siopinib;
    70         intptr_t exinf;
    71         bool_t openflag;
    72         serial_t serial;
     66        const SIOPINIB *p_siopinib;     /* SIOポート初期化ブロック */
     67        intptr_t        exinf;                  /* 拡張情報 */
     68        bool_t          opened;         /* オープン済みフラグ */
     69        struct termios saved_term;      /* 元の端末制御情報 */
     70
     71        int_t           read_fd;                /* 読出し用ファイルディスクリプタ */
     72        bool_t          rcv_flag;               /* 受信文字バッファ有効フラグ */
     73        char            rcv_buf;                /* 受信文字バッファ */
     74        bool_t          rcv_rdy;                /* 受信通知コールバック許可フラグ */
     75
     76        int_t           write_fd;               /* 書込み用ファイルディスクリプタ */
     77        bool_t          snd_flag;               /* 送信文字バッファ有効フラグ */
     78        char            snd_buf;                /* 送信文字バッファ */
     79        bool_t          snd_rdy;                /* 送信通知コールバック許可フラグ */
    7380};
    7481
    7582/*
    76  *  シリアルI/Oポート管理ブロックのエリア
    77  */
    78 SIOPCB siopcb_table[TNUM_PORT];
    79 
    80 static const SIOPINIB siopinib_table[TNUM_SIOP] =
    81 {
    82         { P20, P21 },
    83 #if TNUM_SIOP > 1
    84         { P50, P52 },
    85 #endif
    86 #if TNUM_SIOP > 2
    87         { P32, P33 },
    88 #endif
    89 #if TNUM_SIOP > 3
    90         { PC7, PC6 },
    91 #endif
    92 #if TNUM_SIOP > 4
    93         { P26, P30 },
    94 #endif
    95 #if TNUM_SIOP > 5
    96         { PB5, P25 },
    97 #endif
    98 #if TNUM_SIOP > 6
    99         { PA0, PC2 },
    100 #endif
     83 *  SIOポート初期化ブロック
     84 */
     85const SIOPINIB siopinib_table[TNUM_SIOP] = {
     86        { NULL }
    10187};
    10288
    10389/*
    104  *  シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
    105  */
    106 #define INDEX_SIOP(siopid)       ((uint_t)((siopid) - 1))
    107 #define get_siopcb(siopid)       (&(siopcb_table[INDEX_SIOP(siopid)]))
    108 #define get_siopinib(siopid) (&(siopinib_table[INDEX_SIOP(siopid)]))
    109 
    110 static void mbed_serial_irq_handler(uint32_t id, SerialIrq event);
     90 *  SIOポート管理ブロックのエリア
     91 */
     92SIOPCB  siopcb_table[TNUM_SIOP];
     93
     94/*
     95 *  SIOポートIDから管理ブロックを取り出すためのマクロ
     96 */
     97#define INDEX_SIOP(siopid)      ((uint_t)((siopid) - 1))
     98#define get_siopcb(siopid)      (&(siopcb_table[INDEX_SIOP(siopid)]))
    11199
    112100/*
     
    120108
    121109        /*
    122          *  シリアルI/Oポート管理ブロックの初期化
     110         *  SIOポート管理ブロックの初期化
    123111         */
    124         for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) {
     112        for (i = 0; i < TNUM_SIOP; i++) {
     113                p_siopcb = &(siopcb_table[i]);
    125114                p_siopcb->p_siopinib = &(siopinib_table[i]);
    126                 p_siopcb->openflag = false;
    127         }
    128 }
    129 
    130 /*
    131  *  シリアルI/Oポートのオープン
     115                p_siopcb->opened = false;
     116        }
     117}
     118
     119/*
     120 *  SIOドライバの終了処理
     121 */
     122void
     123sio_terminate(intptr_t exinf)
     124{
     125        uint_t  i;
     126
     127        /*
     128         *  オープンされているSIOポートのクローズ
     129         */
     130        for (i = 0; i < TNUM_SIOP; i++) {
     131                sio_cls_por(&(siopcb_table[i]));
     132        }
     133}
     134
     135/*
     136 *  SIOポートのオープン
    132137 */
    133138SIOPCB *
    134139sio_opn_por(ID siopid, intptr_t exinf)
    135140{
    136         SIOPCB  *p_siopcb = NULL;
    137         ER      ercd;
    138         serial_t *serial;
    139 
    140         if ((siopid <= 0) || (siopid > (sizeof(siopcb_table) / sizeof(siopcb_table[0]))))
    141                 return NULL;
     141        SIOPCB                  *p_siopcb;
     142        const SIOPINIB  *p_siopinib;
     143        int_t                   fd;
     144        struct termios  term;
     145
    142146        p_siopcb = get_siopcb(siopid);
    143 
    144         if (p_siopcb->openflag)
    145                 return NULL;
    146         p_siopcb->openflag = true;
    147         p_siopcb->exinf = exinf;
    148 
    149         serial = &p_siopcb->serial;
    150         serial_init(serial, p_siopcb->p_siopinib->tx, p_siopcb->p_siopinib->rx);
    151         serial_baud(serial, UART_BAUDRATE);
    152         serial_format(serial, 8, ParityNone, 1);
    153 
    154         serial_irq_handler(serial, mbed_serial_irq_handler, siopid);
    155 
    156         return p_siopcb;
    157 }
    158 
    159 /*
    160  *  シリアルI/Oポートのクローズ
     147        p_siopinib = p_siopcb->p_siopinib;
     148
     149        if (!(p_siopcb->opened)) {
     150                if (p_siopinib->path != NULL) {
     151                        fd = siofd_open(p_siopinib->path, O_RDWR, 0777);
     152                        assert(fd >= 0);
     153                        p_siopcb->read_fd = fd;
     154                        p_siopcb->write_fd = fd;
     155                }
     156                else {
     157                        fd = STDIN_FILENO;                                      /* 標準入出力を使う */
     158                        p_siopcb->read_fd = STDIN_FILENO;
     159                        p_siopcb->write_fd = STDOUT_FILENO;
     160                }
     161                siofd_fcntl(fd, F_SETOWN, getpid());
     162                siofd_fcntl(fd, F_SETFL, (O_NONBLOCK | O_ASYNC));
     163
     164                siofd_tcgetattr(fd, &(p_siopcb->saved_term));
     165                term = p_siopcb->saved_term;
     166                term.c_lflag &= ~(ECHO | ICANON);
     167                siofd_tcsetattr(fd, TCSAFLUSH, &term);
     168
     169                p_siopcb->exinf = exinf;
     170                p_siopcb->rcv_flag = false;
     171                p_siopcb->rcv_rdy = false;
     172                p_siopcb->snd_flag = false;
     173                p_siopcb->snd_rdy = false;
     174                p_siopcb->opened = true;
     175        }
     176        return(p_siopcb);
     177}
     178
     179/*
     180 *  SIOポートのクローズ
    161181 */
    162182void
    163183sio_cls_por(SIOPCB *p_siopcb)
    164184{
    165         ER        ercd;
    166         serial_t *serial = &p_siopcb->serial;
    167 
    168         /*
    169          *  デバイス依存のクローズ処理.
    170          */
    171         serial_free(serial);
    172         p_siopcb->openflag = false;
    173 }
    174 
    175 /*
    176  *  シリアルI/Oポートへの文字送信
     185        int_t   fd;
     186
     187        if (p_siopcb->opened) {
     188                fd = p_siopcb->read_fd;
     189                siofd_tcsetattr(fd, TCSAFLUSH, &(p_siopcb->saved_term));
     190                siofd_fcntl(fd, F_SETFL, 0);
     191
     192                if (p_siopcb->p_siopinib->path != NULL) {
     193                        siofd_close(p_siopcb->read_fd);
     194                }
     195
     196                p_siopcb->opened = false;
     197        }
     198}
     199
     200/*
     201 *  SIOの割込みサービスルーチン
     202 */
     203bool_t
     204sio_isr_snd(ID siopid)
     205{
     206        SIOPCB  *p_siopcb = get_siopcb(siopid);
     207        int_t   n;
     208
     209        if (p_siopcb->snd_flag) {
     210                if ((n = siofd_write(p_siopcb->write_fd, &(p_siopcb->snd_buf), 1)) > 0) {
     211                        p_siopcb->snd_flag = false;
     212                        if (p_siopcb->snd_rdy) {
     213                                sio_irdy_snd(p_siopcb->exinf);
     214                                return p_siopcb->snd_rdy;
     215                        }
     216                }
     217        }
     218
     219        return false;
     220}
     221
     222/*
     223 *  SIOの割込みサービスルーチン
     224 */
     225bool_t
     226sio_isr_rcv(ID siopid, char c)
     227{
     228        SIOPCB  *p_siopcb = get_siopcb(siopid);
     229
     230        if (!p_siopcb->rcv_flag) {
     231                p_siopcb->rcv_buf = c;
     232                p_siopcb->rcv_flag = true;
     233                if (p_siopcb->rcv_rdy) {
     234                        sio_irdy_rcv(p_siopcb->exinf);
     235                        return p_siopcb->rcv_rdy;
     236                }
     237        }
     238
     239        return false;
     240}
     241
     242/*
     243 *  SIOポートへの文字送信
    177244 */
    178245bool_t
    179246sio_snd_chr(SIOPCB *p_siopcb, char c)
    180247{
    181         serial_t *serial = &p_siopcb->serial;
    182         if (!serial_writable(serial))
    183                 return false;
    184         serial_putc(serial, c);
    185         return true;
    186 }
    187 
    188 /*
    189  *  シリアルI/Oポートからの文字受信
     248        int_t   n;
     249
     250        if (!p_siopcb->snd_flag) {
     251                if ((n = siofd_write(p_siopcb->write_fd, &c, 1)) > 0) {
     252                        return(true);
     253                }
     254                else {
     255                        assert(n < 0 && errno == EAGAIN);
     256                        p_siopcb->snd_flag = true;
     257                        p_siopcb->snd_buf = c;
     258                        return(true);
     259                }
     260        }
     261        else {
     262                return(false);
     263        }
     264}
     265
     266/*
     267 *  SIOポートからの文字受信
    190268 */
    191269int_t
    192270sio_rcv_chr(SIOPCB *p_siopcb)
    193271{
    194         serial_t *serial = &p_siopcb->serial;
    195         if (!serial_readable(serial))
    196                 return -1;
    197         return serial_getc(serial);
    198 }
    199 
    200 /*
    201  *  シリアルI/Oポートからのコールバックの許可
     272        char    c;
     273        int_t   n;
     274
     275        if (p_siopcb->rcv_flag) {
     276                p_siopcb->rcv_flag = false;
     277                return((int_t)(uint8_t)(p_siopcb->rcv_buf));
     278        }
     279        else if ((n = siofd_read(p_siopcb->read_fd, &c, 1)) > 0) {
     280                return((int_t)(uint8_t) c);
     281        }
     282        else {
     283                assert(n < 0 && errno == EAGAIN);
     284                return(-1);
     285        }
     286}
     287
     288/*
     289 *  SIOポートからのコールバックの許可
    202290 */
    203291void
    204292sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
    205293{
    206         serial_t *serial = &p_siopcb->serial;
    207294        switch (cbrtn) {
    208295        case SIO_RDY_SND:
    209                 serial_irq_set(serial, TxIrq, true);
     296                p_siopcb->snd_rdy = true;
    210297                break;
    211298        case SIO_RDY_RCV:
    212                 serial_irq_set(serial, RxIrq, true);
     299                p_siopcb->rcv_rdy = true;
    213300                break;
    214301        }
     
    216303
    217304/*
    218  *  シリアルI/Oポートからのコールバックの禁止
     305 *  SIOポートからのコールバックの禁止
    219306 */
    220307void
    221308sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
    222309{
    223         serial_t *serial = &p_siopcb->serial;
    224310        switch (cbrtn) {
    225311        case SIO_RDY_SND:
    226                 serial_irq_set(serial, TxIrq, false);
     312                p_siopcb->snd_rdy = false;
    227313                break;
    228314        case SIO_RDY_RCV:
    229                 serial_irq_set(serial, RxIrq, false);
     315                p_siopcb->rcv_rdy = false;
    230316                break;
    231317        }
    232318}
    233 
    234 /*
    235  *  シリアルI/Oポートからの送信可能コールバック
    236  */
    237 void
    238 serial_irdy_snd(SIOPCB  *p_siopcb)
    239 {
    240         /* 共通部(syssvc\serial.c)にあるsio_irdy_snd関数を呼び出し*/
    241         sio_irdy_snd(p_siopcb->exinf);
    242 }
    243 
    244 /*
    245  *  シリアルI/Oポートからの受信通知コールバック
    246  */
    247 void
    248 serial_irdy_rcv(SIOPCB  *p_siopcb)
    249 {
    250         /* 共通部(syssvc\serial.c)にあるsio_irdy_rcv関数を呼び出し*/
    251         sio_irdy_rcv(p_siopcb->exinf);
    252 }
    253 
    254 /*
    255  *  SIOの割込みハンドラ
    256  */
    257 void
    258 mbed_serial_irq_handler(uint32_t siopid, SerialIrq event)
    259 {
    260         SIOPCB  *p_siopcb;
    261 
    262         if ((siopid <= 0) || (siopid > (sizeof(siopcb_table) / sizeof(siopcb_table[0]))))
    263                 return;
    264         p_siopcb = get_siopcb(siopid);
    265 
    266         if (!p_siopcb->openflag)
    267                 return;
    268 
    269         switch (event) {
    270         case TxIrq:
    271                 serial_irdy_snd(p_siopcb);
    272                 break;
    273         case RxIrq:
    274                 serial_irdy_rcv(p_siopcb);
    275                 break;
    276         }
    277 }
Note: See TracChangeset for help on using the changeset viewer.