⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serpkt.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*-C-*- * * $Revision: 1.6.6.7 $ *   $Author: rivimey $ *     $Date: 1998/03/21 22:54:10 $ * * Copyright (c) 1996 Advanced RISC Machines Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: High-level packet-based device driver for serial (or similar) *              devices.  Interfaces to low-level drivers via serring.h. */#include "devdriv.h"            /* device driver support */#include "rxtx.h"               /* rx/tx packet engines */#include "logging.h"#include "serring.h"/* General purpose constants, macros, enums, typedefs *//* Publically-accessible globals */static unsigned long spk_rx_numpackets = 0;static unsigned long spk_rx_numbadpackets = 0;static unsigned long spk_rx_numdrops = 0;static unsigned long spk_rx_numbytes = 0;static unsigned long spk_tx_numpackets = 0;static unsigned long spk_tx_numdrops = 0;static unsigned long spk_tx_numbytes = 0;struct StatInfo spk_stat_info[] ={    "Serpkt Stats:\n"    " Transmit\n"    "  NumPackets          %4d\n", &spk_tx_numpackets,    "  NumPackets Dropped  %4d\n", &spk_tx_numdrops,    "  Number of Bytes     %4d\n", &spk_tx_numbytes,    "\n"    " Receive\n"    "  NumPackets          %4d\n", &spk_rx_numpackets,    "  NumPackets Bad      %4d\n", &spk_rx_numbadpackets,    "  NumPackets Dropped  %4d\n", &spk_rx_numdrops,    "  Number of Bytes     %4d\n", &spk_rx_numbytes,    NULL, NULL};/* Private globals *//* none *//* *  Function: serpkt_fill_tx_ring *   Purpose: Fill ups a transmit ring buffer from the Tx engine * *  Pre-conditions: Interrupts should be disabled * *    Params: *       Input: devid   device ID of the driver * *      In/Out: ring    the ring buffer to be filled * *   Returns: Nothing */static void serpkt_fill_tx_ring(const DeviceID devid,                    RingBuffer * const ring){    volatile unsigned int *const status = angel_DeviceStatus + devid;    unsigned int eod = *status & SER_TX_EOD; /* not bool -- it's a bitmask */    /*     * loop while data left to send and the buffer has space left     */    while ((eod == 0) && !ringBufFull(ring))    {        te_status tx_status;        unsigned char new_ch;//        unsigned int s;        /*         * This task is running as AngelCallback priority so it can         * be interrupted. If a heartbeat arrives which needs to write         * an acknowledge, the interrupting heartbeat task will never         * terminate (because we're busy); the result is deadlock.         *         * Interim Solution: Don't let the interrupt happen!         */        /* s = Angel_EnableInterruptsFromSVC(); */        tx_status = Angel_TxEngine(SerEngine(devid)->tx_packet,                                   SerEngine(devid)->te_state,                                   &new_ch);        /* Angel_RestoreInterruptsFromSVC(s); */        switch (tx_status)        {            case TS_DONE_PKT:                eod = TRUE;                spk_tx_numpackets++;                /* and FALL THROUGH TO */            case TS_IN_PKT:#if DEBUG == 1                {                    static int count = 0;                    LogInfo(LOG_WIRE, (">%02X ", new_ch));                    if (++count > 16)                    {                        LogInfo(LOG_WIRE, ("\n"));                        count = 0;                    }                }#endif                ringBufPutChar(ring, new_ch);                spk_tx_numbytes++;                break;            case TS_IDLE:                LogWarning(LOG_SERPKT, ( "TS_IDLE in fill_ring\n"));                break;                            default:                LogError(LOG_SERPKT, ( "Unknown status in fill_ring\n"));                break;        }    }    if (eod)        *status |= SER_TX_EOD;    /*     * if ring buffer was empty when we started filling it, then     * we need to kick start the first character     */	  #ifdef NEVER    if ((*status & SER_TX_KICKSTART) != 0)    {        *status |= SER_TX_DATA;        *status &= ~SER_TX_KICKSTART;        SerCtrl(devid)->control_tx(devid);        SerCtrl(devid)->kick_start(devid);    }#endif	SerCtrl(devid)->kick_start(devid);}/* *  Function: serpkt_AsyncWrite *   Purpose: Entry point for asynchronous writes to the serial device. *            See documentation for angel_DeviceWrite in devdriv.h */DevError serpkt_AsyncWrite(DeviceID devid, p_Buffer buffer,                  unsigned int length, DevChanID devchan){    struct data_packet *const txp = SerEngine(devid)->tx_packet;    RingBuffer *ring = SerCtrl(devid)->tx_ring;    txp->len = length;    txp->type = devchan;    txp->data = buffer;    Angel_TxEngineInit(SerEngine(devid)->config, txp,                       SerEngine(devid)->te_state);    /* need to protect this bit */    Angel_EnterSVC();    angel_DeviceStatus[devid] |= SER_TX_KICKSTART;    serpkt_fill_tx_ring(devid, ring);    Angel_ExitToUSR();    LogInfo(LOG_SERPKT, ( "serpkt_AsyncWrite OK\n"));    return DE_OKAY;}/* *  Function: serpkt_RegisterRead *   Purpose: Entry point for asynchronous reads from the serial device. *            See documentation for angel_RegisterRead in devdriv.h */DevError serpkt_RegisterRead(DeviceID devid, DevChanID devchan){    struct data_packet *const rxp = SerEngine(devid)->rx_packet;    IGNORE(devchan);    LogInfo(LOG_SERPKT, ( "serpkt_RegisterRead\n"));    Angel_EnterSVC();    rxp->data = NULL;           /* gets set in callback later on */    rxp->type = DC_NUM_CHANNELS;  /* invalid */    SerCtrl(devid)->control_rx(devid);    Angel_ExitToUSR();    return DE_OKAY;}/* *  Function: serpkt_reset *   Purpose: Reset a serial port * *    Params: *       Input: devid   device ID of the driver * *   Returns: DE_OKAY */static DevError serpkt_reset(const DeviceID devid){    Angel_RxEngineInit(SerEngine(devid)->config, SerEngine(devid)->re_state);    /* get low-level control to do the rest */    return SerCtrl(devid)->control(devid, DC_RESET, NULL);}/* *  Function: serpkt_rxflow *   Purpose:  *             */static DevError serpkt_rxflow(DeviceID devid, void *v_arg){    int oldarg;    int arg = (int)v_arg;        LogWarning(LOG_SERPKT, ( "serpkt_rxflow: dev %d arg %x\n", devid, arg));        /*     * arg == 0: no packets allowed;     * arg > 0: normal processing     * arg < 0: allow (-arg) packets (delivered) before disabling flow     * Note: delivered packets exclude bad packets!     */    if (SerCtrl(devid)->rx_tx_state != NULL)    {        oldarg = SerCtrl(devid)->rx_tx_state->rx_pkt_flow;        SerCtrl(devid)->rx_tx_state->rx_pkt_flow = (int)arg;        /* This code is (I think ) only relevant in a system which can         * handle multiple tasks... if in minimal angel, therefore,         * just ignore it.         *         * ... I may be wrong!  RIC 1/98         */#if !defined(MINIMAL_ANGEL) || MINIMAL_ANGEL == 0                /* restart the rx engine if it was stopped */        if (arg > 0 && oldarg == 0)        {            volatile unsigned int *const status = angel_DeviceStatus + devid;            if ((*status & SER_RX_QUEUED) == 0)            {                int s;                                *status |= SER_RX_QUEUED;                                /* allow pending ints to be processed... */                s = Angel_EnableInterruptsFromSVC();                Angel_RestoreInterruptsFromSVC(s);                                LogWarning(LOG_SERPKT, ( "serpkt_rxflow: Queue rx_processing.\n"));                /*                 * This is what is wanted, but it can't be done here and now;                 * if a packet were delivered as a result, we would end up                 * reentering code which isn't reentrant!                 *                 * SerCtrl(devid)->rx_processing((void*)devid);                 */                                Angel_QueueCallback((angel_CallbackFn)SerCtrl(devid)->rx_processing,                                    TP_AngelWantLock,                                    (void *)devid, 0, 0, 0);            }            else                LogWarning(LOG_SERPKT, ( "serpkt_rxflow: still running\n"));        }#endif    }        /* get low-level control to do the rest */    return SerCtrl(devid)->control(devid, DC_RX_PACKET_FLOW, v_arg);}/* *  Function: serpkt_Control *   Purpose: Entry point for device control functions *            See documentation for angel_DeviceControl in devdriv.h */DevError serpkt_Control(DeviceID devid,               DeviceControl op,               void *arg){    DevError ret_code;    LogInfo(LOG_SERPKT, ( "serpkt_Control: dev %d, op %d arg %x\n", devid, op, arg));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -