diff --git a/TESTS/mbed_drivers/flashiap/main.cpp b/TESTS/mbed_drivers/flashiap/main.cpp index 648240466a..2684dc7b74 100644 --- a/TESTS/mbed_drivers/flashiap/main.cpp +++ b/TESTS/mbed_drivers/flashiap/main.cpp @@ -20,7 +20,7 @@ #else #include "utest/utest.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" #include "unity/unity.h" #include "greentea-client/test_env.h" #include "FlashIAP.h" diff --git a/TESTS/mbed_hal/trng/main.cpp b/TESTS/mbed_hal/trng/main.cpp index 38c228a2a4..edd5dff70e 100644 --- a/TESTS/mbed_hal/trng/main.cpp +++ b/TESTS/mbed_hal/trng/main.cpp @@ -43,6 +43,7 @@ #include "base64b.h" #include "pithy.h" #include +#include #include "mbedtls/config.h" #include "mbedtls/platform.h" diff --git a/TESTS/psa/entropy_inject/main.cpp b/TESTS/psa/entropy_inject/main.cpp index a27562e943..0098e8e244 100644 --- a/TESTS/psa/entropy_inject/main.cpp +++ b/TESTS/psa/entropy_inject/main.cpp @@ -28,6 +28,7 @@ #include "entropy.h" #include "entropy_poll.h" #include "psa/crypto.h" +#include /* MAX value support macro */ #if !defined(MAX) diff --git a/TESTS/psa/spm_smoke/COMPONENT_NSPE/main.cpp b/TESTS/psa/spm_smoke/COMPONENT_NSPE/main.cpp index be6ff6833f..775ec2c997 100644 --- a/TESTS/psa/spm_smoke/COMPONENT_NSPE/main.cpp +++ b/TESTS/psa/spm_smoke/COMPONENT_NSPE/main.cpp @@ -27,6 +27,7 @@ #include "utest.h" #include "psa/client.h" #include "psa_manifest/sid.h" +#include #if defined(TARGET_TFM) #define PSA_MAX_IOVEC 4 diff --git a/TEST_APPS/device/nanostack_mac_tester/main.cpp b/TEST_APPS/device/nanostack_mac_tester/main.cpp index b1e99bcca4..93e96f05f1 100644 --- a/TEST_APPS/device/nanostack_mac_tester/main.cpp +++ b/TEST_APPS/device/nanostack_mac_tester/main.cpp @@ -44,7 +44,7 @@ #endif extern mac_api_s *mac_interface; -RawSerial pc(USBTX, USBRX); +UnbufferedSerial pc(USBTX, USBRX); osThreadId_t main_thread; static CircularBuffer rx_buffer; static uint8_t ns_heap[HEAP_FOR_MAC_TESTER_SIZE]; @@ -68,7 +68,8 @@ static void app_heap_error_handler(heap_fail_t event) static void rx_interrupt(void) { - uint8_t c = pc.getc(); + uint8_t c; + pc.read(&c, 1); rx_buffer.push(c); if (main_thread != NULL) { osThreadFlagsSet(main_thread, 1); diff --git a/components/testing/COMPONENT_FPGA_CI_TEST_SHIELD/test_utils.h b/components/testing/COMPONENT_FPGA_CI_TEST_SHIELD/test_utils.h index 5deeaeb430..e27e138559 100644 --- a/components/testing/COMPONENT_FPGA_CI_TEST_SHIELD/test_utils.h +++ b/components/testing/COMPONENT_FPGA_CI_TEST_SHIELD/test_utils.h @@ -540,6 +540,7 @@ typedef Port<1, AnalogoutMaps, DefaultFormFactor, TF1> AnalogoutPort; #if DEVICE_SERIAL #if DEVICE_SERIAL_FC +#include "hal/serial_api.h" struct UARTMaps { static const PinMap *maps[]; static const char *const pin_type_names[]; diff --git a/drivers/RawSerial.h b/drivers/RawSerial.h index 5fb9ce123d..55f8122a52 100644 --- a/drivers/RawSerial.h +++ b/drivers/RawSerial.h @@ -27,9 +27,6 @@ #include namespace mbed { -/** \defgroup drivers-public-api-uart UART - * \ingroup drivers-public-api - */ /** * \defgroup drivers_RawSerial RawSerial class diff --git a/drivers/UnbufferedSerial.h b/drivers/UnbufferedSerial.h index 3909644dc5..ec5f3fe9d7 100644 --- a/drivers/UnbufferedSerial.h +++ b/drivers/UnbufferedSerial.h @@ -30,6 +30,9 @@ namespace mbed { +/** \defgroup drivers-public-api-uart UART + * \ingroup drivers-public-api + */ /** * \defgroup drivers_UnbufferedSerial UnbufferedSerial class @@ -152,6 +155,12 @@ public: */ virtual short poll(short events) const; + using SerialBase::readable; + using SerialBase::writeable; + using SerialBase::format; + using SerialBase::attach; + using SerialBase::baud; + #if DEVICE_SERIAL_FC // For now use the base enum - but in future we may have extra options // such as XON/XOFF or manual GPIO RTSCTS. diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.cpp b/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.cpp index 431876efdc..8a61c102ad 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.cpp +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.cpp @@ -53,7 +53,7 @@ uint16_t H4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) while (i < len + 1) { uint8_t to_write = i == 0 ? type : pData[i - 1]; while (uart.writeable() == 0); - uart.putc(to_write); + uart.write(&to_write, 1); ++i; } return len; @@ -62,8 +62,10 @@ uint16_t H4TransportDriver::write(uint8_t type, uint16_t len, uint8_t *pData) void H4TransportDriver::on_controller_irq() { while (uart.readable()) { - uint8_t char_received = uart.getc(); - on_data_received(&char_received, 1); + uint8_t char_received; + if (uart.read(&char_received, 1)) { + on_data_received(&char_received, 1); + } } } diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.h index 299083e31d..6827d2756d 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/driver/H4TransportDriver.h @@ -69,11 +69,9 @@ public: private: void on_controller_irq(); - // Use RawSerial as opposed to Serial as we don't require the locking primitives - // provided by the Serial class (access to the UART should be exclusive to this driver) - // Furthermore, we access the peripheral in interrupt context which would clash - // with Serial's locking facilities - RawSerial uart; + // Use UnbufferedSerial as we don't require locking primitives. + // We access the peripheral in interrupt context. + UnbufferedSerial uart; PinName cts; PinName rts; }; diff --git a/features/frameworks/greentea-client/greentea-client/greentea_serial.h b/features/frameworks/greentea-client/greentea-client/greentea_serial.h deleted file mode 100644 index ff0901cbfe..0000000000 --- a/features/frameworks/greentea-client/greentea-client/greentea_serial.h +++ /dev/null @@ -1,21 +0,0 @@ - -/** \addtogroup frameworks */ -/** @{*/ -#ifndef GREENTEA_SERIAL_H -#define GREENTEA_SERIAL_H - -#if DEVICE_SERIAL - -#include "RawSerial.h" -#include "SingletonPtr.h" - -class GreenteaSerial : public mbed::RawSerial { -public: - GreenteaSerial(); -}; - -extern SingletonPtr greentea_serial; -#endif - -/** @}*/ -#endif \ No newline at end of file diff --git a/features/frameworks/greentea-client/greentea-client/test_env.h b/features/frameworks/greentea-client/greentea-client/test_env.h index f041233377..b21db6b181 100644 --- a/features/frameworks/greentea-client/greentea-client/test_env.h +++ b/features/frameworks/greentea-client/greentea-client/test_env.h @@ -117,6 +117,8 @@ void greentea_send_kv(const char * key, const char * val); int greentea_parse_kv(char * key, char * val, const int key_len, const int val_len); int greentea_getc(); +void greentea_putc(int c); +void greentea_write_string(const char *str); #ifdef __cplusplus } diff --git a/features/frameworks/greentea-client/source/greentea_serial.cpp b/features/frameworks/greentea-client/source/greentea_serial.cpp deleted file mode 100644 index 6f80a69a1d..0000000000 --- a/features/frameworks/greentea-client/source/greentea_serial.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "greentea-client/greentea_serial.h" - -#if DEVICE_SERIAL - -/** - * Macros for setting console flow control. - */ -#define CONSOLE_FLOWCONTROL_RTS 1 -#define CONSOLE_FLOWCONTROL_CTS 2 -#define CONSOLE_FLOWCONTROL_RTSCTS 3 -#define mbed_console_concat_(x) CONSOLE_FLOWCONTROL_##x -#define mbed_console_concat(x) mbed_console_concat_(x) -#define CONSOLE_FLOWCONTROL mbed_console_concat(MBED_CONF_TARGET_CONSOLE_UART_FLOW_CONTROL) - -SingletonPtr greentea_serial; - -GreenteaSerial::GreenteaSerial() : mbed::RawSerial(USBTX, USBRX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE) { -#if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS - set_flow_control(SerialBase::RTS, STDIO_UART_RTS, NC); -#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS - set_flow_control(SerialBase::CTS, NC, STDIO_UART_CTS); -#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS - set_flow_control(SerialBase::RTSCTS, STDIO_UART_RTS, STDIO_UART_CTS); -#endif -} - -#endif \ No newline at end of file diff --git a/features/frameworks/greentea-client/source/greentea_test_env.cpp b/features/frameworks/greentea-client/source/greentea_test_env.cpp index cb6a8a3267..584a8b2417 100644 --- a/features/frameworks/greentea-client/source/greentea_test_env.cpp +++ b/features/frameworks/greentea-client/source/greentea_test_env.cpp @@ -15,15 +15,13 @@ * limitations under the License. */ -#if DEVICE_SERIAL - #include #include #include #include "greentea-client/test_env.h" -#include "greentea-client/greentea_serial.h" #include "greentea-client/greentea_metrics.h" #include "mbed_trace.h" +#include "platform/mbed_retarget.h" /** * Generic test suite transport protocol keys @@ -59,7 +57,6 @@ static void greentea_notify_timeout(const int); static void greentea_notify_hosttest(const char *); static void greentea_notify_completion(const int); static void greentea_notify_version(); -static void greentea_write_string(const char *str); /** \brief Handle the handshake with the host * \details This is contains the shared handhshake functionality that is used between @@ -212,17 +209,15 @@ void greentea_notify_coverage_end() { * * This function writes the preamble "{{" which is required * 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. + * This uses greentea_putc which allows the direct writing of characters + * using the write() method. * This suite of functions are provided to allow for serial communication * to the host from within a thread/ISR. - * */ -inline void greentea_write_preamble() +static void greentea_write_preamble() { - greentea_serial->putc('{'); - greentea_serial->putc('{'); + greentea_putc('{'); + greentea_putc('{'); } /** @@ -230,19 +225,18 @@ inline void greentea_write_preamble() * * This function writes the postamble "{{\n" which is required * 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. + * This uses greentea_putc which allows the direct writing of characters + * using the write() method. * This suite of functions are provided to allow for serial communication * to the host from within a thread/ISR. * */ -inline void greentea_write_postamble() +static void greentea_write_postamble() { - greentea_serial->putc('}'); - greentea_serial->putc('}'); - greentea_serial->putc('\r'); - greentea_serial->putc('\n'); + greentea_putc('}'); + greentea_putc('}'); + greentea_putc('\r'); + greentea_putc('\n'); } /** @@ -250,17 +244,14 @@ inline void greentea_write_postamble() * * This function writes a '\0' terminated string from the target * to the host. It writes directly to the serial port using the - * greentea_serial, Rawserial object. + * the write() method. * * \param str - string value * */ -inline void greentea_write_string(const char *str) +void greentea_write_string(const char *str) { - while (*str != '\0') { - greentea_serial->putc(*str); - str ++; - } + write(STDOUT_FILENO, str, strlen(str)); } @@ -270,7 +261,7 @@ inline void greentea_write_string(const char *str) * 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 - * port using the greentea_serial, Rawserial object. + * port using the console. * sprintf() is used to convert the int to a string. Sprintf if * inherently thread safe so can be used. * @@ -278,13 +269,13 @@ inline void greentea_write_string(const char *str) * */ #define MAX_INT_STRING_LEN 15 -inline void greentea_write_int(const int val) +static void greentea_write_int(const int val) { char intval[MAX_INT_STRING_LEN]; unsigned int i = 0; sprintf(intval, "%d", val); while (intval[i] != '\0') { - greentea_serial->putc(intval[i]); + greentea_putc(intval[i]); i++; } } @@ -304,7 +295,7 @@ extern "C" void greentea_send_kv(const char *key, const char *val) { if (key && val) { greentea_write_preamble(); greentea_write_string(key); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_string(val); greentea_write_postamble(); } @@ -327,7 +318,7 @@ void greentea_send_kv(const char *key, const int val) { if (key) { greentea_write_preamble(); greentea_write_string(key); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(val); greentea_write_postamble(); } @@ -351,9 +342,9 @@ void greentea_send_kv(const char *key, const char *val, const int result) { if (key) { greentea_write_preamble(); greentea_write_string(key); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_string(val); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(result); greentea_write_postamble(); @@ -384,11 +375,11 @@ void greentea_send_kv(const char *key, const char *val, const int passes, const if (key) { greentea_write_preamble(); greentea_write_string(key); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_string(val); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(passes); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(failures); greentea_write_postamble(); } @@ -417,9 +408,9 @@ void greentea_send_kv(const char *key, const int passes, const int failures) { if (key) { greentea_write_preamble(); greentea_write_string(key); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(passes); - greentea_serial->putc(';'); + greentea_putc(';'); greentea_write_int(failures); greentea_write_postamble(); } @@ -562,7 +553,21 @@ enum Token { * */ extern "C" int greentea_getc() { - return greentea_serial->getc(); + uint8_t c; + read(STDOUT_FILENO, &c, 1); + return c; +} + + +/** + * \brief Write character from stream of data + * + * \return The number of bytes written + * + */ +extern "C" void greentea_putc(int c) { + uint8_t _c = c; + write(STDOUT_FILENO, &_c, 1); } /** @@ -786,5 +791,3 @@ static int HandleKV(char *out_key, getNextToken(0, 0); return 0; } - -#endif diff --git a/features/frameworks/utest/source/unity_handler.cpp b/features/frameworks/utest/source/unity_handler.cpp index 2b9b52000b..8ac51ceed7 100644 --- a/features/frameworks/utest/source/unity_handler.cpp +++ b/features/frameworks/utest/source/unity_handler.cpp @@ -19,10 +19,8 @@ #include "utest/utest_harness.h" #include "utest/utest_stack_trace.h" #include "utest/unity_handler.h" +#include "greentea-client/test_env.h" -#if DEVICE_SERIAL -#include "greentea-client/greentea_serial.h" -#endif void utest_unity_assert_failure(void) { @@ -36,10 +34,7 @@ void utest_unity_ignore_failure(void) utest::v1::Harness::raise_failure(utest::v1::failure_reason_t(utest::v1::REASON_ASSERTION | utest::v1::REASON_IGNORE)); } -#if DEVICE_SERIAL void utest_safe_putc(int chr) { - greentea_serial->putc(chr); -} -#endif - + greentea_putc(chr); +} diff --git a/features/frameworks/utest/source/utest_case.cpp b/features/frameworks/utest/source/utest_case.cpp index c5650c3117..852869d84a 100644 --- a/features/frameworks/utest/source/utest_case.cpp +++ b/features/frameworks/utest/source/utest_case.cpp @@ -17,7 +17,7 @@ */ #include "utest/utest_case.h" - #include "utest/utest_serial.h" + #include "utest/utest_print.h" using namespace utest::v1; diff --git a/features/frameworks/utest/source/utest_default_handlers.cpp b/features/frameworks/utest/source/utest_default_handlers.cpp index 63171e8748..22c592726f 100644 --- a/features/frameworks/utest/source/utest_default_handlers.cpp +++ b/features/frameworks/utest/source/utest_default_handlers.cpp @@ -21,7 +21,7 @@ #include "utest/utest_default_handlers.h" #include "utest/utest_case.h" #include "utest/utest_stack_trace.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" using namespace utest::v1; diff --git a/features/frameworks/utest/source/utest_greentea_handlers.cpp b/features/frameworks/utest/source/utest_greentea_handlers.cpp index b55407d098..3311b77864 100644 --- a/features/frameworks/utest/source/utest_greentea_handlers.cpp +++ b/features/frameworks/utest/source/utest_greentea_handlers.cpp @@ -20,7 +20,7 @@ #include "utest/utest_case.h" #include "greentea-client/test_env.h" #include "utest/utest_stack_trace.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" using namespace utest::v1; diff --git a/features/frameworks/utest/source/utest_harness.cpp b/features/frameworks/utest/source/utest_harness.cpp index 2a020c6899..63911b1f44 100644 --- a/features/frameworks/utest/source/utest_harness.cpp +++ b/features/frameworks/utest/source/utest_harness.cpp @@ -18,7 +18,7 @@ #include "utest/utest_harness.h" #include "utest/utest_stack_trace.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" #include diff --git a/features/frameworks/utest/source/utest_print.cpp b/features/frameworks/utest/source/utest_print.cpp new file mode 100644 index 0000000000..57c0224c53 --- /dev/null +++ b/features/frameworks/utest/source/utest_print.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** + * Copyright (c) 2019, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * 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 +#include +#include + +#include "greentea-client/test_env.h" +#include "platform/mbed_retarget.h" + + +#define STRING_STACK_LIMIT 120 + +static int utest_vprintf(const char *format, std::va_list arg) +{ + // ARMCC microlib does not properly handle a size of 0. + // As a workaround supply a dummy buffer with a size of 1. + char dummy_buf[1]; + int len = vsnprintf(dummy_buf, sizeof(dummy_buf), format, arg); + if (len < STRING_STACK_LIMIT) { + char temp[STRING_STACK_LIMIT]; + vsprintf(temp, format, arg); + greentea_write_string(temp); + } else { + char *temp = new char[len + 1]; + vsprintf(temp, format, arg); + greentea_write_string(temp); + delete[] temp; + } + + return len; +} + + +extern "C" int utest_printf(const char *format, ...) +{ + std::va_list args; + va_start(args, format); + int len = utest_vprintf(format, args); + va_end(args); + return len; +} diff --git a/features/frameworks/utest/source/utest_stack_trace.cpp b/features/frameworks/utest/source/utest_stack_trace.cpp index 5c7858be4b..634b1f2a05 100644 --- a/features/frameworks/utest/source/utest_stack_trace.cpp +++ b/features/frameworks/utest/source/utest_stack_trace.cpp @@ -20,7 +20,7 @@ #include "utest/utest.h" #include "unity/unity.h" #include "utest/utest_stack_trace.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" using namespace utest::v1; diff --git a/features/frameworks/utest/utest/utest.h b/features/frameworks/utest/utest/utest.h index 0d08ddf33b..829f65558f 100644 --- a/features/frameworks/utest/utest/utest.h +++ b/features/frameworks/utest/utest/utest.h @@ -26,7 +26,7 @@ #include "utest/utest_case.h" #include "utest/utest_default_handlers.h" #include "utest/utest_harness.h" -#include "utest/utest_serial.h" +#include "utest/utest_print.h" #endif // UTEST_H diff --git a/features/frameworks/utest/utest/utest_serial.h b/features/frameworks/utest/utest/utest_print.h similarity index 80% rename from features/frameworks/utest/utest/utest_serial.h rename to features/frameworks/utest/utest/utest_print.h index 8d94e21a3b..3f29dfca2d 100644 --- a/features/frameworks/utest/utest/utest_serial.h +++ b/features/frameworks/utest/utest/utest_print.h @@ -19,17 +19,11 @@ **************************************************************************** */ -#if DEVICE_SERIAL +#ifndef UTEST_PRINT_H +#define UTEST_PRINT_H -#ifndef UTEST_SERIAL_H -#define UTEST_SERIAL_H +extern "C" int utest_printf(const char *format, ...); -#include "greentea-client/greentea_serial.h" - -#define utest_printf(...) greentea_serial->printf(__VA_ARGS__) - -#endif // UTEST_SERIAL_H +#endif // UTEST_PRINT_H /** @}*/ - -#endif \ No newline at end of file