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

📄 ecostestserialfilter.cpp

📁 基于ecos的redboot
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // Send checksum to target.
    SendChecksum(pSer, crc);

    // Give the target 1/10th of a sec to digest it
    CeCosThreadUtils::Sleep(100);

    switch (mode) {
    case MODE_NO_ECHO:
    {
        // Simple transmit. Don't expect target to echo data back.
        TargetWrite(pSer, data_out, size);
        ReceiveDone(pSer, NULL, 0);
    }
    break;
    case MODE_EOP_ECHO:
    {
        int in_crc;

        TargetWrite(pSer, data_out, size);
        Trace("Finished write, waiting for target echo.\n");

        // Expect target to echo the data
        TargetRead(pSer, data_in, size);

        // Check echoed data, and reply OK/ER accordingly.
        in_crc = DoCRC(data_in, size);
        SendStatus(pSer, (in_crc == crc));


        // Dump seen/expected on console.
        if (in_crc != crc) {
            Trace("Data seen:\n");
            PrintHex(data_in, size);
            Trace("<end>\n");
            Trace("Data expected:\n");
            PrintHex(data_out, size);
            Trace("<end>\n");
        }

        ReceiveDone(pSer, data_in, size);

    }
    break;
    case MODE_DUPLEX_ECHO:
    {
        int block_size = 64;
        int fail, j;

        // This is a simple implementation (maybe too simple).
        // Host sends 4 packets with the same size (64 bytes atm).
        // Target echoes in this way:
        //  packet1 -> packet1
        //  packet2 -> packet2, packet2
        //  packet3 -> packet3
        //  packet4 -> /dev/null
        //
        // The reads/writes are interleaved in a way that should ensure
        // the target out buffer to be full before the target starts to read
        // packet3. That is, the target should be both receiving (packet3)
        // and sending (packet2) at the same time.

        // This code needs restructuring. It's not very obvious what's
        // happening: The same block of data is output several times,
        // the target echoes the data back (one of the blocks is
        // echoed twice). Then the echoed data is compared agains the
        // outgoing data block.

        fail = 0;
        while (loop_count--) {
            int i;
            for (i = 0; i < block_size*4; i++)
                data_in[i] = 0;

            // out1: block_size -> block_size
            TargetWrite(pSer, data_out, block_size);

            // out2: block_size -> 2 x block_size
            TargetWrite(pSer, data_out, block_size);

            // in1:
            TargetRead(pSer, data_in, block_size);

            // out3: block_size -> block_size
            TargetWrite(pSer, data_out, block_size);
        
            // in2:
            TargetRead(pSer, &data_in[block_size], 2*block_size);

            // out4: block_size -> 0
            TargetWrite(pSer, data_out, block_size);
        
            // in3:
            TargetRead(pSer, &data_in[block_size*3], block_size);

            if (0 == loop_count % 10)
                Trace("%d loops to go\n", loop_count);

            // Verify data.
            if (!fail) {
                for (j = 0; j < 4 && !fail; j++) {
                    for (i = 0; i < block_size && !fail; i++) {
                        if (data_out[i] != data_in[j*block_size + i]) {
                            fail = 1;
                            Trace("Failed at byte %d\n", j*block_size + i);
                            
                            Trace("Data seen:\n");
                            PrintHex(&data_in[j*block_size], 
                                           block_size);
                            Trace("<end>\n");
                            Trace("Data expected:\n");
                            PrintHex(data_out, block_size);
                            Trace("<end>\n");
                        }
                    }
                }
            }
        }
        // Check echoed data, and reply OK/ER accordingly.
        SendStatus(pSer, (!fail));
        ReceiveDone(pSer, data_in, block_size*4);
    }
    break;
    default:
        Trace("Unknown mode. Ignoring.\n");
    }

    // Free buffer.
    free(data_in);
    free(data_out);
}

//-----------------------------------------------------------------------------
// Test transformations on text transmissions
//
// This test transmits null-terminated C strings back and forth. Since
// the translation is under test and may fail, the length of the data is
// (potentially) unknown. Sending with a null-terminator allows proper
// recovery even if the translations do not work as intended.
//
// Format in:
//  <flags>!<4 bytes binary checksum><C string>
// Format out:
//  <C string>
//  OK/ER
//
// Mode:
//   MODE_EOP_ECHO:
//       Receive data, verify CRC, resend data.
//       Send OK/ER reply when done.
//   MODE_DUPLEX_ECHO:
//       Receive data, echo data, verify CRC.
//       Send OK/ER reply when done.
//
// To Do:
//  Implement.
void
CeCosTestSerialFilter::CMD_TestText(CeCosSerial &pSer, char* /*args*/)
{
    SendStatus(pSer, 1);
}

//-----------------------------------------------------------------------------
// Reply to PING packet from target.
// Format in:
//  "!"
// Format out:
//  OK
void
CeCosTestSerialFilter::CMD_TestPing(CeCosSerial &pSer, char* /*args*/)
{ 
    SendStatus(pSer, 1);
}

//-----------------------------------------------------------------------------
// Dispatch test command. 
void
CeCosTestSerialFilter::DispatchCommand(CeCosSerial &pSer, char* cmd)
{
    char* args;

    args = strchr(cmd, (int) ':');
    if (!args) {
        Trace("Bogus command (%s) Ignoring.\n", cmd);
        return;
    }
        
    *args++ = 0;

    Trace("Dispatching command %s.\n", cmd);

    if (0 == strcmp("CONFIG", cmd)) {
        CMD_ChangeConfig(pSer, args);
    } 
    else if (0 == strcmp("DEFCONFIG", cmd)) {
        // Note: Currently the arguments are ignored. 9600 8N1 is default.
        CMD_DefaultConfig(pSer);
    }
    else if (0 == strcmp("BINARY", cmd)) {
        CMD_TestBinary(pSer, args);
    }
    else if (0 == strcmp("TEXT", cmd)) {
        CMD_TestText(pSer, args);
    }
    else if (0 == strcmp("PING", cmd)) {
        CMD_TestPing(pSer, args);
    }
    else
        Trace("Unknown command '%s'.\n", cmd);

    Trace("Command %s completed.\n", cmd);
}

bool CALLBACK
SerialFilterFunction(void*& pBuf,
                     unsigned int& nRead,
                     CeCosSerial& serial,
                     CeCosSocket& socket,
                     void* pParem)
{
    CeCosTestSerialFilter* p = (CeCosTestSerialFilter*) pParem;
    return p->FilterFunctionProper(pBuf, nRead, serial, socket);
}

