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

📄 channels.c

📁 ARM入门的好帮手.包含了从简单到相对较复杂的程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
            }        } while (chan_err == DE_BUSY);                if (chan_err == DE_OKAY)        {            LogInfo(LOG_CHANNEL, ( "resend msg: %d ok\n", thispacket));        }        else        {            LogError(LOG_CHANNEL, ( "resend msg: packet %d FAILED ret code 0x%x\n",                                    thispacket, chan_err));        }        /* now wait for the write to complete */        LogInfo(LOG_CHANNEL, ( "resend msg: waiting for send to complete...\n"));                while (chan_state[chanid].write_blocking)        {            Angel_Yield();        }                LogInfo(LOG_CHANNEL, ( "resend msg: send complete\n"));        INC(thispacket);                j = i;        Angel_EnterCriticalSection();    }    Angel_LeaveCriticalSection();    return adp_translate_dev_error(chan_err);}/* * Function: angel_ChannelRead *  Purpose: blocking read of a packet from a channel * * see channels.h for full description *//* callback for this routine */static void read_unblock_callback(DeviceID devid, ChannelID chanid,                      p_Buffer buffer, unsigned len,                      void *callback_data){    ChanError chan_error;    ChanError *read_error = (ChanError *) callback_data;    ASSERT(chanid < CI_NUM_CHANNELS, ("Channel ID %d invalid in callback\n", chanid));    ASSERT(chan_state[chanid].read_blocking == TRUE, ("Read not blocking in callback\n"));    ASSERT(read_error != NULL, ("Nowhere to write error code in callback\n"));    /* unregister the async read */    chan_error = angel_ChannelReadAsync(devid, chanid, NULL, NULL);    ASSERT(chan_error == CE_OKAY, ("Error unregistering async read in callback\n"));    LogInfo(LOG_CHANNEL, ("read_unblock_callback: channel %d buffer %d len %d\n",                          chanid, buffer, len));        *read_error = CE_OKAY;    chan_state[chanid].read_buffer = buffer;    chan_state[chanid].read_len = len;    chan_state[chanid].read_blocking = FALSE;}#ifdef NEED_CHANNEL_READChanError angel_ChannelRead(DeviceID devid,                  ChannelID chanid,                  p_Buffer * buffer,                  unsigned *len){    ChanError chan_error;    ChanError read_error = CE_PRIVATE;    ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid));    /* Check that a read is not already in progress */    Angel_EnterCriticalSection();    if (chan_state[chanid].read_blocking)    {        Angel_LeaveCriticalSection();        LogWarning(LOG_CHANNEL, ( "ChannelRead: already busy on chan %d\n", chanid));        return CE_BUSY;    }    chan_state[chanid].read_blocking = TRUE;    Angel_LeaveCriticalSection();    /* Register an async read */    chan_error = angel_ChannelReadAsync(devid, chanid,                                        read_unblock_callback,                                        (void *)&read_error);    if (chan_error != CE_OKAY)    {        chan_state[chanid].read_blocking = FALSE;        return chan_error;    }    /* now wait for the read to complete */    while (chan_state[chanid].read_blocking)    {        TRACE("crb");        Angel_Yield();    }    /* get at the results of the async read */    if (read_error == CE_OKAY)    {        *buffer = chan_state[chanid].read_buffer;        *len = chan_state[chanid].read_len;    }    if (read_error)        LogWarning(LOG_CHANNEL, ( "ChannelRead: error code %d\n", read_error));    return read_error;}#endif /* def NEED_CHANNEL_READ *//* * Function: angel_ChannelReadAsync *  Purpose: asynchronous read of a packet via a channel * * see channels.h for full details */ChanError angel_ChannelReadAsync(DeviceID devid,                       ChannelID chanid,                       ChanRx_CB_Fn callback,                       void *callback_data){    /* adjust the device id, if required */    if (devid == CH_DEFAULT_DEV)    {        devid = active_device;    }    ASSERT(devid < DI_NUM_DEVICES, ("Bad device ID %d\n", devid));    /* we can only read from the active device in this version */    ASSERT(devid == active_device, ("ReadAsync device %d not active device %d\n",                                    devid, active_device));    ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid));    /*     * we can only service one request per channel in this version,     * OR unregister by specifying a NULL callback     */    Angel_EnterCriticalSection();           /* start critical region */    if (chan_state[chanid].reader != NULL && callback != NULL)    {        Angel_LeaveCriticalSection();        LogWarning(LOG_CHANNEL, ( "ChannelReadAsync: already reader on chan %d\n",                                  chanid));        return CE_BUSY;    }    /* record what we need to know later */    chan_state[chanid].reader = callback;    chan_state[chanid].read_cb_data = callback_data;    Angel_LeaveCriticalSection();          /* end critical region */    /* that's all we need to do */    return CE_OKAY;}/* * Function: angel_ChannelReadAll *  Purpose: register an asynchronous read across all devices * * see channels.h for full details */ChanError angel_ChannelReadAll(ChannelID chanid,                     ChanRx_CB_Fn callback,                     void *callback_data){    ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid));    ASSERT(callback != NULL, ("No callback function in Read All\n"));    if (read_all_callback != NULL || chan_state[chanid].reader != NULL)    {        LogWarning(LOG_CHANNEL, ( "ChannelReadAll: already reader on chan %d\n", chanid));        return CE_BUSY;    }    /* just register the info */    read_all_channel = chanid;    read_all_callback = callback;    read_all_cb_data = callback_data;    return CE_OKAY;}/* * Function: angel_ChannelSendThenRead *  Purpose: blocking read of a packet from a channel * * see channels.h for full description */ChanError angel_ChannelSendThenRead(DeviceID devid,                          ChannelID chanid,                          p_Buffer * buffer,                          unsigned *len){    ChanError chan_error;    ChanError send_error = CE_PRIVATE;    ChanError read_error = CE_PRIVATE;#if DEBUG == 1    unsigned int reason;    unpack_message(BUFFERDATA(*buffer), "%w", &reason);#endif        ASSERT(chanid < CI_NUM_CHANNELS, ("Bad channel ID %d\n", chanid));            LogInfo(LOG_CHANNEL, ( "angel_ChannelSendThenRead: chan %d buffer %p, len %d [reason: %s]\n",                           chanid, *buffer, *len, log_adpname(reason)));    /* Check that nothing is already in progress */    Angel_EnterCriticalSection();    if (chan_state[chanid].read_blocking || chan_state[chanid].write_blocking)    {        Angel_LeaveCriticalSection();        LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: already busy on chan %d\n",                                   chanid));        angel_ChannelReleaseBuffer(*buffer);        return CE_BUSY;    }    chan_state[chanid].read_blocking = TRUE;    chan_state[chanid].write_blocking = TRUE;    Angel_LeaveCriticalSection();    /* Register an async read */    chan_error = angel_ChannelReadAsync(devid, chanid,                                        read_unblock_callback,                                        (void *)&read_error);    if (chan_error != CE_OKAY)    {        LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Can't register read "                                   "callback for chan %d\n", chanid));        angel_ChannelReleaseBuffer(*buffer);        chan_state[chanid].read_blocking = FALSE;        chan_state[chanid].write_blocking = FALSE;        return chan_error;    }    /* Then start an async write */    chan_error = angel_ChannelSendAsync(devid, chanid, *buffer, *len,                                        write_unblock_callback,                                        (void *)&send_error);    if (chan_error != CE_OKAY)    {        ChanError unreg_error;        LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Send failed, error %d "                                   "for chan %d\n", chan_error, chanid));                unreg_error = angel_ChannelReadAsync(devid, chanid, NULL, NULL);                if (unreg_error != 0)            LogWarning(LOG_CHANNEL, ("ChannelSendThenRead: Can't unregister read "                                       "callback for chan %d, error %d\n", chanid, unreg_error));        chan_state[chanid].read_blocking = FALSE;        chan_state[chanid].write_blocking = FALSE;        return chan_error;    }    /* Now wait for both to complete */    while (chan_state[chanid].write_blocking           || chan_state[chanid].read_blocking)    {        if (!chan_state[chanid].read_blocking)            LogWarning(LOG_CHANNEL, ( "read packet before write complete\n"));        TRACE("csr");        Angel_Yield();    }    /* get at the results of the async read */    if (read_error == CE_OKAY)    {        *buffer = chan_state[chanid].read_buffer;        *len = chan_state[chanid].read_len;#if DEBUG == 1        unpack_message(BUFFERDATA(*buffer), "%w", &reason);        LogInfo(LOG_CHANNEL, ( "angel_ChannelSendThenRead: Return buffer %p, len %d [reason: %s]\n",                               *buffer, *len, log_adpname(reason)));#endif    }    if (read_error)        LogWarning(LOG_CHANNEL, ( "SendThenRead: read error code %d\n", read_error));    if (send_error)        LogWarning(LOG_CHANNEL, ( "SendThenRead: write error code %d\n", send_error));    return (send_error ? send_error : read_error);}/* * Function: angel_ChannelSelectDevice *  Purpose: select the device to be used for all channel comms * * see channels.h for full details */ChanError angel_ChannelSelectDevice(DeviceID device){    unsigned int i;    ASSERT(device < DI_NUM_DEVICES, ("Bad device ID %d\n", device));    LogInfo(LOG_CHANNEL, ( "ChannelSelectDevice: %d\n", device));    if (device == active_device)        return CE_OKAY;         /* already correct */    /* first we must do an abort on any blocking reads or writes */    for (i = 0; i < CI_NUM_CHANNELS; ++i)    {        if (chan_state[i].read_blocking)        {            ChanError *read_error = (ChanError *) chan_state[i].read_cb_data;            ASSERT(read_error != NULL, ("angel_ChannelSelectDevice: write_error NULL\n"));            LogWarning(LOG_CHANNEL, ( "ABANDON read on channel %d\n", i));            *read_error = CE_ABANDONED;            if (chan_state[i].read_buffer != NULL)                angel_ChannelReleaseBuffer(chan_state[i].read_buffer);            chan_state[i].reader = NULL;            chan_state[i].read_blocking = FALSE;        }        if (chan_state[i].write_blocking)        {            ChanError *write_error = (ChanError *) chan_state[i].write_cb_data;            ASSERT(write_error != NULL, ("angel_ChannelSelectDevice: write_error NULL\n"));            LogWarning(LOG_CHANNEL, ( "ABANDON write on channel %d\n", i));            *write_error = CE_ABANDONED;            chan_state[i].writer = NULL;            chan_state[i].write_buff = NULL;            chan_state[i].write_blocking = FALSE;        }    }    active_device = device;    return CE_OKAY;}/* * Function: angel_ChannelReadActiveDevice *  Purpose: reads the device id of the currently active device * * see channels.h for full details */ChanError angel_ChannelReadActiveDevice(DeviceID * device){    *device = active_device;    return CE_OKAY;}/* EOF channels.c */

⌨️ 快捷键说明

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