mirror of https://github.com/ARMmbed/mbed-os.git
Tests: USB: Add tests for Serial class.
parent
3ed7d8139b
commit
7a4b36c37f
|
@ -25,6 +25,7 @@ import mbed_host_tests
|
||||||
|
|
||||||
|
|
||||||
MSG_KEY_PORT_OPEN_WAIT = 'port_open_wait'
|
MSG_KEY_PORT_OPEN_WAIT = 'port_open_wait'
|
||||||
|
MSG_KEY_PORT_OPEN_CLOSE = 'port_open_close'
|
||||||
MSG_KEY_SEND_BYTES_SINGLE = 'send_single'
|
MSG_KEY_SEND_BYTES_SINGLE = 'send_single'
|
||||||
MSG_KEY_SEND_BYTES_MULTIPLE = 'send_multiple'
|
MSG_KEY_SEND_BYTES_MULTIPLE = 'send_multiple'
|
||||||
MSG_KEY_LOOPBACK = 'loopback'
|
MSG_KEY_LOOPBACK = 'loopback'
|
||||||
|
@ -109,6 +110,7 @@ class USBSerialTest(mbed_host_tests.BaseHostTest):
|
||||||
return
|
return
|
||||||
|
|
||||||
def port_open_close(self, usb_id_str):
|
def port_open_close(self, usb_id_str):
|
||||||
|
"""Open the serial and close it with a delay."""
|
||||||
mbed_serial = serial.Serial(timeout=0.5, write_timeout=0.1)
|
mbed_serial = serial.Serial(timeout=0.5, write_timeout=0.1)
|
||||||
try:
|
try:
|
||||||
mbed_serial.port = retry_fun_call(
|
mbed_serial.port = retry_fun_call(
|
||||||
|
@ -197,6 +199,7 @@ class USBSerialTest(mbed_host_tests.BaseHostTest):
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.register_callback(MSG_KEY_PORT_OPEN_WAIT, self.cb_port_open_wait)
|
self.register_callback(MSG_KEY_PORT_OPEN_WAIT, self.cb_port_open_wait)
|
||||||
|
self.register_callback(MSG_KEY_PORT_OPEN_CLOSE, self.cb_port_open_close)
|
||||||
self.register_callback(MSG_KEY_SEND_BYTES_SINGLE, self.cb_send_bytes_single)
|
self.register_callback(MSG_KEY_SEND_BYTES_SINGLE, self.cb_send_bytes_single)
|
||||||
self.register_callback(MSG_KEY_SEND_BYTES_MULTIPLE, self.cb_send_bytes_multiple)
|
self.register_callback(MSG_KEY_SEND_BYTES_MULTIPLE, self.cb_send_bytes_multiple)
|
||||||
self.register_callback(MSG_KEY_LOOPBACK, self.cb_loopback)
|
self.register_callback(MSG_KEY_LOOPBACK, self.cb_loopback)
|
||||||
|
@ -223,6 +226,12 @@ class USBSerialTest(mbed_host_tests.BaseHostTest):
|
||||||
target=self.port_open_wait,
|
target=self.port_open_wait,
|
||||||
args=(value, ))
|
args=(value, ))
|
||||||
|
|
||||||
|
def cb_port_open_close(self, key, value, timestamp):
|
||||||
|
"""Open the serial and close it with a delay."""
|
||||||
|
self.start_bg_task(
|
||||||
|
target=self.port_open_close,
|
||||||
|
args=(value, ))
|
||||||
|
|
||||||
def cb_send_bytes_single(self, key, value, timestamp):
|
def cb_send_bytes_single(self, key, value, timestamp):
|
||||||
"""Open the serial and send a sequence of values."""
|
"""Open the serial and send a sequence of values."""
|
||||||
self.start_bg_task(
|
self.start_bg_task(
|
||||||
|
|
|
@ -24,11 +24,15 @@
|
||||||
#include "mbed.h"
|
#include "mbed.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "USBCDC.h"
|
#include "USBCDC.h"
|
||||||
|
#include "USBSerial.h"
|
||||||
|
|
||||||
#define USB_CDC_VID 0x1f00
|
#define USB_CDC_VID 0x1f00
|
||||||
#define USB_CDC_PID 0x2013
|
#define USB_CDC_PID 0x2013
|
||||||
|
#define USB_SERIAL_VID 0x1f00
|
||||||
|
#define USB_SERIAL_PID 0x2012
|
||||||
|
|
||||||
#define MSG_KEY_PORT_OPEN_WAIT "port_open_wait"
|
#define MSG_KEY_PORT_OPEN_WAIT "port_open_wait"
|
||||||
|
#define MSG_KEY_PORT_OPEN_CLOSE "port_open_close"
|
||||||
#define MSG_KEY_SEND_BYTES_SINGLE "send_single"
|
#define MSG_KEY_SEND_BYTES_SINGLE "send_single"
|
||||||
#define MSG_KEY_SEND_BYTES_MULTIPLE "send_multiple"
|
#define MSG_KEY_SEND_BYTES_MULTIPLE "send_multiple"
|
||||||
#define MSG_KEY_LOOPBACK "loopback"
|
#define MSG_KEY_LOOPBACK "loopback"
|
||||||
|
@ -36,6 +40,7 @@
|
||||||
#define TX_BUFF_SIZE 32
|
#define TX_BUFF_SIZE 32
|
||||||
#define RX_BUFF_SIZE 32
|
#define RX_BUFF_SIZE 32
|
||||||
#define CDC_LOOPBACK_REPS 1200
|
#define CDC_LOOPBACK_REPS 1200
|
||||||
|
#define SERIAL_LOOPBACK_REPS 100
|
||||||
#define USB_RECONNECT_DELAY_MS 200
|
#define USB_RECONNECT_DELAY_MS 200
|
||||||
|
|
||||||
using utest::v1::Case;
|
using utest::v1::Case;
|
||||||
|
@ -304,6 +309,202 @@ void test_cdc_loopback()
|
||||||
usb_cdc.disconnect();
|
usb_cdc.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Test Serial USB reconnect
|
||||||
|
*
|
||||||
|
* Given the host has successfully opened the port of a USB Serial device
|
||||||
|
* When the USB device disconnects and connects again
|
||||||
|
* Then the host is able to successfully open the port again
|
||||||
|
*/
|
||||||
|
void test_serial_usb_reconnect()
|
||||||
|
{
|
||||||
|
USBSerial usb_serial(false, USB_SERIAL_VID, USB_SERIAL_PID);
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
// Connect the USB device.
|
||||||
|
usb_serial.connect();
|
||||||
|
// Wait for the USB enumeration to complete.
|
||||||
|
while (!usb_serial.configured()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
if (!send_testcase_data(MSG_KEY_PORT_OPEN_WAIT, USB_SERIAL_VID, USB_SERIAL_PID)) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Wait for the host to open the port.
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
// Disconnect the USB device.
|
||||||
|
usb_serial.disconnect();
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
wait_ms(USB_RECONNECT_DELAY_MS);
|
||||||
|
// Connect the USB device again.
|
||||||
|
usb_serial.connect();
|
||||||
|
// Wait for the USB enumeration to complete.
|
||||||
|
while (!usb_serial.configured()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
if (!send_testcase_data(MSG_KEY_PORT_OPEN_WAIT, USB_SERIAL_VID, USB_SERIAL_PID)) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Wait for the host to open the port again.
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
// Disconnect the USB device again.
|
||||||
|
usb_serial.disconnect();
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Test Serial terminal reopen
|
||||||
|
*
|
||||||
|
* Given the host has successfully opened the port of a USB Serial device
|
||||||
|
* When the host closes its port
|
||||||
|
* Then the host is able to successfully open the port again
|
||||||
|
*/
|
||||||
|
void test_serial_term_reopen()
|
||||||
|
{
|
||||||
|
USBSerial usb_serial(false, USB_SERIAL_VID, USB_SERIAL_PID);
|
||||||
|
usb_serial.connect();
|
||||||
|
if (!send_testcase_data(MSG_KEY_PORT_OPEN_CLOSE, USB_SERIAL_VID, USB_SERIAL_PID)) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Wait for the host to open the terminal.
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.ready());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
// Wait for the host to close the terminal.
|
||||||
|
while (usb_serial.ready()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.ready());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
if (!send_testcase_data(MSG_KEY_PORT_OPEN_CLOSE, USB_SERIAL_VID, USB_SERIAL_PID)) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Wait for the host to open the terminal again.
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.ready());
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
// Wait for the host to close the terminal again.
|
||||||
|
while (usb_serial.ready()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
TEST_ASSERT_TRUE(usb_serial.configured());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.ready());
|
||||||
|
TEST_ASSERT_FALSE(usb_serial.connected());
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, usb_serial.readable());
|
||||||
|
|
||||||
|
usb_serial.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Test Serial getc
|
||||||
|
*
|
||||||
|
* Given the USB Serial device connected to a host
|
||||||
|
* When the host transmits a known sequence one byte at a time
|
||||||
|
* Then every byte received by the device matches the sequence
|
||||||
|
*/
|
||||||
|
void test_serial_getc()
|
||||||
|
{
|
||||||
|
USBSerial usb_serial(false, USB_SERIAL_VID, USB_SERIAL_PID);
|
||||||
|
usb_serial.connect();
|
||||||
|
if (send_testcase_data(MSG_KEY_SEND_BYTES_SINGLE, USB_SERIAL_VID, USB_SERIAL_PID) == false) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
for (int expected = 0xff; expected >= 0; expected--) {
|
||||||
|
TEST_ASSERT_EQUAL_INT(expected, usb_serial.getc());
|
||||||
|
}
|
||||||
|
for (int expected = 0; expected <= 0xff; expected++) {
|
||||||
|
TEST_ASSERT_EQUAL_INT(expected, usb_serial.getc());
|
||||||
|
}
|
||||||
|
// Wait for the host to close its port.
|
||||||
|
while (usb_serial.ready()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
usb_serial.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Test Serial printf & scanf
|
||||||
|
*
|
||||||
|
* Given the USB Serial device connected to a host
|
||||||
|
* When the device trensmits a formatted string with a random value
|
||||||
|
* using the printf method
|
||||||
|
* and the host sends it back to the device
|
||||||
|
* Then the device can successfully read the value using scanf method
|
||||||
|
* and the value received is equal value sent
|
||||||
|
*/
|
||||||
|
void test_serial_printf_scanf()
|
||||||
|
{
|
||||||
|
USBSerial usb_serial(false, USB_SERIAL_VID, USB_SERIAL_PID);
|
||||||
|
usb_serial.connect();
|
||||||
|
if (!send_testcase_data(MSG_KEY_LOOPBACK, USB_SERIAL_VID, USB_SERIAL_PID)) {
|
||||||
|
TEST_ASSERT_MESSAGE(0, "Dev-host communication error.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (!usb_serial.connected()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
static const char fmt[] = "Formatted\nstring %i.";
|
||||||
|
int tx_val, rx_val, rc;
|
||||||
|
for (int i = 0; i < SERIAL_LOOPBACK_REPS; i++) {
|
||||||
|
tx_val = rand();
|
||||||
|
rx_val = tx_val + 1;
|
||||||
|
rc = usb_serial.printf(fmt, tx_val);
|
||||||
|
TEST_ASSERT(rc > 0);
|
||||||
|
rc = usb_serial.scanf(fmt, &rx_val);
|
||||||
|
TEST_ASSERT(rc == 1);
|
||||||
|
TEST_ASSERT_EQUAL_INT(tx_val, rx_val);
|
||||||
|
}
|
||||||
|
// Wait for the host to close its port.
|
||||||
|
while (usb_serial.ready()) {
|
||||||
|
wait_ms(1);
|
||||||
|
}
|
||||||
|
usb_serial.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
utest::v1::status_t testsuite_setup(const size_t number_of_cases)
|
utest::v1::status_t testsuite_setup(const size_t number_of_cases)
|
||||||
{
|
{
|
||||||
GREENTEA_SETUP(25, "usb_device_serial");
|
GREENTEA_SETUP(25, "usb_device_serial");
|
||||||
|
@ -318,6 +519,10 @@ Case cases[] = {
|
||||||
Case("CDC RX multiple bytes", test_cdc_rx_multiple_bytes),
|
Case("CDC RX multiple bytes", test_cdc_rx_multiple_bytes),
|
||||||
Case("CDC RX multiple bytes concurrent", test_cdc_rx_multiple_bytes_concurrent),
|
Case("CDC RX multiple bytes concurrent", test_cdc_rx_multiple_bytes_concurrent),
|
||||||
Case("CDC loopback", test_cdc_loopback),
|
Case("CDC loopback", test_cdc_loopback),
|
||||||
|
Case("Serial USB reconnect", test_serial_usb_reconnect),
|
||||||
|
Case("Serial terminal reopen", test_serial_term_reopen),
|
||||||
|
Case("Serial getc", test_serial_getc),
|
||||||
|
Case("Serial printf/scanf", test_serial_printf_scanf),
|
||||||
};
|
};
|
||||||
|
|
||||||
Specification specification(testsuite_setup, cases);
|
Specification specification(testsuite_setup, cases);
|
||||||
|
|
Loading…
Reference in New Issue