bool
CeCosTestSerialFilter::FilterFunctionProper(void*& pBuf,
                                            unsigned int& nRead,
                                            CeCosSerial& serial,
                                            CeCosSocket& socket)
{
    char* buffer = (char*) pBuf;

    // Don't do anything in the null filter mode.
    if (m_bNullFilter)
        return true;

    // Allows trace to be called without a reference to the socket...
    m_cGDBSocket = &socket;

    // Put in trace buffer in case we have to leave it because the packet
    // is incomplete
    m_xStoredTraceBuffer = (unsigned char *)
        realloc( m_xStoredTraceBuffer, m_nStoredTraceBufferSize + nRead );
    if ( NULL == m_xStoredTraceBuffer ) 
        throw "Could not allocate stored trace buffer";
    memcpy( m_xStoredTraceBuffer + m_nStoredTraceBufferSize, buffer, nRead );
    m_nStoredTraceBufferSize += nRead;

    // Now search for distinct packets, delimited by '@' (filter commands)
    // and '$' (GDB packets)
    unsigned int i, newStart=0;
    for (i=0; i<m_nStoredTraceBufferSize; i++) {
        if ( m_xStoredTraceBuffer[i] == '@' ||
             m_xStoredTraceBuffer[i] == '$' ) {
            if (m_bOptSerDebug &&
                (m_bOptConsoleOutput || m_bFirstCommandSeen)) {

                // Output the serial data if option enabled - but only if
                // dumping state to the console or after the first command
                // has been seen from the filter. GDB gets confused by
                // O-packets if they appear when it's trying to connect.

                PrintHex(&m_xStoredTraceBuffer[newStart], i - newStart);
            }
            newStart = i;
        }
    }

    // If we managed to print output, rejig the buffer size, and shunt
    // the new start of the data to the front of the trace buffer
    m_nStoredTraceBufferSize -= newStart;
    
    memmove( m_xStoredTraceBuffer, &m_xStoredTraceBuffer[newStart],
             m_nStoredTraceBufferSize );
        

    // Command handling.
    // If we are not presently reading a command, look for the
    // start marker.
    i = 0;
    if (!m_bCmdFlag)
        for (; i < nRead; i++) {
            if ('@' == buffer[i]) {
                m_bCmdFlag = true;
                // Send the data before the marker.
                if (i)
                    socket.send(buffer, i);
                break;
            }
        }

    // If reading a command, look for the end marker.
    if (m_bCmdFlag) {
        char c = 0;
        while (i < nRead && m_nCmdIndex < MAX_CMD_LEN) {
            c = buffer[i++];
            m_aCmd[m_nCmdIndex++] = c;
            if ('!' == c) {
                if (i != nRead) {
                    m_nUnreadBufferIndex = 0;
                    m_nUnreadBufferSize = nRead - i;
                    m_xUnreadBuffer = 
                        (unsigned char*) malloc(m_nUnreadBufferSize);
                    if (!m_xUnreadBuffer) {
                        m_nUnreadBufferSize = 0;
                        throw "Could not allocate unread buffer!";
                    }
                    
                    int ix = 0;
                    while (i < nRead)
                        m_xUnreadBuffer[ix++] = buffer[i++];
                }
                break;
            }
        }

        if (MAX_CMD_LEN == m_nCmdIndex) {
            Trace("Received too long command. Ignoring it!\n");
            m_nCmdIndex = 0;
            m_bCmdFlag = false;
        } else if ('!' == c) {
            // Was the command completed?
            m_aCmd[m_nCmdIndex - 1] = 0;// terminate cmd
            m_nCmdIndex = 0;
            m_bCmdFlag = false;

            // First command dispatched. Initialize serial to nonblocking.
            if (!m_bFirstCommandSeen) {
                m_bFirstCommandSeen = true;
                serial.SetBlockingReads(false);
            }
  
            try {
                // skip @ when passing ptr
                DispatchCommand(serial, &m_aCmd[1]);
            } 
            catch (filter_abort_t* msg) {
                // This allows the filter to unwind, wherever in the
                // protocol it may be, when a $ is detected from the
                // target side.  When this happens, we may have a
                // trap/exception on the target and we want the user
                // to access the target via GDB without intervention.

                // Do nothing from next call.
                m_bNullFilter = true;

                // Copy the start of the $-packet to the inbuffer.
                unsigned char *d = (unsigned char*) pBuf;
                const unsigned char *s = msg->data_ptr;
                unsigned int len = msg->data_len;
                
                // It should be possible to re-allocate buffer. Didn't seem
                // to work properly though. Probably won't be a problem
                // since we would normally only see 1-2 bytes of the
                // $-packet anyway.
                if (len > nRead)
                    throw "Not enough room for $-message";

                while (len--)
                    *d++ = *s++;

                nRead = msg->data_len;

                delete msg;

                return true;
            }
        }

        nRead = 0;                      // Never leave anything for caller
                                        // This is a violation of the intended
                                        // filter function behavior.
    }
    return true;
}

⌨️ 快捷键说明

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