📄 ser_test_protocol.inl
字号:
#endif }#if 0 // FIXME: This is needed to prevent sending data at the new baud rate // before the host is ready.... Need to fiddle this a bit more. // Loop counts for ARM and PII in host side source. Replace with // timed loops. { int i; for (i = 0; i < 100000; i++); }#else cyg_thread_delay(80); // this requires kernel#endif return res;}//-----------------------------------------------------------------------------// Host sends CRC in decimal ASCII, terminated with !intread_host_crc(cyg_io_handle_t handle){ int crc, len; cyg_uint8 ch; crc = 0; while (1) { len = 1; Tcyg_io_read(handle, &ch, &len); if ('!' == ch) break;#ifdef __DEVELOPER__ if (!((ch >= '0' && ch <= '9'))){ diag_printf("CHAR: %02x\n", ch); }#endif CYG_TEST_CHECK((ch >= '0' && ch <= '9'), "Illegal CRC format from host"); crc = crc*10 + (ch - '0'); } return crc;}//---------------------------------------------------------------------------// Test binary data transmission.// Format out:// "@BINARY:<byte size>:<mode>!"// Format in:// <checksum>!<#size bytes data>// For echo modes, also:// Format out:// <#size bytes data>// Format in:// OK/ER// Format out:// DONE//// The last DONE allows the host to eat bytes if target is sending too many.//// Mode:// MODE_NO_ECHO: // Just receive data and verify CRC.// MODE_EOP_ECHO:// Receive data, verify CRC, resend data.// Expect OK/ER reply from host when done.// MODE_DUPLEX_ECHO:// Receive data, echo data, verify CRC.// Expect OK/ER reply from host when done.//// Note:// Using diag_printf while talking with the host may cause some funky// errors (bytes from the host side being lost!?!?)//// To Do:// MODE_DUPLEX_ECHO:// The current implementation is simple and may not stress the// driver enough. Also, it's command packet format doesn't match// that of the other modes.cyg_test_return_ttest_binary(cyg_io_handle_t handle, int size, cyg_mode_t mode){ const char cmd[] = "@BINARY:"; int msglen; cyg_uint32 xcrc; int icrc, host_crc; cyg_uint8 *p1; cyg_int8 host_status = 'O'; // host is happy by default int spurious = 0; // Verify that the test can be run with available ressources. if (MODE_EOP_ECHO == mode && size > IN_BUFFER_SIZE) return TEST_RETURN_NA; // Prepare and send the command. p1 = &cmd_buffer[0]; p1 = strcpy(p1, &cmd[0]); p1 = itoa(p1, size); *p1++ = ':'; p1 = itoa(p1, mode); *p1++ = '!'; *p1++ = 0; CYG_TEST_INFO(&cmd_buffer[1]); msglen = strlen(&cmd_buffer[0]); Tcyg_io_write(handle, &cmd_buffer[0], &msglen); // Get CRC back. host_crc = read_host_crc(handle); // Depending on mode, start reading data. xcrc = 0; switch (mode) { case MODE_NO_ECHO: { // Break transfers into chunks no larger than the buffer size. int tx_len, chunk_len, i; while (size > 0) { chunk_len = min(IN_BUFFER_SIZE, size); tx_len = chunk_len; size -= chunk_len; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); for (i = 0; i < tx_len; i++) { ADD_CRC_BYTE(xcrc, in_buffer[i]); } } // Reply that we have completed the test. { const char msg_done[] = "DONE"; chunk_len = strlen(&msg_done[0]); Tcyg_io_write(handle, &msg_done[0], &chunk_len); } } break; case MODE_EOP_ECHO: { // We have already checked that the in buffer is large enough. int i, tx_len, chunk_len; chunk_len = tx_len = size; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); for (i = 0; i < tx_len; i++) { ADD_CRC_BYTE(xcrc, in_buffer[i]); } // Echo data back. chunk_len = size; Tcyg_io_write(handle, &in_buffer[0], &chunk_len); // Now read host side's status chunk_len = 2; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); host_status = in_buffer[0];#if HANDLE_SPURIOUS // FIXME: This occassionally reads back a spurious character // from the transmission. It's not just noise, it's definitely // a byte from the previously transmitted data. if (in_buffer[0] != 'O' && in_buffer[1] == 'O') { spurious = in_buffer[0]; chunk_len = 1; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); if (in_buffer[0] == 'K') { host_status = 'O'; } }#endif // Reply that we have completed the test. { const char msg_done[] = "DONE"; chunk_len = strlen(&msg_done[0]); Tcyg_io_write(handle, &msg_done[0], &chunk_len); }#if HANDLE_SPURIOUS if (spurious) { diag_printf("******* Spurious byte 0x%02x *******\n", spurious); }#endif } break; case MODE_DUPLEX_ECHO: { int chunk_len; int block_size = 64; // 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. while (size--) { // block_size -> block_size chunk_len = block_size; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); chunk_len = block_size; Tcyg_io_write(handle, &in_buffer[0], &chunk_len); // block_size -> 2 x block_size chunk_len = block_size; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); chunk_len = block_size; Tcyg_io_write(handle, &in_buffer[0], &chunk_len); chunk_len = block_size; Tcyg_io_write(handle, &in_buffer[0], &chunk_len); // block_size -> block_size chunk_len = block_size; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); chunk_len = block_size; Tcyg_io_write(handle, &in_buffer[0], &chunk_len); // block_size -> 0 chunk_len = block_size; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); } // Kill the CRC. Leave packet verification to the host for now. xcrc = host_crc = 0; // Now read host side's status chunk_len = 2; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); host_status = in_buffer[0];#if HANDLE_SPURIOUS // FIXME: This occassionally reads back a spurious character // from the transmission. It's not just noise, it's definitely // a byte from the previously transmitted data. if (in_buffer[0] != 'O' && in_buffer[1] == 'O') { spurious = in_buffer[0]; chunk_len = 1; Tcyg_io_read(handle, &in_buffer[0], &chunk_len); if (in_buffer[0] == 'K') { host_status = 'O'; } }#endif // Reply that we have completed the test. { const char msg_done[] = "DONE"; chunk_len = strlen(&msg_done[0]); Tcyg_io_write(handle, &msg_done[0], &chunk_len); }#if HANDLE_SPURIOUS if (spurious) { diag_printf("******* Spurious byte 0x%02x *******\n", spurious); }#endif } break; default: CYG_TEST_CHECK(0, "unknown mode"); } // Verify that the CRC matches the one from the host. FIX_CRC(xcrc, icrc);#ifdef __DEVELOPER__ if (host_crc != icrc) diag_printf("%d != %d\n", icrc, host_crc);#endif CYG_TEST_CHECK(host_crc == icrc, "CRC failed!"); // Verify that the host is happy with the data we echoed. CYG_TEST_CHECK('O' == host_status, "Host failed checksum on echoed data"); CYG_TEST_PASS("Binary test completed"); return TEST_RETURN_OK;}//---------------------------------------------------------------------------// Test transformations on text transmissions// Format out:// "@TEXT:<mode>!<4 bytes binary checksum><C string>"// Format in:// "<C string>"// OK/ER//// Mode:// MODE_EOP_ECHO:// Receive data, verify CRC, resend data.// Expect OK/ER reply from host when done.// MODE_DUPLEX_ECHO:// Receive data, echo data, verify CRC.// Expect OK/ER reply from host when done.//cyg_test_return_ttest_text(cyg_io_handle_t handle, cyg_mode_t mode, const char* s_base, const char* s_out, const char* s_in){ return TEST_RETURN_NA;}//---------------------------------------------------------------------------// Send PING to host, verifying the filter's presence.// Format out:// "@PING!"// Format in:// "OK"// or// No response if directly connected to GDB.//// This call only returns if the ser_filter is listening. Otherwise it// sends N/A and hangs.voidtest_ping(cyg_io_handle_t handle){ char msg[] = "@PING:!"; char msg2[] = "\n"; int msglen = strlen(msg); int res; msglen = strlen(msg); Tcyg_io_write(handle, msg, &msglen); // Now read host side's status msglen = 2; Tcyg_io_read_timeout(handle, &in_buffer[0], &msglen, 100, &res); if (ENOERR == res && 'O' == in_buffer[0] && 'K' == in_buffer[1]) return; msglen = strlen(msg2); Tcyg_io_write(handle, msg2, &msglen); CYG_TEST_NA("No host side testing harness detected.");}//---------------------------------------------------------------------------// Some helper functions to get a test started.voidtest_open_ser( cyg_io_handle_t* handle ){#ifndef SER_NOP_TEST Cyg_ErrNo res; if (cyg_test_is_simulator) CYG_TEST_NA("Cannot run from simulator");#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)# if defined(SER_OVERRIDE_INT_1) HAL_VSR_SET_TO_ECOS_HANDLER(SER_OVERRIDE_INT_1, NULL);# endif# if defined(SER_OVERRIDE_INT_2) HAL_VSR_SET_TO_ECOS_HANDLER(SER_OVERRIDE_INT_2, NULL);# endif#endif res = cyg_io_lookup(TEST_SER_DEV, handle); if (res != ENOERR) { CYG_TEST_FAIL_FINISH("Can't lookup " TEST_SER_DEV); }#else CYG_TEST_NA("No test device specified");#endif}voidtest_open_tty( cyg_io_handle_t* handle ){#ifndef TTY_NOP_TEST Cyg_ErrNo res; if (cyg_test_is_simulator) CYG_TEST_NA("Cannot run from simulator");#if defined(HAL_VSR_SET_TO_ECOS_HANDLER)# if defined(SER_OVERRIDE_INT_1) HAL_VSR_SET_TO_ECOS_HANDLER(SER_OVERRIDE_INT_1, NULL);# endif# if defined(SER_OVERRIDE_INT_2) HAL_VSR_SET_TO_ECOS_HANDLER(SER_OVERRIDE_INT_2, NULL);# endif#endif res = cyg_io_lookup(TEST_TTY_DEV, handle); if (res != ENOERR) { CYG_TEST_FAIL_FINISH("Can't lookup " TEST_TTY_DEV); }#else CYG_TEST_NA("No test device specified");#endif}//---------------------------------------------------------------------------// end of ser_test_protocol.inl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -