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

📄 serpkt.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
    Angel_EnterSVC();    /* we only implement the special cases here */    switch (op)    {        case DC_INIT:            if (SerCtrl(devid)->rx_tx_state)                SerCtrl(devid)->rx_tx_state->rx_pkt_flow = 1;            ret_code = SerCtrl(devid)->control(devid, op, arg);            break;                    case DC_RESET:            ret_code = serpkt_reset(devid);            break;        case DC_RX_PACKET_FLOW:            ret_code = serpkt_rxflow(devid, arg);            break;                    default:            /* all others passed through */            ret_code = SerCtrl(devid)->control(devid, op, arg);            break;    }    Angel_ExitToUSR();    return ret_code;}/* *  Function: serpkt_int_rx_processing *   Purpose: Deferred Rx processing for interrupt handler * *    Params: (via args) *       Input: devid           device ID of the driver * *   Returns: Nothing */void serpkt_int_rx_processing(void *args){    const DeviceID devid = (DeviceID) args;    RingBuffer *ring = SerCtrl(devid)->rx_ring;    volatile int *rx_flow = &(SerCtrl(devid)->rx_tx_state->rx_pkt_flow);    volatile unsigned int *status = angel_DeviceStatus + devid;    struct data_packet *rxp = SerEngine(devid)->rx_packet;    unsigned int s;        ASSERT(devid < DI_NUM_DEVICES, ("devid"));    LogInfo(LOG_RX, ("Entry: count = %d\n", ringBufCount(ring)));        /*      * We need to disable IRQ & FIQ whenever we modify critical data      * shared with the interrupt handler     */    s = Angel_DisableInterruptsFromSVC();    /*     * If there are characters in the rx ring buffer, process them     * through the rx engine and take appropriate action.     */    while (ringBufNotEmpty(ring))    {        re_status rx_eng_status;        unsigned char new_ch;        unsigned char overrun;        /* if we've been stopped, get out*/        if (*rx_flow == 0)        {            LogWarning(LOG_RX, ("Packet processing postponed; rx_flow == 0, ring->count = %d\n",                                ringBufCount(ring)));            break;        }                overrun = ringBufIsOvr(ring);        if (overrun)        {            LogWarning(LOG_RX, ("Character Overflow detected, ring->count = %d\n",                                ringBufCount(ring)));            ringBufResetOvr(ring);        }        new_ch = ringBufGetChar(ring);        Angel_RestoreInterruptsFromSVC(s);#if DEBUG == 1  /* don't want 'count' maintained in release versions */        {            static int count = 0;            LogInfo(LOG_WIRE, ("<%02X ", new_ch));            if (++count > 16)            {                LogInfo(LOG_WIRE, ("\n"));                count = 0;            }        }#endif                rx_eng_status = Angel_RxEngine(new_ch, overrun, rxp,                                       SerEngine(devid)->re_state);        switch (rx_eng_status)        {            case RS_WAIT_PKT:            case RS_IN_PKT:                /* we've done all we need within the engine */                break;            case RS_BAD_PKT:                /* tell the channels layer about a bad packet */                spk_rx_numbadpackets++;                                if (rxp->type < DC_NUM_CHANNELS)                {                    LogWarning(LOG_SERPKT, ( "Bad packet: Chan %d; delivering...\n", rxp->type));                            angel_DD_GotPacket(devid, rxp->data,                                       rxp->len, DS_BAD_PACKET,                                       rxp->type);                }                else                {                    LogWarning(LOG_SERPKT, ( "Bad packet: can't deliver...\n"));                    /*                     * we assume that if type is bad, no storage has been                     * allocated in the engine, so just do this to be safe:                     */                    if (rxp->data != NULL)                    {                        LogInfo(LOG_SERPKT, ("Bad packet's data non-null, freeing..."));                        Angel_BufferRelease(rxp->data);                    }                    spk_rx_numdrops++;                }                /* I think now bad packets shouldn't count towards incrementing the                 * flow; when the flow is set negative, we are really saying "let this                 * many _good_ packets through.                 *                  * if (*rx_flow < 0)                 *  (*rx_flow)++;                 */                rxp->data = NULL;                rxp->type = DC_NUM_CHANNELS;                break;                            case RS_NO_BUF:                LogWarning(LOG_SERPKT, ( "No buffer available: can't deliver...\n"));                spk_rx_numdrops++;                                /*                 * See msg above.                  * if (*rx_flow < 0)                 *  (*rx_flow)++;                 */                /*                 * We've done all we can do within the engine. Don't                 * try to deliver this; it can cause havoc with task                 * priorities and anyway there's little point... ric                 */                rxp->data = NULL;                rxp->type = DC_NUM_CHANNELS;  /* invalid */                break;            case RS_GOOD_PKT:                spk_rx_numbytes += rxp->len;                spk_rx_numpackets ++;                                if (*rx_flow < 0)                    (*rx_flow)++;                                LogInfo(LOG_SERPKT, ( "Delivering good packet:\n"));                                angel_DD_GotPacket(devid, rxp->data, rxp->len,                                   DS_DONE, rxp->type);                rxp->data = NULL;                rxp->type = DC_NUM_CHANNELS;  /* invalid */                break;        }        s = Angel_DisableInterruptsFromSVC();  /* for next test */    }    /*     * need to clear the flag to say we have been here     */    *status &= ~SER_RX_QUEUED;    /*     * call rx control to reenable interrupts in case they were disabled     */    SerCtrl(devid)->control_rx(devid);    /*     * remember to reenable interrupts before we leave     */    Angel_RestoreInterruptsFromSVC(s);        LogInfo(LOG_RX, ("Exit: count = %d\n", ringBufCount(ring)));}/* *  Function: serpkt_int_tx_processing *   Purpose: Deferred Tx processing for interrupt handler * *    Params: (via args) *       Input: devid           device ID of the driver * *   Returns: Nothing */void serpkt_int_tx_processing(void *args){    const DeviceID devid = (DeviceID) args;    volatile unsigned int *const status = angel_DeviceStatus + devid;    RingBuffer *ring = SerCtrl(devid)->tx_ring;    struct data_packet *txp = SerEngine(devid)->tx_packet;    unsigned int s;    ASSERT(devid < DI_NUM_DEVICES, ("serpkt_int_tx_processing: bad devid %d", devid));    /*      * We need to disable IRQ & FIQ whenever we modify critical data     * shared with the interrupt handler     */    s = Angel_DisableInterruptsFromSVC();    /*     * If we are called with SER_TX_EOD set then we need to handle     * TX completion callback      */    if (((*status & SER_TX_EOD) != 0) && ringBufEmpty(ring))    {        *status &= ~SER_TX_EOD;        Angel_RestoreInterruptsFromSVC(s);        angel_DD_SentPacket(devid, txp->data, txp->len, DS_DONE, txp->type);        s = Angel_DisableInterruptsFromSVC();    }    /* need to clear the flag to say we have been here */    *status &= ~SER_TX_QUEUED;    /*     * If there is space in the tx ring buffer, fill it up     * as far as possible.     */     if ((*status & SER_TX_DATA) != 0)    {        serpkt_fill_tx_ring(devid, ring);    }        /* remember to reenable interrupts before we leave */    Angel_RestoreInterruptsFromSVC(s);}/**********************************************************************//* *  Function: serpkt_flow_control *   Purpose: Flow control handler called by Rx engine when it gets an *              XON or XOFF * *  Pre-conditions: * *    Params: *       Input: fc_char         the Rx character * *              cb_data         device ID of the driver * *   Returns: Nothing */void serpkt_flow_control(char fc_char, void *cb_data){    const DeviceID devid = (DeviceID) cb_data;    volatile unsigned int *const status = angel_DeviceStatus + devid;    unsigned int s = Angel_DisableInterruptsFromSVC();    ASSERT(devid < DI_NUM_DEVICES, ("serpkt_flow_control: bad devid %d", devid));    if (fc_char == serial_XON)    {        *status &= ~SER_TX_CONTROLLED_OFF;        SerCtrl(devid)->control_tx(devid);    }    else if (fc_char == serial_XOFF)    {        *status |= SER_TX_CONTROLLED_OFF;        SerCtrl(devid)->control_tx(devid);    }    Angel_RestoreInterruptsFromSVC(s);}/* EOF serpkt.c */

⌨️ 快捷键说明

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