Merge pull request #12917 from rajkan01/usb_serial_greentea

Bare metal profile: Enable USB serial greentea test
pull/12973/head
Martin Kojtal 2020-05-14 10:49:39 +02:00 committed by GitHub
commit 595754dffa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 69 additions and 48 deletions

View File

@ -19,10 +19,6 @@
#error [NOT_SUPPORTED] usb device tests not enabled #error [NOT_SUPPORTED] usb device tests not enabled
#else #else
#if !defined(MBED_CONF_RTOS_PRESENT)
#error [NOT_SUPPORTED] USB stack and test cases require RTOS to run.
#else
#if !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE #if !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE
#error [NOT_SUPPORTED] USB Device not supported for this target #error [NOT_SUPPORTED] USB Device not supported for this target
#else #else
@ -78,11 +74,11 @@
// The solution is to wait for the first DTR spike, ignore it, and wait for // The solution is to wait for the first DTR spike, ignore it, and wait for
// the correct DTR signal again. // the correct DTR signal again.
#define LINUX_HOST_DTR_FIX 1 #define LINUX_HOST_DTR_FIX 1
#define LINUX_HOST_DTR_FIX_DELAY_MS 1 #define LINUX_HOST_DTR_FIX_DELAY_MS 1ms
#define CDC_LOOPBACK_REPS 1200 #define CDC_LOOPBACK_REPS 1200
#define SERIAL_LOOPBACK_REPS 100 #define SERIAL_LOOPBACK_REPS 100
#define USB_RECONNECT_DELAY_MS 1 #define USB_RECONNECT_DELAY_MS 1ms
#define LINE_CODING_SEP (',') #define LINE_CODING_SEP (',')
#define LINE_CODING_DELIM (';') #define LINE_CODING_DELIM (';')
@ -153,8 +149,7 @@ line_coding_t test_codings[] = {
{ 9600, 8, 0, 0 }, { 9600, 8, 0, 0 },
{ 57600, 8, 0, 0 }, { 57600, 8, 0, 0 },
}; };
static CircularBuffer<line_coding_t, 8> lc_data;
Mail<line_coding_t, 8> lc_mail;
#define EF_SEND (1ul << 0) #define EF_SEND (1ul << 0)
EventFlags event_flags; EventFlags event_flags;
@ -297,7 +292,7 @@ void test_cdc_usb_reconnect()
usb_cdc.connect(); usb_cdc.connect();
// Wait for the USB enumeration to complete. // Wait for the USB enumeration to complete.
while (!usb_cdc.configured()) { while (!usb_cdc.configured()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_cdc.configured()); TEST_ASSERT_TRUE(usb_cdc.configured());
TEST_ASSERT_FALSE(usb_cdc.ready()); TEST_ASSERT_FALSE(usb_cdc.ready());
@ -322,7 +317,7 @@ void test_cdc_usb_reconnect()
usb_cdc.connect(); usb_cdc.connect();
// Wait for the USB enumeration to complete. // Wait for the USB enumeration to complete.
while (!usb_cdc.configured()) { while (!usb_cdc.configured()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_cdc.configured()); TEST_ASSERT_TRUE(usb_cdc.configured());
TEST_ASSERT_FALSE(usb_cdc.ready()); TEST_ASSERT_FALSE(usb_cdc.ready());
@ -370,7 +365,7 @@ void test_cdc_rx_single_bytes()
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_cdc.ready()) { while (usb_cdc.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_cdc.disconnect(); usb_cdc.disconnect();
} }
@ -381,7 +376,7 @@ void tx_thread_fun(USBCDC *usb_cdc)
uint8_t buff[TX_BUFF_SIZE] = { 0 }; uint8_t buff[TX_BUFF_SIZE] = { 0 };
while (event_flags.get() & EF_SEND) { while (event_flags.get() & EF_SEND) {
if (!usb_cdc->send(buff, TX_BUFF_SIZE)) { if (!usb_cdc->send(buff, TX_BUFF_SIZE)) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
continue; continue;
} }
buff_val++; buff_val++;
@ -389,6 +384,17 @@ void tx_thread_fun(USBCDC *usb_cdc)
} }
} }
void tx_ticker_fun(USBCDC *usb_cdc, uint8_t start_val, uint8_t size = TX_BUFF_SIZE)
{
static uint8_t buff_val = start_val;
uint32_t actual_tx = 0;
uint8_t buff[TX_BUFF_SIZE] = { 0 };
memset(buff, buff_val, size);
usb_cdc->send_nb(buff, size, &actual_tx);
TEST_ASSERT_EQUAL_UINT8(size, actual_tx);
buff_val++;
}
/** Test CDC receive single bytes concurrently /** Test CDC receive single bytes concurrently
* *
* Given the USB CDC device connected to a host * Given the USB CDC device connected to a host
@ -406,9 +412,15 @@ void test_cdc_rx_single_bytes_concurrent()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
usb_cdc.wait_ready(); usb_cdc.wait_ready();
#if defined(MBED_CONF_RTOS_PRESENT)
Thread tx_thread; Thread tx_thread;
event_flags.set(EF_SEND); event_flags.set(EF_SEND);
tx_thread.start(mbed::callback(tx_thread_fun, &usb_cdc)); tx_thread.start(mbed::callback(tx_thread_fun, &usb_cdc));
#else
Ticker t;
t.attach([&] { tx_ticker_fun(&usb_cdc, 0, 1); }, 2ms);
#endif
uint8_t buff = 0x01; uint8_t buff = 0x01;
for (int expected = 0xff; expected >= 0; expected--) { for (int expected = 0xff; expected >= 0; expected--) {
TEST_ASSERT(usb_cdc.receive(&buff, 1, NULL)); TEST_ASSERT(usb_cdc.receive(&buff, 1, NULL));
@ -418,11 +430,16 @@ void test_cdc_rx_single_bytes_concurrent()
TEST_ASSERT(usb_cdc.receive(&buff, 1, NULL)); TEST_ASSERT(usb_cdc.receive(&buff, 1, NULL));
TEST_ASSERT_EQUAL_UINT8(expected, buff); TEST_ASSERT_EQUAL_UINT8(expected, buff);
} }
#if defined(MBED_CONF_RTOS_PRESENT)
event_flags.clear(EF_SEND); event_flags.clear(EF_SEND);
tx_thread.join(); tx_thread.join();
#else
t.detach();
#endif
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_cdc.ready()) { while (usb_cdc.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_cdc.disconnect(); usb_cdc.disconnect();
} }
@ -461,7 +478,7 @@ void test_cdc_rx_multiple_bytes()
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_cdc.ready()) { while (usb_cdc.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_cdc.disconnect(); usb_cdc.disconnect();
} }
@ -483,9 +500,14 @@ void test_cdc_rx_multiple_bytes_concurrent()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
usb_cdc.wait_ready(); usb_cdc.wait_ready();
#if defined(MBED_CONF_RTOS_PRESENT)
Thread tx_thread; Thread tx_thread;
event_flags.set(EF_SEND); event_flags.set(EF_SEND);
tx_thread.start(mbed::callback(tx_thread_fun, &usb_cdc)); tx_thread.start(mbed::callback(tx_thread_fun, &usb_cdc));
#else
Ticker t;
t.attach([&] { tx_ticker_fun(&usb_cdc, 0); }, 3ms);
#endif
uint8_t buff[RX_BUFF_SIZE] = { 0 }; uint8_t buff[RX_BUFF_SIZE] = { 0 };
uint8_t expected_buff[RX_BUFF_SIZE] = { 0 }; uint8_t expected_buff[RX_BUFF_SIZE] = { 0 };
for (int expected = 0xff; expected >= 0; expected--) { for (int expected = 0xff; expected >= 0; expected--) {
@ -502,11 +524,15 @@ void test_cdc_rx_multiple_bytes_concurrent()
TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_buff, buff, RX_BUFF_SIZE); TEST_ASSERT_EQUAL_UINT8_ARRAY(expected_buff, buff, RX_BUFF_SIZE);
} }
} }
#if defined(MBED_CONF_RTOS_PRESENT)
event_flags.clear(EF_SEND); event_flags.clear(EF_SEND);
tx_thread.join(); tx_thread.join();
#else
t.detach();
#endif
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_cdc.ready()) { while (usb_cdc.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_cdc.disconnect(); usb_cdc.disconnect();
} }
@ -538,7 +564,7 @@ void test_cdc_loopback()
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_cdc.ready()) { while (usb_cdc.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_cdc.disconnect(); usb_cdc.disconnect();
} }
@ -560,7 +586,7 @@ void test_serial_usb_reconnect()
usb_serial.connect(); usb_serial.connect();
// Wait for the USB enumeration to complete. // Wait for the USB enumeration to complete.
while (!usb_serial.configured()) { while (!usb_serial.configured()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_FALSE(usb_serial.connected()); TEST_ASSERT_FALSE(usb_serial.connected());
@ -573,7 +599,7 @@ void test_serial_usb_reconnect()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
while (!usb_serial.connected()) { while (!usb_serial.connected()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_TRUE(usb_serial.connected()); TEST_ASSERT_TRUE(usb_serial.connected());
@ -590,7 +616,7 @@ void test_serial_usb_reconnect()
usb_serial.connect(); usb_serial.connect();
// Wait for the USB enumeration to complete. // Wait for the USB enumeration to complete.
while (!usb_serial.configured()) { while (!usb_serial.configured()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_FALSE(usb_serial.connected()); TEST_ASSERT_FALSE(usb_serial.connected());
@ -603,7 +629,7 @@ void test_serial_usb_reconnect()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
while (!usb_serial.connected()) { while (!usb_serial.connected()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_TRUE(usb_serial.connected()); TEST_ASSERT_TRUE(usb_serial.connected());
@ -633,7 +659,7 @@ void test_serial_term_reopen()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
while (!usb_serial.connected()) { while (!usb_serial.connected()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_TRUE(usb_serial.ready()); TEST_ASSERT_TRUE(usb_serial.ready());
@ -642,7 +668,7 @@ void test_serial_term_reopen()
// Wait for the host to close the terminal. // Wait for the host to close the terminal.
while (usb_serial.ready()) { while (usb_serial.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_FALSE(usb_serial.ready()); TEST_ASSERT_FALSE(usb_serial.ready());
@ -656,7 +682,7 @@ void test_serial_term_reopen()
ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS); ThisThread::sleep_for(LINUX_HOST_DTR_FIX_DELAY_MS);
#endif #endif
while (!usb_serial.connected()) { while (!usb_serial.connected()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_TRUE(usb_serial.ready()); TEST_ASSERT_TRUE(usb_serial.ready());
@ -665,7 +691,7 @@ void test_serial_term_reopen()
// Wait for the host to close the terminal again. // Wait for the host to close the terminal again.
while (usb_serial.ready()) { while (usb_serial.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
TEST_ASSERT_TRUE(usb_serial.configured()); TEST_ASSERT_TRUE(usb_serial.configured());
TEST_ASSERT_FALSE(usb_serial.ready()); TEST_ASSERT_FALSE(usb_serial.ready());
@ -699,7 +725,7 @@ void test_serial_getc()
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_serial.ready()) { while (usb_serial.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_serial.disconnect(); usb_serial.disconnect();
} }
@ -736,19 +762,21 @@ void test_serial_printf_scanf()
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_serial.ready()) { while (usb_serial.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_serial.disconnect(); usb_serial.disconnect();
} }
void line_coding_changed_cb(int baud, int bits, int parity, int stop) void line_coding_changed_cb(int baud, int bits, int parity, int stop)
{ {
line_coding_t *lc = lc_mail.alloc(); line_coding_t lc = {
lc->baud = baud; .baud = baud,
lc->bits = bits; .bits = bits,
lc->parity = parity; .parity = parity,
lc->stop = stop; .stop = stop
lc_mail.put(lc); };
lc_data.push(lc);
event_flags.set(EF_SEND);
} }
/** Test Serial / CDC line coding change /** Test Serial / CDC line coding change
@ -772,9 +800,9 @@ void test_serial_line_coding_change()
size_t num_line_codings = sizeof test_codings / sizeof test_codings[0]; size_t num_line_codings = sizeof test_codings / sizeof test_codings[0];
line_coding_t *lc_prev = &default_lc; line_coding_t *lc_prev = &default_lc;
line_coding_t *lc_expected = NULL; line_coding_t *lc_expected = NULL;
line_coding_t *lc_actual = NULL;
int num_expected_callbacks, rc; int num_expected_callbacks, rc;
for (size_t i = 0; i < num_line_codings; i++) { for (size_t i = 0; i < num_line_codings; i++) {
line_coding_t lc_actual = {0};
lc_expected = &(test_codings[i]); lc_expected = &(test_codings[i]);
num_expected_callbacks = lc_prev->get_num_diffs(*lc_expected); num_expected_callbacks = lc_prev->get_num_diffs(*lc_expected);
rc = usb_serial.printf("%06i,%02i,%01i,%01i%c", lc_expected->baud, lc_expected->bits, lc_expected->parity, rc = usb_serial.printf("%06i,%02i,%01i,%01i%c", lc_expected->baud, lc_expected->bits, lc_expected->parity,
@ -786,27 +814,21 @@ void test_serial_line_coding_change()
// calls to line_coding_changed callback on the device. // calls to line_coding_changed callback on the device.
while (num_expected_callbacks > 0) { while (num_expected_callbacks > 0) {
num_expected_callbacks--; num_expected_callbacks--;
osEvent event = lc_mail.get(); event_flags.wait_all(EF_SEND);
TEST_ASSERT_EQUAL_UINT32(osEventMail, event.status); lc_data.pop(lc_actual);
lc_actual = (line_coding_t *) event.value.p; if (lc_expected->get_num_diffs(lc_actual) == 0) {
if (lc_expected->get_num_diffs(*lc_actual) == 0) {
break; break;
} else if (num_expected_callbacks > 0) {
// Discard lc_actual only if there is still a chance to get new
// set of params.
lc_mail.free(lc_actual);
} }
} }
TEST_ASSERT_EQUAL_INT(lc_expected->baud, lc_actual->baud); TEST_ASSERT_EQUAL_INT(lc_expected->baud, lc_actual.baud);
TEST_ASSERT_EQUAL_INT(lc_expected->bits, lc_actual->bits); TEST_ASSERT_EQUAL_INT(lc_expected->bits, lc_actual.bits);
TEST_ASSERT_EQUAL_INT(lc_expected->parity, lc_actual->parity); TEST_ASSERT_EQUAL_INT(lc_expected->parity, lc_actual.parity);
TEST_ASSERT_EQUAL_INT(lc_expected->stop, lc_actual->stop); TEST_ASSERT_EQUAL_INT(lc_expected->stop, lc_actual.stop);
lc_mail.free(lc_actual);
lc_prev = lc_expected; lc_prev = lc_expected;
} }
// Wait for the host to close its port. // Wait for the host to close its port.
while (usb_serial.ready()) { while (usb_serial.ready()) {
ThisThread::sleep_for(1); ThisThread::sleep_for(1ms);
} }
usb_serial.disconnect(); usb_serial.disconnect();
} }
@ -858,5 +880,4 @@ int main()
} }
#endif // !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE #endif // !defined(DEVICE_USBDEVICE) || !DEVICE_USBDEVICE
#endif // !defined(MBED_CONF_RTOS_PRESENT)
#endif // !defined(USB_DEVICE_TESTS) #endif // !defined(USB_DEVICE_TESTS)