Skip to content

Commit 6f88b2c

Browse files
committed
UnbufferedSerial: Replace DirectSerial and RawSerial classes
* Remove the private class DirectSerial and deprecate the public class RawSerial. * Introduce the public class UnbufferedSerial instead to provides unbuffered I/O by implementing features from DirectSerial and RawSerial. It inherits from FileHandle and SerialBase so it can be used in the system IO retarget code and as a stand-alone class to access I/O streams. * Add Greentea test for the UnbufferedSerial class.
1 parent 24c6c4c commit 6f88b2c

File tree

9 files changed

+494
-130
lines changed

9 files changed

+494
-130
lines changed

TESTS/host_tests/serial_comms.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
Copyright (c) 2019 Arm Limited and affiliates.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
"""
18+
19+
from mbed_host_tests import BaseHostTest
20+
21+
22+
MSG_KEY_ECHO_MESSAGE = "echo_message"
23+
24+
25+
class SerialComms(BaseHostTest):
26+
"""Host side test that handles messages sent using serial classes."""
27+
28+
def __init__(self):
29+
"""Initialize an object."""
30+
super(SerialComms, self).__init__()
31+
32+
def setup(self):
33+
"""Register call backs to handle message from the target."""
34+
self.register_callback(MSG_KEY_ECHO_MESSAGE, self.cb_echo_message)
35+
36+
def cb_echo_message(self, key, value, timestamp):
37+
"""Send back the key and value received."""
38+
self.send_kv(key, value)
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Copyright (c) 2019 Arm Limited and affiliates.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#if !DEVICE_SERIAL
18+
#error [NOT_SUPPORTED] serial communication not supported for this target
19+
#else
20+
21+
#include "mbed.h"
22+
#include "utest/utest.h"
23+
#include "unity/unity.h"
24+
#include "greentea-client/test_env.h"
25+
26+
27+
using namespace utest::v1;
28+
29+
30+
/**
31+
* Macros for setting console flow control.
32+
*/
33+
#define CONSOLE_FLOWCONTROL_RTS 1
34+
#define CONSOLE_FLOWCONTROL_CTS 2
35+
#define CONSOLE_FLOWCONTROL_RTSCTS 3
36+
#define mbed_console_concat_(x) CONSOLE_FLOWCONTROL_##x
37+
#define mbed_console_concat(x) mbed_console_concat_(x)
38+
#define CONSOLE_FLOWCONTROL mbed_console_concat(MBED_CONF_TARGET_CONSOLE_UART_FLOW_CONTROL)
39+
40+
41+
#define MSG_KEY_ECHO_MESSAGE "echo_message"
42+
#define MSG_VALUE_HELLO_WORLD "Hello, world!"
43+
44+
#define EXPECTED_ECHOED_STRING "{{" MSG_KEY_ECHO_MESSAGE ";" MSG_VALUE_HELLO_WORLD "}}"
45+
// The target is expected to transmit Greentea messages with \n (or \r\n) or they are not detected by the host
46+
#define STRING_TO_SEND EXPECTED_ECHOED_STRING "\n"
47+
48+
49+
static UnbufferedSerial unbuffered_serial_obj(
50+
USBTX, USBRX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE
51+
);
52+
53+
static ssize_t unbuffered_serial_read(void *buffer, ssize_t length)
54+
{
55+
if (length == 0) {
56+
return 0;
57+
}
58+
59+
// Ignore the `\n` character previously sent to the host in the previous
60+
// key-value pair that was not removed from the FIFO.
61+
unsigned char *buf = static_cast<unsigned char *>(buffer);
62+
unbuffered_serial_obj.read(buf, 1);
63+
64+
// Get the message sent by the host
65+
for (ssize_t i = 0; i < length; i++) {
66+
TEST_ASSERT_EQUAL_UINT(1, unbuffered_serial_obj.read(buf + i, 1));
67+
}
68+
69+
return length;
70+
}
71+
72+
73+
// Test that data sent using an UnbufferedSerial object is correctly sent.
74+
// The test case sends a Greentea key-value pair message from the target to the
75+
// host using an UnbufferedSerial object and expects the message
76+
// to be echoed back by the host. The host response is received via the Greentea
77+
// framework usual route using greentea_parse_kv(). Success is determined upon
78+
// reception of the echoed message which indicates that the message was received
79+
// by the host as it was sent by the target.
80+
static void test_serial_write()
81+
{
82+
char tx_msg[] = STRING_TO_SEND;
83+
84+
TEST_ASSERT_EQUAL_UINT(
85+
strlen(tx_msg) + 1,
86+
unbuffered_serial_obj.write(tx_msg, strlen(tx_msg) + 1)
87+
);
88+
89+
char rx_key[30] = {0};
90+
char rx_value[30] = {0};
91+
greentea_parse_kv(rx_key, rx_value, sizeof(rx_key), sizeof(rx_value));
92+
93+
TEST_ASSERT_EQUAL_STRING(MSG_KEY_ECHO_MESSAGE, rx_key);
94+
TEST_ASSERT_EQUAL_STRING(MSG_VALUE_HELLO_WORLD, rx_value);
95+
}
96+
97+
98+
// Test that data received using an UnbufferedSerial object is correctly received.
99+
// The test case sends a Greentea key-value pair message from the target to the
100+
// host via the Greentea framework usual route using greentea_send_kv().
101+
// It expects the message to be echoed back to the target. An UnbufferedSerial
102+
// object is used to handle the received message. Succes is determined upon
103+
// reception of a key-value pair matching the key-value pair sent by the target.
104+
static void test_serial_read()
105+
{
106+
greentea_send_kv(MSG_KEY_ECHO_MESSAGE, MSG_VALUE_HELLO_WORLD);
107+
108+
char rx_msg[sizeof(EXPECTED_ECHOED_STRING)] = {0};
109+
// Exclude the null terminator which is not read
110+
ssize_t expected_rx_msg_length = sizeof(EXPECTED_ECHOED_STRING) - 1;
111+
112+
unbuffered_serial_read(rx_msg, expected_rx_msg_length);
113+
114+
TEST_ASSERT_EQUAL_STRING(EXPECTED_ECHOED_STRING, rx_msg);
115+
}
116+
117+
118+
utest::v1::status_t greentea_setup(const size_t number_of_cases)
119+
{
120+
GREENTEA_SETUP(12, "serial_comms");
121+
122+
return greentea_test_setup_handler(number_of_cases);
123+
}
124+
125+
126+
utest::v1::status_t greentea_failure_handler(
127+
const Case *const source, const failure_t reason
128+
)
129+
{
130+
greentea_case_failure_abort_handler(source, reason);
131+
return STATUS_CONTINUE;
132+
}
133+
134+
135+
Case cases[] = {
136+
Case(
137+
"Bytes are correctly sent",
138+
test_serial_write, greentea_failure_handler
139+
),
140+
Case(
141+
"Bytes are correctly received",
142+
test_serial_read, greentea_failure_handler
143+
),
144+
};
145+
146+
147+
Specification specification(
148+
greentea_setup, cases, greentea_test_teardown_handler
149+
);
150+
151+
152+
int main()
153+
{
154+
#if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
155+
unbuffered_serial_obj.set_flow_control(
156+
SerialBase::RTS, STDIO_UART_RTS, NC
157+
);
158+
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS
159+
unbuffered_serial_obj.set_flow_control(
160+
SerialBase::CTS, NC, STDIO_UART_CTS
161+
);
162+
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS
163+
unbuffered_serial_obj.set_flow_control(
164+
SerialBase::RTSCTS, STDIO_UART_RTS, STDIO_UART_CTS
165+
);
166+
#endif
167+
return !Harness::run(specification);
168+
}
169+
170+
#endif // !DEVICE_SERIAL

drivers/RawSerial.h

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ namespace mbed {
3737
* @{
3838
*/
3939

40-
/** A serial port (UART) for communication with other serial devices
40+
/** @deprecated
41+
* A serial port (UART) for communication with other serial devices
4142
* This is a variation of the Serial class that doesn't use streams,
4243
* thus making it safe to use in interrupt handlers with the RTOS.
4344
*
@@ -59,10 +60,15 @@ namespace mbed {
5960
* }
6061
* @endcode
6162
*/
62-
class RawSerial: public SerialBase, private NonCopyable<RawSerial> {
63+
class
64+
MBED_DEPRECATED_SINCE(
65+
"mbed-os-6.0.0",
66+
"Use UnbufferedSerial instead."
67+
) RawSerial: public SerialBase, private NonCopyable<RawSerial> {
6368

6469
public:
65-
/** Create a RawSerial port, connected to the specified transmit and receive pins, with the specified baud.
70+
/** @deprecated
71+
* Create a RawSerial port, connected to the specified transmit and receive pins, with the specified baud.
6672
*
6773
* @param tx Transmit pin
6874
* @param rx Receive pin
@@ -71,31 +77,41 @@ class RawSerial: public SerialBase, private NonCopyable<RawSerial> {
7177
* @note
7278
* Either tx or rx may be specified as NC if unused
7379
*/
80+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
7481
RawSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
7582

76-
/** Write a char to the serial port
83+
/** @deprecated
84+
* Write a char to the serial port
7785
*
7886
* @param c The char to write
7987
*
8088
* @returns The written char or -1 if an error occurred
8189
*/
90+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
8291
int putc(int c);
8392

84-
/** Read a char from the serial port
93+
/** @deprecated
94+
* Read a char from the serial port
8595
*
8696
* @returns The char read from the serial port
8797
*/
98+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
8899
int getc();
89100

90-
/** Write a string to the serial port
101+
/** @deprecated
102+
* Write a string to the serial port
91103
*
92104
* @param str The string to write
93105
*
94106
* @returns 0 if the write succeeds, EOF for error
95107
*/
108+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
96109
int puts(const char *str);
97110

111+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
98112
int printf(const char *format, ...) MBED_PRINTF_METHOD(1, 2);
113+
114+
MBED_DEPRECATED("The class has been deprecated and will be removed in the future.")
99115
int vprintf(const char *format, std::va_list arg);
100116

101117
#if !(DOXYGEN_ONLY)

drivers/SerialBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace mbed {
3939
*/
4040

4141
/** A base class for serial port implementations
42-
* Can't be instantiated directly (use Serial or RawSerial)
42+
* Can't be instantiated directly (use UnbufferedSerial or UARTSerial)
4343
*
4444
* @note Synchronization level: Set by subclass
4545
*/

0 commit comments

Comments
 (0)