Merge pull request #4369 from bridadan/networking_test_update

Increase DHCP timeout, and rework networking tests logic
pull/4521/merge
Sam Grove 2017-06-10 15:31:16 -05:00 committed by GitHub
commit f56d64f0f5
21 changed files with 698 additions and 131 deletions

View File

@ -51,13 +51,13 @@ void test_bring_up_down() {
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(60, "default_auto");
GREENTEA_SETUP(120, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("Testing bringing the network up and down", test_bring_up_down<1>),
Case("Testing bringing the network up and down twice", test_bring_up_down<2>),
Case("Bringing the network up and down", test_bring_up_down<1>),
Case("Bringing the network up and down twice", test_bring_up_down<2>),
};
Specification specification(test_setup, cases);

View File

@ -91,16 +91,16 @@ void test_dns_literal_pref() {
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(60, "default_auto");
GREENTEA_SETUP(120, "default_auto");
net_bringup();
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("Testing DNS query", test_dns_query),
Case("Testing DNS preference query", test_dns_query_pref),
Case("Testing DNS literal", test_dns_literal),
Case("Testing DNS preference literal", test_dns_literal_pref),
Case("DNS query", test_dns_query),
Case("DNS preference query", test_dns_query_pref),
Case("DNS literal", test_dns_literal),
Case("DNS preference literal", test_dns_literal_pref),
};
Specification specification(test_setup, cases);

View File

@ -10,6 +10,9 @@
#include "TCPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE
@ -28,11 +31,14 @@ void prep_buffer(char *tx_buffer, size_t tx_size) {
}
}
int main() {
GREENTEA_SETUP(60, "tcp_echo");
void test_tcp_echo() {
EthernetInterface eth;
eth.connect();
int err = eth.connect();
if (err) {
printf("MBED: failed to connect with an error of %d\r\n", err);
TEST_ASSERT_EQUAL(0, err);
}
printf("MBED: TCPClient IP address is '%s'\n", eth.get_ip_address());
printf("MBED: TCPClient waiting for server IP and port...\n");
@ -64,17 +70,34 @@ int main() {
prep_buffer(tx_buffer, sizeof(tx_buffer));
sock.send(tx_buffer, sizeof(tx_buffer));
printf("MBED: Finished sending\r\n");
// Server will respond with HTTP GET's success code
const int ret = sock.recv(rx_buffer, sizeof(rx_buffer));
printf("MBED: Finished receiving\r\n");
result = !memcmp(tx_buffer, rx_buffer, sizeof(tx_buffer));
TEST_ASSERT_EQUAL(ret, sizeof(rx_buffer));
TEST_ASSERT_EQUAL(true, result);
TEST_ASSERT(result);
}
sock.close();
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
TEST_ASSERT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("TCP echo", test_tcp_echo),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -10,6 +10,9 @@
#include "TCPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE
@ -64,7 +67,7 @@ public:
TEST_ASSERT_EQUAL(0, err);
iomutex.lock();
printf("HTTP: Connected to %s:%d\r\n",
printf("HTTP: Connected to %s:%d\r\n",
tcp_addr.get_ip_address(), tcp_addr.get_port());
printf("tx_buffer buffer size: %u\r\n", sizeof(tx_buffer));
printf("rx_buffer buffer size: %u\r\n", sizeof(rx_buffer));
@ -77,18 +80,16 @@ public:
const int ret = sock.recv(rx_buffer, sizeof(rx_buffer));
bool result = !memcmp(tx_buffer, rx_buffer, sizeof(tx_buffer));
TEST_ASSERT_EQUAL(ret, sizeof(rx_buffer));
TEST_ASSERT_EQUAL(true, result);
TEST_ASSERT(result);
err = sock.close();
TEST_ASSERT_EQUAL(0, err);
}
};
int main() {
GREENTEA_SETUP(60, "tcp_echo");
Echo echoers[MBED_CFG_TCP_CLIENT_ECHO_THREADS];
Echo *echoers[MBED_CFG_TCP_CLIENT_ECHO_THREADS];
void test_tcp_echo_parallel() {
int err = net.connect();
TEST_ASSERT_EQUAL(0, err);
@ -115,13 +116,30 @@ int main() {
// Startup echo threads in parallel
for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
echoers[i].start();
echoers[i] = new Echo;
echoers[i]->start();
}
for (int i = 0; i < MBED_CFG_TCP_CLIENT_ECHO_THREADS; i++) {
echoers[i].join();
echoers[i]->join();
delete echoers[i];
}
net.disconnect();
GREENTEA_TESTSUITE_RESULT(true);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("TCP echo parallel", test_tcp_echo_parallel),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -11,6 +11,10 @@
#include "TCPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
namespace {
// Test connection information
@ -35,9 +39,7 @@ bool find_substring(const char *first, const char *last, const char *s_first, co
return (f != last);
}
int main() {
GREENTEA_SETUP(60, "default_auto");
void test_tcp_hello_world() {
bool result = false;
EthernetInterface eth;
//eth.init(); //Use DHCP
@ -67,8 +69,8 @@ int main() {
// Find "Hello World!" string in reply
bool found_hello = find_substring(buffer, buffer + ret, HTTP_HELLO_STR, HTTP_HELLO_STR + strlen(HTTP_HELLO_STR));
TEST_ASSERT_TRUE(found_200_ok);
TEST_ASSERT_TRUE(found_hello);
TEST_ASSERT(found_200_ok);
TEST_ASSERT(found_hello);
if (found_200_ok && found_hello) result = true;
@ -83,5 +85,22 @@ int main() {
}
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
TEST_ASSERT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("TCP hello world", test_tcp_hello_world),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -13,6 +13,9 @@
#include "TCPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
@ -107,8 +110,7 @@ void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
}
int main() {
GREENTEA_SETUP(60, "tcp_echo");
void test_tcp_packet_pressure() {
generate_buffer(&buffer, &buffer_size,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX);
@ -123,8 +125,6 @@ int main() {
greentea_send_kv("target_ip", eth.get_ip_address());
bool result = true;
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
@ -219,9 +219,25 @@ int main() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("TCP packet pressure", test_tcp_packet_pressure),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -13,6 +13,9 @@
#include "TCPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN
@ -224,9 +227,7 @@ public:
PressureTest *pressure_tests[MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS];
int main() {
GREENTEA_SETUP(2*60, "tcp_echo");
void test_tcp_packet_pressure_parallel() {
uint8_t *buffer;
size_t buffer_size;
generate_buffer(&buffer, &buffer_size,
@ -247,8 +248,6 @@ int main() {
greentea_send_kv("target_ip", net.get_ip_address());
bool result = true;
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
@ -282,9 +281,25 @@ int main() {
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_THREADS*
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
8*(2*MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_TCP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
net.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "tcp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("TCP packet pressure parallel", test_tcp_packet_pressure_parallel),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -10,6 +10,10 @@
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE
#define MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE 512
@ -23,13 +27,15 @@
#define MBED_CFG_UDP_DTLS_HANDSHAKE_PATTERN 112, 384, 200, 219, 25
#endif
#ifndef MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT
#define MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT 1500
#endif
uint8_t buffer[MBED_CFG_UDP_DTLS_HANDSHAKE_BUFFER_SIZE] = {0};
int udp_dtls_handshake_pattern[] = {MBED_CFG_UDP_DTLS_HANDSHAKE_PATTERN};
const int udp_dtls_handshake_count = sizeof(udp_dtls_handshake_pattern) / sizeof(int);
int main() {
GREENTEA_SETUP(60, "udp_shotgun");
void test_udp_dtls_handshake() {
EthernetInterface eth;
int err = eth.connect();
TEST_ASSERT_EQUAL(0, err);
@ -71,6 +77,7 @@ int main() {
UDPSocket sock;
SocketAddress udp_addr(ipbuf, port);
sock.set_timeout(MBED_CFG_UDP_DTLS_HANDSHAKE_TIMEOUT);
for (int attempt = 0; attempt < MBED_CFG_UDP_DTLS_HANDSHAKE_RETRIES; attempt++) {
err = sock.open(&eth);
@ -122,5 +129,22 @@ int main() {
}
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
TEST_ASSERT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "udp_shotgun");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("UDP DTLS handshake", test_udp_dtls_handshake),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -10,9 +10,13 @@
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 256
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
#endif
#ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
@ -25,19 +29,35 @@ namespace {
char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
const char ASCII_MAX = '~' - ' ';
const int ECHO_LOOPS = 16;
char uuid[GREENTEA_UUID_LENGTH] = {0};
}
void prep_buffer(char *tx_buffer, size_t tx_size) {
for (size_t i=0; i<tx_size; ++i) {
// Creates a buffer that contains the test's UUID in the first part of the contents
// so the output can be associated with individual test runs. The rest of the
// buffer is filled with random data so it is unique within the CURRENT test run.
//
// Ex. A test with UUID of `33e5002c-9722-4685-817a-709cc69c4701` would have a
// buffer filled with something like `33e5002c-9722-4685-817a-709cc69c4701 12594387`
// where `33e5002c-9722-4685-817a-709cc69c4701` is the UUID and `12594387` is the random data
void prep_buffer(char *uuid, char *tx_buffer, size_t tx_size) {
size_t i = 0;
memcpy(tx_buffer, uuid, strlen(uuid));
i += strlen(uuid);
tx_buffer[i++] = ' ';
for (; i<tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0';
}
}
int main() {
GREENTEA_SETUP(60, "udp_echo");
void test_udp_echo() {
EthernetInterface eth;
eth.connect();
int err = eth.connect();
TEST_ASSERT_EQUAL(0, err);
printf("UDP client IP Address is %s\n", eth.get_ip_address());
greentea_send_kv("target_ip", eth.get_ip_address());
@ -62,26 +82,63 @@ int main() {
SocketAddress udp_addr(ipbuf, port);
int success = 0;
for (int i=0; i < ECHO_LOOPS; ++i) {
prep_buffer(tx_buffer, sizeof(tx_buffer));
const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
printf("[%02d] sent...%d Bytes \n", i, ret);
for (unsigned int i = 0; success < ECHO_LOOPS; i++) {
prep_buffer(uuid, tx_buffer, sizeof(tx_buffer));
int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
if (ret >= 0) {
printf("[%02u] sent %d bytes - %.*s \n", i, ret, ret, tx_buffer);
} else {
printf("[%02u] Network error %d\n", i, ret);
continue;
}
SocketAddress temp_addr;
const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
printf("[%02d] recv...%d Bytes \n", i, n);
ret = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
if (ret >= 0) {
printf("[%02u] recv %d bytes - %.*s \n", i, ret, ret, tx_buffer);
} else {
printf("[%02u] Network error %d\n", i, ret);
continue;
}
if ((temp_addr == udp_addr &&
n == sizeof(tx_buffer) &&
ret == sizeof(tx_buffer) &&
memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
success += 1;
}
}
bool result = (success > 3*ECHO_LOOPS/4);
printf("[%02u] success #%d\n", i, success);
continue;
}
// failed, clean out any remaining bad packets
sock.set_timeout(0);
while (true) {
err = sock.recvfrom(NULL, NULL, 0);
if (err == NSAPI_ERROR_WOULD_BLOCK) {
break;
}
}
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
}
sock.close();
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
TEST_ASSERT_EQUAL(ECHO_LOOPS, success);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP_UUID(120, "udp_echo", uuid, GREENTEA_UUID_LENGTH);
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("UDP echo", test_udp_echo),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -10,6 +10,10 @@
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
@ -28,9 +32,34 @@ const int ECHO_LOOPS = 16;
EthernetInterface net;
SocketAddress udp_addr;
Mutex iomutex;
char uuid[GREENTEA_UUID_LENGTH] = {0};
void prep_buffer(char *tx_buffer, size_t tx_size) {
for (size_t i=0; i<tx_size; ++i) {
// NOTE: assuming that "id" stays in the single digits
//
// Creates a buffer that first contains the thread's id.
//
// The second part of the buffer contains the test's UUID so the output can be
// associated with individual test runs.
//
// The rest of the buffer is filled with random data so it is unique within the
// CURRENT test run.
//
// Ex. A thread with id "2" and a test with UUID of `33e5002c-9722-4685-817a-709cc69c4701`
// would have a buffer filled with something like `2 33e5002c-9722-4685-817a-709cc69c4701 12594387`
// where `2` is the thread id, `33e5002c-9722-4685-817a-709cc69c4701` is the UUID
// and `12594387` is the random data
void prep_buffer(unsigned int id, char *uuid, char *tx_buffer, size_t tx_size) {
size_t i = 0;
tx_buffer[i++] = '0' + id;
tx_buffer[i++] = ' ';
memcpy(tx_buffer+i, uuid, strlen(uuid));
i += strlen(uuid);
tx_buffer[i++] = ' ';
for (; i<tx_size; ++i) {
tx_buffer[i] = (rand() % 10) + '0';
}
}
@ -44,15 +73,19 @@ private:
UDPSocket sock;
Thread thread;
bool result;
unsigned int id;
char *uuid;
public:
// Limiting stack size to 1k
Echo(): thread(osPriorityNormal, 1024) {
Echo(): thread(osPriorityNormal, 1024), result(false) {
}
void start() {
void start(unsigned int id, char *uuid) {
this->id = id;
this->uuid = uuid;
osStatus status = thread.start(callback(this, &Echo::echo));
TEST_ASSERT_EQUAL(osOK, status);
}
void join() {
@ -68,40 +101,74 @@ public:
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
for (int i = 0; i < ECHO_LOOPS; i++) {
prep_buffer(tx_buffer, sizeof(tx_buffer));
const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
iomutex.lock();
printf("[%02d] sent...%d Bytes \n", i, ret);
iomutex.unlock();
for (unsigned int i = 0; success < ECHO_LOOPS; i++) {
prep_buffer(id, uuid, tx_buffer, sizeof(tx_buffer));
int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
if (ret >= 0) {
iomutex.lock();
printf("[ID:%01u][%02u] sent %d bytes - %.*s \n", id, i, ret, ret, tx_buffer);
iomutex.unlock();
} else {
iomutex.lock();
printf("[ID:%01u][%02u] Network error %d\n", id, i, ret);
iomutex.unlock();
continue;
}
SocketAddress temp_addr;
const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
iomutex.lock();
printf("[%02d] recv...%d Bytes \n", i, n);
iomutex.unlock();
ret = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
if (ret >= 0) {
iomutex.lock();
printf("[ID:%01u][%02u] recv %d bytes - %.*s \n", id, i, ret, ret, tx_buffer);
iomutex.unlock();
} else {
iomutex.lock();
printf("[ID:%01u][%02u] Network error %d\n", id, i, ret);
iomutex.unlock();
continue;
}
if ((temp_addr == udp_addr &&
n == sizeof(tx_buffer) &&
ret == sizeof(tx_buffer) &&
memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
success += 1;
iomutex.lock();
printf("[ID:%01u][%02u] success #%d\n", id, i, success);
iomutex.unlock();
continue;
}
// failed, clean out any remaining bad packets
sock.set_timeout(0);
while (true) {
err = sock.recvfrom(NULL, NULL, 0);
if (err == NSAPI_ERROR_WOULD_BLOCK) {
break;
}
}
sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
}
err = sock.close();
TEST_ASSERT_EQUAL(0, err);
result = success == ECHO_LOOPS;
TEST_ASSERT(success > 3*ECHO_LOOPS/4);
err = sock.close();
printf("[ID:%01u] Failed to close socket!\n", id);
if (err) {
result = false;
}
}
bool get_result() {
return result;
}
};
int main() {
GREENTEA_SETUP(60, "udp_echo");
Echo echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
Echo *echoers[MBED_CFG_UDP_CLIENT_ECHO_THREADS];
void test_udp_echo_parallel() {
int err = net.connect();
TEST_ASSERT_EQUAL(0, err);
printf("UDP client IP Address is %s\n", net.get_ip_address());
greentea_send_kv("target_ip", net.get_ip_address());
@ -123,14 +190,36 @@ int main() {
udp_addr.set_port(port);
// Startup echo threads in parallel
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i].start();
for (unsigned int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i] = new Echo;
echoers[i]->start(i, uuid);
}
for (int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i].join();
bool result = true;
for (unsigned int i = 0; i < MBED_CFG_UDP_CLIENT_ECHO_THREADS; i++) {
echoers[i]->join();
result = result && echoers[i]->get_result();
delete echoers[i];
}
net.disconnect();
GREENTEA_TESTSUITE_RESULT(true);
TEST_ASSERT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP_UUID(120, "udp_echo", uuid, GREENTEA_UUID_LENGTH);
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("UDP echo parallel", test_udp_echo_parallel),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -13,6 +13,9 @@
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
@ -110,8 +113,7 @@ void generate_buffer(uint8_t **buffer, size_t *size, size_t min, size_t max) {
TEST_ASSERT(buffer);
}
int main() {
GREENTEA_SETUP(60, "udp_echo");
void test_udp_packet_pressure() {
generate_buffer(&buffer, &buffer_size,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN,
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX);
@ -126,8 +128,6 @@ int main() {
greentea_send_kv("target_ip", eth.get_ip_address());
bool result = true;
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
@ -242,9 +242,25 @@ int main() {
timer.stop();
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
eth.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "udp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("UDP packet pressure", test_udp_packet_pressure),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -13,6 +13,9 @@
#include "UDPSocket.h"
#include "greentea-client/test_env.h"
#include "unity/unity.h"
#include "utest.h"
using namespace utest::v1;
#ifndef MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN
@ -249,9 +252,7 @@ public:
PressureTest *pressure_tests[MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS];
int main() {
GREENTEA_SETUP(2*60, "udp_echo");
void test_udp_packet_pressure_parallel() {
uint8_t *buffer;
size_t buffer_size;
generate_buffer(&buffer, &buffer_size,
@ -272,8 +273,6 @@ int main() {
greentea_send_kv("target_ip", net.get_ip_address());
bool result = true;
char recv_key[] = "host_port";
char ipbuf[60] = {0};
char portbuf[16] = {0};
@ -307,9 +306,25 @@ int main() {
printf("MBED: Time taken: %fs\r\n", timer.read());
printf("MBED: Speed: %.3fkb/s\r\n",
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_THREADS*
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
8*(2*MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MAX -
MBED_CFG_UDP_CLIENT_PACKET_PRESSURE_MIN) / (1000*timer.read()));
net.disconnect();
GREENTEA_TESTSUITE_RESULT(result);
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases) {
GREENTEA_SETUP(120, "udp_echo");
return verbose_test_setup_handler(number_of_cases);
}
Case cases[] = {
Case("UDP packet pressure parallel", test_udp_packet_pressure_parallel),
};
Specification specification(test_setup, cases);
int main() {
return !Harness::run(specification);
}

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stm32f4xx_hal.h"
void _eth_config_mac(ETH_HandleTypeDef *heth)
{
ETH_MACInitTypeDef macconf =
{
.Watchdog = ETH_WATCHDOG_ENABLE,
.Jabber = ETH_JABBER_ENABLE,
.InterFrameGap = ETH_INTERFRAMEGAP_96BIT,
.CarrierSense = ETH_CARRIERSENCE_ENABLE,
.ReceiveOwn = ETH_RECEIVEOWN_ENABLE,
.LoopbackMode = ETH_LOOPBACKMODE_DISABLE,
.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE,
.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE,
.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE,
.BackOffLimit = ETH_BACKOFFLIMIT_10,
.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE,
.ReceiveAll = ETH_RECEIVEAll_DISABLE,
.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE,
.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL,
.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE,
.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL,
.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE,
.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE, // Disable multicast filter
.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT,
.HashTableHigh = 0x0U,
.HashTableLow = 0x0U,
.PauseTime = 0x0U,
.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE,
.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4,
.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,
.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE,
.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE,
.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT,
.VLANTagIdentifier = 0x0U,
};
if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
} else {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
}
(void) HAL_ETH_ConfigMAC(heth, &macconf);
}

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stm32f4xx_hal.h"
void _eth_config_mac(ETH_HandleTypeDef *heth)
{
ETH_MACInitTypeDef macconf =
{
.Watchdog = ETH_WATCHDOG_ENABLE,
.Jabber = ETH_JABBER_ENABLE,
.InterFrameGap = ETH_INTERFRAMEGAP_96BIT,
.CarrierSense = ETH_CARRIERSENCE_ENABLE,
.ReceiveOwn = ETH_RECEIVEOWN_ENABLE,
.LoopbackMode = ETH_LOOPBACKMODE_DISABLE,
.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE,
.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE,
.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE,
.BackOffLimit = ETH_BACKOFFLIMIT_10,
.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE,
.ReceiveAll = ETH_RECEIVEAll_DISABLE,
.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE,
.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL,
.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE,
.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL,
.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE,
.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE, // Disable multicast filter
.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT,
.HashTableHigh = 0x0U,
.HashTableLow = 0x0U,
.PauseTime = 0x0U,
.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE,
.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4,
.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,
.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE,
.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE,
.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT,
.VLANTagIdentifier = 0x0U,
};
if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
} else {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
}
(void) HAL_ETH_ConfigMAC(heth, &macconf);
}

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stm32f4xx_hal.h"
void _eth_config_mac(ETH_HandleTypeDef *heth)
{
ETH_MACInitTypeDef macconf =
{
.Watchdog = ETH_WATCHDOG_ENABLE,
.Jabber = ETH_JABBER_ENABLE,
.InterFrameGap = ETH_INTERFRAMEGAP_96BIT,
.CarrierSense = ETH_CARRIERSENCE_ENABLE,
.ReceiveOwn = ETH_RECEIVEOWN_ENABLE,
.LoopbackMode = ETH_LOOPBACKMODE_DISABLE,
.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE,
.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE,
.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE,
.BackOffLimit = ETH_BACKOFFLIMIT_10,
.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE,
.ReceiveAll = ETH_RECEIVEAll_DISABLE,
.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE,
.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL,
.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE,
.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL,
.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE,
.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE, // Disable multicast filter
.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT,
.HashTableHigh = 0x0U,
.HashTableLow = 0x0U,
.PauseTime = 0x0U,
.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE,
.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4,
.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,
.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE,
.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE,
.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT,
.VLANTagIdentifier = 0x0U,
};
if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
} else {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
}
(void) HAL_ETH_ConfigMAC(heth, &macconf);
}

View File

@ -0,0 +1,61 @@
/* mbed Microcontroller Library
* Copyright (c) 2017 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "stm32f4xx_hal.h"
void _eth_config_mac(ETH_HandleTypeDef *heth)
{
ETH_MACInitTypeDef macconf =
{
.Watchdog = ETH_WATCHDOG_ENABLE,
.Jabber = ETH_JABBER_ENABLE,
.InterFrameGap = ETH_INTERFRAMEGAP_96BIT,
.CarrierSense = ETH_CARRIERSENCE_ENABLE,
.ReceiveOwn = ETH_RECEIVEOWN_ENABLE,
.LoopbackMode = ETH_LOOPBACKMODE_DISABLE,
.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE,
.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE,
.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE,
.BackOffLimit = ETH_BACKOFFLIMIT_10,
.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE,
.ReceiveAll = ETH_RECEIVEAll_DISABLE,
.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE,
.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL,
.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE,
.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL,
.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE,
.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_NONE, // Disable multicast filter
.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT,
.HashTableHigh = 0x0U,
.HashTableLow = 0x0U,
.PauseTime = 0x0U,
.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE,
.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4,
.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE,
.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE,
.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE,
.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT,
.VLANTagIdentifier = 0x0U,
};
if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
} else {
macconf.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
}
(void) HAL_ETH_ConfigMAC(heth, &macconf);
}

View File

@ -47,8 +47,6 @@ static nsapi_error_t mbed_lwip_err_remap(err_t err);
#define MBED_NETIF_INIT_FN eth_arch_enetif_init
#endif
#define DHCP_TIMEOUT 15000
/* Static arena of sockets */
static struct lwip_socket {
bool in_use;
@ -550,6 +548,7 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
#endif /* LWIP_IPV6_AUTOCONFIG */
#endif // LWIP_IPV6
#if LWIP_IPV4
if (!dhcp && !ppp) {
ip4_addr_t ip_addr;
@ -600,10 +599,11 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
// If doesn't have address
if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) {
if (sys_arch_sem_wait(&lwip_netif_has_addr, 15000) == SYS_ARCH_TIMEOUT) {
if (sys_arch_sem_wait(&lwip_netif_has_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) {
if (ppp) {
ppp_lwip_disconnect();
}
return NSAPI_ERROR_DHCP_FAILURE;
}
}

View File

@ -52,6 +52,8 @@
#define ADDR_TIMEOUT 0
#endif
#define DHCP_TIMEOUT 60
#define PREF_IPV4 1
#define PREF_IPV6 2

View File

@ -43,6 +43,11 @@
#define TEST_ENV_TESTCASE_FINISH GREENTEA_TEST_ENV_TESTCASE_FINISH
#define TEST_ENV_TESTCASE_SUMMARY GREENTEA_TEST_ENV_TESTCASE_SUMMARY
/**
* Default length for UUID buffers (used during the sync process)
*/
#define GREENTEA_UUID_LENGTH 48
/**
* Generic test suite transport protocol keys
*/
@ -77,6 +82,7 @@ extern const char* GREENTEA_TEST_ENV_LCOV_START;
* Greentea-client related API for communication with host side
*/
void GREENTEA_SETUP(const int, const char *);
void GREENTEA_SETUP_UUID(const int timeout, const char *host_test_name, char *buffer, size_t size);
void GREENTEA_TESTSUITE_RESULT(const int);
void GREENTEA_TESTCASE_START(const char *test_case_name);
void GREENTEA_TESTCASE_FINISH(const char *test_case_name, const size_t passes, const size_t failed);

View File

@ -60,25 +60,25 @@ static void greentea_notify_completion(const int);
static void greentea_notify_version();
static void greentea_write_string(const char *str);
/** \brief Handshake with host and send setup data (timeout and host test name)
* \details This function will send preamble to master.
* After host test name is received master will invoke host test script
* and add hos test's callback handlers to main event loop
/** \brief Handle the handshake with the host
* \details This is contains the shared handhshake functionality that is used between
* GREENTEA_SETUP and GREENTEA_SETUP_UUID.
* This function is blocking.
*/
void GREENTEA_SETUP(const int timeout, const char *host_test_name) {
void _GREENTEA_SETUP_COMMON(const int timeout, const char *host_test_name, char *buffer, size_t size) {
greentea_metrics_setup();
// Key-value protocol handshake function. Waits for {{__sync;...}} message
// Sync preamble: "{{__sync;0dad4a9d-59a3-4aec-810d-d5fb09d852c1}}"
// Example value of sync_uuid == "0dad4a9d-59a3-4aec-810d-d5fb09d852c1"
char _key[8] = {0};
char _value[48] = {0};
while (1) {
greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value));
char _key[8] = {0};
while (1) {
greentea_parse_kv(_key, buffer, sizeof(_key), size);
greentea_write_string("mbedmbedmbedmbedmbedmbedmbedmbed\r\n");
if (strcmp(_key, GREENTEA_TEST_ENV_SYNC) == 0) {
// Found correct __sunc message
greentea_send_kv(_key, _value);
// Found correct __sync message
greentea_send_kv(_key, buffer);
break;
}
}
@ -88,6 +88,29 @@ void GREENTEA_SETUP(const int timeout, const char *host_test_name) {
greentea_notify_hosttest(host_test_name);
}
/** \brief Handshake with host and send setup data (timeout and host test name)
* \details This function will send preamble to master.
* After host test name is received master will invoke host test script
* and add host test's callback handlers to main event loop
* This function is blocking.
*/
void GREENTEA_SETUP(const int timeout, const char *host_test_name) {
char _value[GREENTEA_UUID_LENGTH] = {0};
_GREENTEA_SETUP_COMMON(timeout, host_test_name, _value, GREENTEA_UUID_LENGTH);
}
/** \brief Handshake with host and send setup data (timeout and host test name). Allows you to preserve sync UUID.
* \details This function will send preamble to master.
* After host test name is received master will invoke host test script
* and add host test's callback handlers to main event loop
* This function is blocking.
* This function differs from GREENTEA_SETUP because it allows you to
* preserve the UUID sent during the sync process.
*/
void GREENTEA_SETUP_UUID(const int timeout, const char *host_test_name, char *buffer, size_t size) {
_GREENTEA_SETUP_COMMON(timeout, host_test_name, buffer, size);
}
/** \brief Notify host (__exit message) side that test suite execution was complete
* \result Test suite result
* \details If __exit is not received by host side we will assume TIMEOUT
@ -194,7 +217,7 @@ inline void greentea_write_preamble()
greentea_serial->putc('{');
greentea_serial->putc('{');
}
/**
* \brief Write the postamble characters to the serial port
*
@ -202,7 +225,7 @@ inline void greentea_write_preamble()
* for key-value comunication between the target and the host.
* This uses a Rawserial object, greentea_serial, which provides
* a direct interface to the USBTX and USBRX serial pins and allows
* the direct writing of characters using the putc() method.
* the direct writing of characters using the putc() method.
* This suite of functions are provided to allow for serial communication
* to the host from within a thread/ISR.
*
@ -238,8 +261,8 @@ inline void greentea_write_string(const char *str)
* \brief Write an int to the serial port
*
* This function writes an integer value from the target
* to the host. The integer value is converted to a string and
* and then written character by character directly to the serial
* to the host. The integer value is converted to a string and
* and then written character by character directly to the serial
* port using the greentea_serial, Rawserial object.
* sprintf() is used to convert the int to a string. Sprintf if
* inherently thread safe so can be used.
@ -302,7 +325,7 @@ void greentea_send_kv(const char *key, const int val) {
greentea_write_postamble();
}
}
/**
* \brief Encapsulate and send key-value-value message from DUT to host
*
@ -367,10 +390,10 @@ void greentea_send_kv(const char *key, const char *val, const int passes, const
/**
* \brief Encapsulate and send key-value-value message from DUT to host
*
* This function uses underlying functions to write directly
* to the serial port, (USBTX). This allows key-value-value to be used
* This function uses underlying functions to write directly
* to the serial port, (USBTX). This allows key-value-value to be used
* from within interrupt context.
* Both values are integers to avoid integer to string conversion
* Both values are integers to avoid integer to string conversion
* made by the user.
*
* Names of the parameters: this function is used to send number