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

📄 channels.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
        dev->lastUsed = b;        Angel_LeaveCriticalSection();                LogInfo(LOG_CHANNEL, ("adp_add_pkt: Dev: %d stored packet %d, buffer 0x%x\n",                              devid, pkt_no, buffer));        Angel_show_unacked_list(devid);        return adp_ok;    }        Angel_LeaveCriticalSection();        LogWarning(LOG_CHANNEL, ("adp_add_pkt: Dev %d: No free buffers to add"                             " packet %d to resend list\n", devid, pkt_no));    Angel_show_unacked_list(devid);    return adp_ok;}/* *  Function: adp_free_pkt *   Purpose: To remove the packet with a given buffer ref from the resend list. * *  Pre-Conditions: 'cur' must point to a buffer in the used list. * *    Params:  *       Input: devid - the device ID of the driver  *              cur - the buffer ref of the buffer to delete *              last - the buffer ref of the previous buffer, or LISTEND if cur is *                     first buffer * *   Returns: adp_ok */static void adp_free_pkt(register struct DevState *dev, int cur, int last){    /* free up the actual buffer */    if (dev->unackedBufs[cur].buf)        Angel_BufferRelease(dev->unackedBufs[cur].buf);    else        LogWarning(LOG_CHANNEL, ("adp_free_pkt: buffer NULL at index %d\n", cur));        /* clear buffer contents for tidyness */    dev->unackedBufs[cur].len = 0;    dev->unackedBufs[cur].packno = 0;    dev->unackedBufs[cur].buf = NULL;    /* remove buffer from used list */    if (cur == dev->firstUsed)    {        /* remove first, possibly only item */        dev->firstUsed = dev->unackedBufs[cur].next;        if (dev->firstUsed == LISTEND)            dev->lastUsed = LISTEND;    }    else if (cur == dev->lastUsed)    {        /* remove last item -- cannot be only one */        dev->lastUsed = last;        dev->unackedBufs[last].next = LISTEND;    }    else    {        /* remove any other -- must be at least 3 to begin with. */        dev->unackedBufs[last].next = dev->unackedBufs[cur].next;           }    /* and add back to free list */    dev->unackedBufs[cur].next = dev->firstFree;    dev->firstFree = cur;}/* *  Function: adp_remove_pkt *   Purpose: To remove all packets which are acknowledged by *            the given sequence number. Normally, this is just *            the packet which has sequence number 'pkt_no', but *            if two (or more) packets are sent out simultaneously, *            then both will be ack'd by the next reply from the *            host. Two or more packets can be sent without an *            intervening reply if the packets are on different *            channels. * *    Params:  *       Input: devid - the device the packet is using *              pkt_no - the packet sequence number * *   Returns: adp_err - an adp error code equivalent to dev_err */static AdpErrs adp_remove_pkt(DeviceID devid, SequenceNR pkt_no){    struct DevState *dev = &dev_state[devid];    short i, j = LISTEND;    LogInfo(LOG_CHANNEL, ("adp_remove_pkt: Dev: %d ack packet %d (ackExpected %d to max %d)\n",                          devid, pkt_no, dev->ackExpected, nextSEQ(dev->currentFrame)));        Angel_EnterCriticalSection();    while (adp_between(dev->ackExpected, pkt_no, nextSEQ(dev->currentFrame)))    {        /* if we've got a buffered packet for this sequence number,         * free it now.         */        i = adp_get_unack_bufno(devid, dev->ackExpected, dev->firstUsed, &j);        if (i != LISTEND)        {            adp_free_pkt(dev, i, j);        }                INC(dev->ackExpected);    }    Angel_LeaveCriticalSection();            Angel_show_unacked_list(devid);    return adp_ok;}/* *  Function: adp_translate_dev_error *   Purpose: To translate an error code from the underlying device *            system to the ADP error code set. * *    Params:  *       Input: dev_err  - a device error code (DE_xxx) * *   Returns: adp_err - an adp error code equivalent to dev_err */AdpErrsadp_translate_dev_error(DevError dev_err){    switch (dev_err)    {        case DE_OKAY:            return adp_ok;        case DE_NO_DEV:        case DE_BAD_DEV:            return adp_device_not_found;        case DE_BAD_CHAN:            return adp_bad_channel_id;        case DE_BUSY:            return adp_write_busy;        case DE_INVAL:            return adp_bad_packet;        default:            return adp_failed;    }}/* *  Function: release_callback *   Purpose: To release the buffer used by various send functions, if the *            packet being sent is not on a reliable packet stream (i.e. there *            will be no acknowledging packet). * *    Params:  *       Input: v_chan_pkt -- pointer to packet's data *              v_chan_len -- length of the packet. *              v_status   -- status *              cb_data    -- the device ID * *   Returns: none */static void release_callback(void *v_chan_pkt,                            void *v_chan_len,                            void *v_status,                            void *cb_data){    DevStatus status = (DevStatus) (int)v_status;    p_Buffer  chan_pkt = (p_Buffer)v_chan_pkt;    p_Buffer  buffer = chan_pkt - CB_CHAN_DATA_BYTE_POS;    IGNORE(cb_data);    IGNORE(v_chan_len);    if (status != DS_DONE)        LogWarning(LOG_CHANNEL, ("release_callback: status not OK (%d)\n", status));    LogInfo(LOG_CHANNEL, ( "release callback: freeing packet\n"));    Angel_BufferRelease( buffer );}/* *  Function: send_resend_msg *   Purpose: To format and send a resend message on device devid. *            The packet sequence numbers are taken from the device  *            state, and the last good frame (i.e. one before the *            packet being requested) is passed in. * *    Params:  *       Input: devid - the device ID of the driver *              lastGoodFrame - the sequence number of the last good *                      frame. The other side should send LGF+1. * *   Returns: AdpErrs - adp_ok if ok *            adp_failed if buffer not available *            translation of device error (see adp_translate_dev_error()) *            otherwise. */static AdpErrs send_resend_msg(DeviceID devid, SequenceNR lastGoodFrame){    DevError dev_err;    p_Buffer packet;    packet = angel_ChannelAllocBuffer(CF_DATA_BYTE_POS);    if (packet == NULL)    {        LogError(LOG_CHANNEL, ("send_resend_msg: Could not allocate a buffer\n"));        return adp_failed;    }    packet[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;    packet[CF_PACKET_SEQ_BYTE_POS] = dev_state[devid].currentFrame;    packet[CF_ACK_SEQ_BYTE_POS] = lastGoodFrame;    packet[CF_FLAGS_BYTE_POS] = CF_RESEND;    LogWarning(LOG_CHANNEL, ( "send_resend_msg: resend for frame %d\n",                              lastGoodFrame));    do    {                dev_err = angel_DeviceWrite(devid, packet,                                    CF_DATA_BYTE_POS, release_callback,                                    (void *)CI_PRIVATE, DC_DBUG);        if (dev_err == DE_BUSY);        {            Angel_Yield();        }    }    while (dev_err == DE_BUSY);        if (dev_err == DE_OKAY)    {        LogInfo(LOG_CHANNEL, ( "sent resend msg... ok\n", dev_err));    }    else    {        LogError(LOG_CHANNEL, ( "sent resend msg, FAILED ret code 0x%x\n", dev_err));        angel_ChannelReleaseBuffer(packet);    }    return adp_translate_dev_error(dev_err);}/* *  Function: send_heartbeat_ack_msg *   Purpose: Send the acknowledgement for a heartbeat msg * *    Params: *       Input: devid   device ID of the driver * *   Returns: AdpErrs - should be adp_ok */static AdpErrs send_heartbeat_ack_msg(DeviceID devid, int timestamp){    p_Buffer packet;    DevError dev_err;    /*     * if not ack'ing then just return; we dont want to mess our     * debugger up!     */    if (!Angel_AckedHeartbeats)    {        LogInfo(LOG_CHANNEL, ( "not acking heartbeats.\n"));        return adp_ok;    }    /*     * Send a resend message, usually in response to a bad packet or     * a resend request     */    packet = angel_ChannelAllocBuffer(CF_DATA_BYTE_POS);    if (packet == NULL)    {        return adp_failed;    }    packet[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;    packet[CF_PACKET_SEQ_BYTE_POS] = dev_state[devid].currentFrame;    packet[CF_ACK_SEQ_BYTE_POS] = lastSEQ(dev_state[devid].frameExpected);    packet[CF_FLAGS_BYTE_POS] = CF_HEARTBEAT;    PUT32LE(packet + CF_DATA_BYTE_POS, timestamp);    LogInfo(LOG_CHANNEL, ( "set up heartbeat packet, trying to write\n"));    do    {                dev_err = angel_DeviceWrite(devid, packet,                                    CF_DATA_BYTE_POS + 4, release_callback,                                    (void *)CI_PRIVATE, DC_DBUG);        if (dev_err == DE_BUSY);        {            Angel_Yield();        }    }    while (dev_err == DE_BUSY);        if (dev_err == DE_OKAY)    {        LogInfo(LOG_CHANNEL, ( "sent heartbeat msg... ok\n", dev_err));    }    else    {        LogError(LOG_CHANNEL, ( "sent heartbeat msg, FAILED ret code 0x%x\n", dev_err));        angel_ChannelReleaseBuffer(packet);    }    return adp_translate_dev_error(dev_err);}/* *  Function: read_callback *   Purpose: callback for packet rx on active device. *            This code handles all packet input for the DC_DBUG *            device channel, implementing it's own channel split *            on top of this to implement the various debugging *            channels. * *            The code must perform most of the reliability functions *            required by the debug channels, checking for lost or *            out of sequence packets, requesting resends etc. This *            version of the code is very different to that in previous *            Angel systems, as it is here that many of the improvements *            to Angel have been made for SDT 2.11a. * *            For a description of the code, see inline comments, and *            the forthcoming Guide "Angel SDT2.11a: An Introduction" * *    Params: *       Input: v_chan_pkt -- pointer to packet's data *              v_chan_len -- length of packet *              v_status   -- status of packet -- good or bad data *              cb_data    -- the device ID * *   Returns: Nothing. May call specific or general read callback, *            or trigger a message to be sent in reply. *//* this macro is called when it is possible that a bad packet delivery * has been counted in the packet flow control; if this weren't done * the code would hang if waiting for the recovery packet when a bad * packet was delivered. */#define check_flow_control()   if (booted_flow_controlled)  \                                   angel_DeviceControl(devid, DC_RX_PACKET_FLOW, (void*)-1);static voidread_callback(void *v_chan_pkt,              void *v_chan_len,              void *v_status,              void *cb_data){    p_Buffer chan_pkt = (p_Buffer) v_chan_pkt;    unsigned chan_len = (unsigned)v_chan_len;    DevStatus status = (DevStatus) (int)v_status;    DeviceID devid = (DeviceID) cb_data;    ChannelID chanid;    SequenceNR rx_packetseq;    SequenceNR rx_ackseq;    unsigned char rx_flags;    register struct DevState *dev = NULL;        /*     * clear buffers mode tells buffers.c to put 0xDEAD in     * free buffers. check we haven't been handed one of these.     */    if (*chan_pkt == 0xAD && *(chan_pkt+1) == 0xDE &&        *(chan_pkt+2) == 0xAD && *(chan_pkt+3) == 0xDE )    {        LogError(LOG_CHANNEL, ("read callback: called with free buffer %x (status %d)\n",                               chan_pkt, status));        return;    }               dev = &dev_state[devid];    switch (status)    {        case DS_DONE:            /* extract and check channel */            chanid = chan_pkt[CF_CHANNEL_BYTE_POS];            rx_packetseq = chan_pkt[CF_PACKET_SEQ_BYTE_POS];            rx_ackseq = chan_pkt[CF_ACK_SEQ_BYTE_POS];

⌨️ 快捷键说明

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