From e9375429908314aaf17bef6dbe4780b3ef2d5bba Mon Sep 17 00:00:00 2001 From: DuaneEllis-TI Date: Thu, 24 Aug 2017 10:28:01 -0700 Subject: [PATCH] [debug] add debug uart (#2082) --- .gitignore | 3 + etc/visual-studio/OpenThread.vcxproj | 8 +- .../libopenthread-cli-windows.vcxproj | 4 +- etc/visual-studio/otApi.vcxproj | 5 +- etc/visual-studio/otCli.vcxproj | 5 +- etc/visual-studio/otNodeApi.vcxproj | 5 +- examples/Makefile-nrf52840 | 4 +- examples/apps/cli/main.c | 20 +- examples/apps/ncp/main.c | 21 +- examples/common-switches.mk | 34 +++ examples/platforms/cc2538/Makefile.am | 1 + examples/platforms/cc2538/cc2538-reg.h | 13 ++ examples/platforms/cc2538/logging.c | 46 +++++ .../cc2538/openthread-core-cc2538-config.h | 8 - examples/platforms/cc2538/platform-cc2538.h | 7 + examples/platforms/cc2538/platform.c | 5 +- examples/platforms/cc2538/uart.c | 115 ++++++++++- examples/platforms/cc2650/Makefile.am | 1 + examples/platforms/cc2650/logging.c | 46 +++++ examples/platforms/cc2650/platform-cc2650.h | 2 + examples/platforms/cc2652/Makefile.am | 1 + examples/platforms/cc2652/logging.c | 46 +++++ .../cc2652/openthread-core-cc2652-config.h | 8 - examples/platforms/cc2652/platform-cc2652.h | 7 + examples/platforms/cc2652/platform.c | 4 + examples/platforms/cc2652/uart.c | 173 ++++++++++++++-- examples/platforms/da15000/logging.c | 4 + .../da15000/openthread-core-da15000-config.h | 17 +- examples/platforms/da15000/platform-da15000.h | 2 + examples/platforms/efr32/logging.c | 3 + .../efr32/openthread-core-efr32-config.h | 17 +- examples/platforms/efr32/platform-efr32.h | 2 + examples/platforms/emsk/Makefile.am | 1 + examples/platforms/emsk/logging.c | 5 +- .../emsk/openthread-core-emsk-config.h | 17 +- examples/platforms/emsk/platform-emsk.h | 2 + examples/platforms/emsk/radio.c | 5 +- examples/platforms/gp712/logging.c | 5 + examples/platforms/gp712/platform_qorvo.h | 2 + examples/platforms/kw41z/logging.c | 3 + .../kw41z/openthread-core-kw41z-config.h | 17 +- examples/platforms/kw41z/platform-kw41z.h | 2 + examples/platforms/nrf52840/alarm.c | 3 + examples/platforms/nrf52840/diag.c | 3 + examples/platforms/nrf52840/flash.c | 3 + examples/platforms/nrf52840/flash_nosd.c | 3 + examples/platforms/nrf52840/flash_sd.c | 3 + examples/platforms/nrf52840/logging.c | 7 +- examples/platforms/nrf52840/misc.c | 3 +- .../openthread-core-nrf52840-config.h | 17 ++ examples/platforms/nrf52840/platform.c | 7 +- examples/platforms/nrf52840/radio.c | 6 +- examples/platforms/nrf52840/random.c | 3 + examples/platforms/nrf52840/softdevice.c | 3 + examples/platforms/nrf52840/uart.c | 3 + examples/platforms/posix/logging.c | 5 + .../posix/openthread-core-posix-config.h | 8 +- examples/platforms/posix/platform-posix.h | 1 + examples/platforms/posix/uart-posix.c | 47 +++++ examples/platforms/utils/Makefile.am | 1 + examples/platforms/utils/debug_uart.c | 152 ++++++++++++++ include/openthread-windows-config.h | 2 +- include/openthread/cli.h | 12 +- include/openthread/ncp.h | 11 + include/openthread/platform/Makefile.am | 3 + include/openthread/platform/alarm-micro.h | 2 +- include/openthread/platform/debug_uart.h | 195 ++++++++++++++++++ include/openthread/platform/logging-windows.h | 29 +++ include/openthread/platform/logging.h | 41 ++-- include/openthread/platform/radio.h | 1 + include/openthread/platform/toolchain.h | 21 ++ include/openthread/types.h | 36 ++++ src/cli/README.md | 10 + src/cli/cli.cpp | 28 +++ src/cli/cli.hpp | 3 + src/cli/cli_uart.cpp | 52 +++-- src/core/common/logging.cpp | 10 + src/core/common/logging.hpp | 57 +++++ src/core/openthread-core-default-config.h | 95 +++++++-- src/core/utils/wrap_stdbool.h | 9 +- src/ncp/ncp_base.cpp | 20 ++ src/ncp/ncp_uart.cpp | 32 --- 82 files changed, 1456 insertions(+), 187 deletions(-) create mode 100644 examples/platforms/cc2538/logging.c create mode 100644 examples/platforms/cc2650/logging.c create mode 100644 examples/platforms/cc2652/logging.c create mode 100644 examples/platforms/utils/debug_uart.c create mode 100644 include/openthread/platform/debug_uart.h diff --git a/.gitignore b/.gitignore index 86ae2526d..e6102274a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ *.suo *.trs *.user +*.bak *~ .deps .dirstamp @@ -32,6 +33,8 @@ etc/visual-studio/BundleArtifacts etc/visual-studio/Generated Files include/openthread-config.h include/openthread-config.h.in +include/openthread-config-generic.h +include/openthread-config-generic.h.in include/stamp-h1 ipch libtool diff --git a/etc/visual-studio/OpenThread.vcxproj b/etc/visual-studio/OpenThread.vcxproj index 021279d46..ebdced03b 100644 --- a/etc/visual-studio/OpenThread.vcxproj +++ b/etc/visual-studio/OpenThread.vcxproj @@ -1,4 +1,4 @@ - + @@ -43,6 +43,10 @@ + + %(PreprocessorDefinitions); + OPENTHREAD_CONFIG_FILE="openthread-windows-config.h"; + /bigobj %(AdditionalOptions) 4453;28204 @@ -152,4 +156,4 @@ - \ No newline at end of file + diff --git a/etc/visual-studio/libopenthread-cli-windows.vcxproj b/etc/visual-studio/libopenthread-cli-windows.vcxproj index 818e2851b..76859c9d7 100644 --- a/etc/visual-studio/libopenthread-cli-windows.vcxproj +++ b/etc/visual-studio/libopenthread-cli-windows.vcxproj @@ -1,4 +1,4 @@ - + @@ -63,4 +63,4 @@ - \ No newline at end of file + diff --git a/etc/visual-studio/otApi.vcxproj b/etc/visual-studio/otApi.vcxproj index 38acfef8f..4430c57d1 100644 --- a/etc/visual-studio/otApi.vcxproj +++ b/etc/visual-studio/otApi.vcxproj @@ -1,4 +1,4 @@ - + @@ -41,6 +41,7 @@ %(PreprocessorDefinitions); OPENTHREAD_FTD=1; OTAPI_EXPORTS; + OPENTHREAD_CONFIG_FILE="openthread-windows-config.h"; true @@ -66,4 +67,4 @@ - \ No newline at end of file + diff --git a/etc/visual-studio/otCli.vcxproj b/etc/visual-studio/otCli.vcxproj index 5291045f3..327e779c2 100644 --- a/etc/visual-studio/otCli.vcxproj +++ b/etc/visual-studio/otCli.vcxproj @@ -1,4 +1,4 @@ - + @@ -38,6 +38,7 @@ %(PreprocessorDefinitions); + OPENTHREAD_CONFIG_FILE="openthread-windows-config.h"; OPENTHREAD_FTD=1; OTDLL; @@ -66,4 +67,4 @@ - \ No newline at end of file + diff --git a/etc/visual-studio/otNodeApi.vcxproj b/etc/visual-studio/otNodeApi.vcxproj index 06d6876e3..dc06757e7 100644 --- a/etc/visual-studio/otNodeApi.vcxproj +++ b/etc/visual-studio/otNodeApi.vcxproj @@ -1,4 +1,4 @@ - + @@ -38,6 +38,7 @@ %(PreprocessorDefinitions); OPENTHREAD_FTD=1; + OPENTHREAD_CONFIG_FILE="openthread-windows-config.h"; OTAPI_EXPORTS; @@ -75,4 +76,4 @@ - \ No newline at end of file + diff --git a/examples/Makefile-nrf52840 b/examples/Makefile-nrf52840 index ac8d6c498..a771e35d5 100644 --- a/examples/Makefile-nrf52840 +++ b/examples/Makefile-nrf52840 @@ -80,7 +80,9 @@ COMMONCFLAGS := \ $(NULL) ifeq ($(CERT_LOG),1) -COMMONCFLAGS += -DOPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT=1 +COMMONCFLAGS += -DOPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_APP +else +COMMONCFLAGS += -DOPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED endif CPPFLAGS += \ diff --git a/examples/apps/cli/main.c b/examples/apps/cli/main.c index 17d489395..9483b2bb9 100644 --- a/examples/apps/cli/main.c +++ b/examples/apps/cli/main.c @@ -27,13 +27,14 @@ */ #include - +#include #include #include #include #include #include +#include #if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES void *otPlatCAlloc(size_t aNum, size_t aSize) @@ -97,3 +98,20 @@ int main(int argc, char *argv[]) return 0; } + +/* + * Provide, if required an "otPlatLog()" function + */ +#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + OT_UNUSED_VARIABLE(aLogLevel); + OT_UNUSED_VARIABLE(aLogRegion); + OT_UNUSED_VARIABLE(aFormat); + + va_list ap; + va_start(ap, aFormat); + otCliPlatLogv(aLogLevel, aLogRegion, aFormat, ap); + va_end(ap); +} +#endif diff --git a/examples/apps/ncp/main.c b/examples/apps/ncp/main.c index 5f5321802..1210aa5ff 100644 --- a/examples/apps/ncp/main.c +++ b/examples/apps/ncp/main.c @@ -27,7 +27,7 @@ */ #include - +#include #include #include @@ -97,3 +97,22 @@ int main(int argc, char *argv[]) return 0; } + + +/* + * Provide, if required an "otPlatLog()" function + */ + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP) +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + OT_UNUSED_VARIABLE(aLogLevel); + OT_UNUSED_VARIABLE(aLogRegion); + OT_UNUSED_VARIABLE(aFormat); + + va_list ap; + va_start(ap, aFormat); + otNcpPlatLogv(aLogLevel, aLogRegion, aFormat, ap); + va_end(ap); +} +#endif diff --git a/examples/common-switches.mk b/examples/common-switches.mk index da411c518..92fd7acaf 100644 --- a/examples/common-switches.mk +++ b/examples/common-switches.mk @@ -89,3 +89,37 @@ endif ifeq ($(MTD_NETDIAG),1) configure_OPTIONS += --enable-mtd-network-diagnostic endif + +ifeq ($(DEBUG_UART),1) +CFLAGS += -DOPENTHREAD_CONFIG_ENABLE_DEBUG_UART=1 +CXXFLAGS += -DOPENTHREAD_CONFIG_ENABLE_DEBUG_UART=1 +endif + +ifeq ($(DEBUG_UART_LOG),1) +CFLAGS += -DOPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART +CXXFLAGS += -DOPENTHREAD_CONFIG_LOG_OUTPUT=OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART +endif + +ifeq ($(FULL_LOGS),1) +# HINT: Add more here, or comment out ones you do not need/want +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_LEVEL=OT_LOG_LEVEL_DEBG +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_API=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_ARP=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_CLI=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_COAP=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_ICMP=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_IP6=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MAC=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MEM=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_MLE=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_NETDATA=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_NETDIAG=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_PKT_DUMP=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_PLATFORM=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_PREPEND_LEVEL=1 +LOG_FLAGS += -DOPENTHREAD_CONFIG_LOG_PREPEND_REGION=1 +endif + +CFLAGS += ${LOG_FLAGS} +CXXFLAGS += ${LOG_FLAGS} + diff --git a/examples/platforms/cc2538/Makefile.am b/examples/platforms/cc2538/Makefile.am index 3ec32f0d2..73677169d 100644 --- a/examples/platforms/cc2538/Makefile.am +++ b/examples/platforms/cc2538/Makefile.am @@ -44,6 +44,7 @@ libopenthread_cc2538_a_SOURCES = \ radio.c \ random.c \ startup-gcc.c \ + logging.c \ uart.c \ $(NULL) diff --git a/examples/platforms/cc2538/cc2538-reg.h b/examples/platforms/cc2538/cc2538-reg.h index b6f7eb73f..960bb2722 100644 --- a/examples/platforms/cc2538/cc2538-reg.h +++ b/examples/platforms/cc2538/cc2538-reg.h @@ -148,19 +148,30 @@ #define SYS_CTRL_SCGCUART_UART0 0x00000001 #define SYS_CTRL_DCGCUART_UART0 0x00000001 +#define SYS_CTRL_RCGCUART_UART1 0x00000002 +#define SYS_CTRL_SCGCUART_UART1 0x00000002 +#define SYS_CTRL_DCGCUART_UART1 0x00000002 + #define IOC_PA0_SEL 0x400D4000 // Peripheral select control #define IOC_PA1_SEL 0x400D4004 // Peripheral select control +#define IOC_PA2_SEL 0x400D4008 +#define IOC_PA3_SEL 0x400D400C #define IOC_UARTRXD_UART0 0x400D4100 +#define IOC_UARTRXD_UART1 0x400D4108 #define IOC_PA0_OVER 0x400D4080 #define IOC_PA1_OVER 0x400D4084 +#define IOC_PA2_OVER 0x400D4088 +#define IOC_PA3_OVER 0x400D408C #define IOC_MUX_OUT_SEL_UART0_TXD 0x00000000 +#define IOC_MUX_OUT_SEL_UART1_TXD 0x00000002 #define IOC_OVERRIDE_OE 0x00000008 // PAD Config Override Output Enable #define IOC_OVERRIDE_DIS 0x00000000 // PAD Config Override Disabled #define UART0_BASE 0x4000C000 +#define UART1_BASE 0x4000D000 #define GPIO_A_BASE 0x400D9000 // GPIO #define GPIO_O_DIR 0x00000400 @@ -168,6 +179,8 @@ #define GPIO_PIN_0 0x00000001 // GPIO pin 0 #define GPIO_PIN_1 0x00000002 // GPIO pin 1 +#define GPIO_PIN_2 0x00000004 // GPIO pin 2 +#define GPIO_PIN_3 0x00000008 // GPIO pin 3 #define UART_O_DR 0x00000000 // UART data #define UART_O_FR 0x00000018 // UART flag diff --git a/examples/platforms/cc2538/logging.c b/examples/platforms/cc2538/logging.c new file mode 100644 index 000000000..5a282d335 --- /dev/null +++ b/examples/platforms/cc2538/logging.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** +* @file logging.c +* Platform abstraction for the logging +* +*/ +#include +#include +#include + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + (void)aLogLevel; + (void)aLogRegion; + (void)aFormat; +} +#endif + diff --git a/examples/platforms/cc2538/openthread-core-cc2538-config.h b/examples/platforms/cc2538/openthread-core-cc2538-config.h index bd927b982..e99cccf5f 100644 --- a/examples/platforms/cc2538/openthread-core-cc2538-config.h +++ b/examples/platforms/cc2538/openthread-core-cc2538-config.h @@ -42,14 +42,6 @@ */ #define OPENTHREAD_CONFIG_PLATFORM_INFO "CC2538" -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT * diff --git a/examples/platforms/cc2538/platform-cc2538.h b/examples/platforms/cc2538/platform-cc2538.h index f23ad1a9a..fa7043bb2 100644 --- a/examples/platforms/cc2538/platform-cc2538.h +++ b/examples/platforms/cc2538/platform-cc2538.h @@ -35,6 +35,8 @@ #ifndef PLATFORM_CC2538_H_ #define PLATFORM_CC2538_H_ +#include +#include #include #include @@ -44,6 +46,11 @@ // Global OpenThread instance structure extern otInstance *sInstance; +/** + * Initialize the debug uart + */ +void cc2538DebugUartInit(void); + /** * This function initializes the alarm service used by OpenThread. * diff --git a/examples/platforms/cc2538/platform.c b/examples/platforms/cc2538/platform.c index 8df97ca71..8ac91740c 100644 --- a/examples/platforms/cc2538/platform.c +++ b/examples/platforms/cc2538/platform.c @@ -31,13 +31,16 @@ * @brief * This file includes the platform-specific initializers. */ - +#include #include "platform-cc2538.h" otInstance *sInstance; void PlatformInit(int argc, char *argv[]) { +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + cc2538DebugUartInit(); +#endif cc2538AlarmInit(); cc2538RandomInit(); cc2538RadioInit(); diff --git a/examples/platforms/cc2538/uart.c b/examples/platforms/cc2538/uart.c index ba1319cf2..2979bb6a6 100644 --- a/examples/platforms/cc2538/uart.c +++ b/examples/platforms/cc2538/uart.c @@ -32,10 +32,17 @@ * */ +#include +#include + +#include +#include #include #include +#include #include +#include #include "platform-cc2538.h" #include "utils/code_utils.h" @@ -67,6 +74,28 @@ typedef struct RecvBuffer static RecvBuffer sReceive; +static void enable_uart_clocks(void) +{ + static int uart_clocks_done = 0; + + if (uart_clocks_done) + { + return; + } + + uart_clocks_done = 1; + +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + HWREG(SYS_CTRL_RCGCUART) = (SYS_CTRL_RCGCUART_UART0 | SYS_CTRL_RCGCUART_UART1); + HWREG(SYS_CTRL_SCGCUART) = (SYS_CTRL_SCGCUART_UART0 | SYS_CTRL_SCGCUART_UART1); + HWREG(SYS_CTRL_DCGCUART) = (SYS_CTRL_DCGCUART_UART0 | SYS_CTRL_DCGCUART_UART1); +#else + HWREG(SYS_CTRL_RCGCUART) = SYS_CTRL_RCGCUART_UART0; + HWREG(SYS_CTRL_SCGCUART) = SYS_CTRL_SCGCUART_UART0; + HWREG(SYS_CTRL_DCGCUART) = SYS_CTRL_DCGCUART_UART0; +#endif +} + otError otPlatUartEnable(void) { uint32_t div; @@ -75,9 +104,7 @@ otError otPlatUartEnable(void) sReceive.mTail = 0; // clock - HWREG(SYS_CTRL_RCGCUART) = SYS_CTRL_RCGCUART_UART0; - HWREG(SYS_CTRL_SCGCUART) = SYS_CTRL_SCGCUART_UART0; - HWREG(SYS_CTRL_DCGCUART) = SYS_CTRL_DCGCUART_UART0; + enable_uart_clocks(); HWREG(UART0_BASE + UART_O_CC) = 0; @@ -200,3 +227,85 @@ void UART0IntHandler(void) } } } + +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + +int otPlatDebugUart_kbhit(void) +{ + uint32_t v; + + /* get flags */ + v = HWREG(UART1_BASE + UART_O_FR); + + /* if FIFO empty we have no data */ + return !(v & UART_FR_RXFE); +} + +int otPlatDebugUart_getc(void) +{ + int v = 1; + + /* if nothing in fifo */ + if (!otPlatDebugUart_kbhit()) + { + return -1; + } + + /* fetch */ + v = (int)HWREG(UART0_BASE + UART_O_DR); + v = (v & 0x0ff); + return v; +} + +void otPlatDebugUart_putchar_raw(int b) +{ + /* wait till not busy */ + while (HWREG(UART1_BASE + UART_O_FR) & UART_FR_TXFF); + + /* write byte */ + HWREG(UART1_BASE + UART_O_DR) = ((uint32_t)(b & 0x0ff)); +} + + +void cc2538DebugUartInit(void) +{ + int32_t a, b; + + // clocks + enable_uart_clocks(); + + HWREG(UART1_BASE + UART_O_CC) = 0; + + // UART1 - tx pin + // Using an RF06 Evaluation board + // http://www.ti.com/tool/cc2538dk + // PA3 => is jumper position RF1.14 + // To use these, you will require a "flying-lead" UART adapter + HWREG(IOC_PA3_SEL) = IOC_MUX_OUT_SEL_UART1_TXD; + HWREG(IOC_PA3_OVER) = IOC_OVERRIDE_OE; + HWREG(GPIO_A_BASE + GPIO_O_AFSEL) |= GPIO_PIN_3; + + // UART1 - rx pin we don't really use but we setup anyway + // PA2 => is jumper position RF1.16 + HWREG(IOC_PA2_SEL) = IOC_UARTRXD_UART1; + HWREG(IOC_PA2_OVER) = IOC_OVERRIDE_DIS; + HWREG(GPIO_A_BASE + GPIO_O_AFSEL) |= GPIO_PIN_2; + + HWREG(UART1_BASE + UART_O_CC) = 0; + + // baud rate + b = (((kPlatformClock * 8) / kBaudRate) + 1) / 2; + a = b / 64; + b = b % 64; + HWREG(UART1_BASE + UART_O_IBRD) = a; + HWREG(UART1_BASE + UART_O_FBRD) = b; + HWREG(UART1_BASE + UART_O_LCRH) = UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE; + + /* NOTE: + * uart1 is not using IRQs it is tx only + * and we block when writing bytes + */ + HWREG(UART1_BASE + UART_O_CTL) = UART_CTL_UARTEN | UART_CTL_TXE | UART_CTL_RXE; +} + +#endif diff --git a/examples/platforms/cc2650/Makefile.am b/examples/platforms/cc2650/Makefile.am index e96c7ffc3..f76ccf3ee 100644 --- a/examples/platforms/cc2650/Makefile.am +++ b/examples/platforms/cc2650/Makefile.am @@ -45,6 +45,7 @@ libopenthread_cc2650_a_SOURCES = \ alarm.c \ flash.c \ misc.c \ + logging.c \ platform.c \ radio.c \ random.c \ diff --git a/examples/platforms/cc2650/logging.c b/examples/platforms/cc2650/logging.c new file mode 100644 index 000000000..5a282d335 --- /dev/null +++ b/examples/platforms/cc2650/logging.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** +* @file logging.c +* Platform abstraction for the logging +* +*/ +#include +#include +#include + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + (void)aLogLevel; + (void)aLogRegion; + (void)aFormat; +} +#endif + diff --git a/examples/platforms/cc2650/platform-cc2650.h b/examples/platforms/cc2650/platform-cc2650.h index 68266ed7e..696d165cf 100644 --- a/examples/platforms/cc2650/platform-cc2650.h +++ b/examples/platforms/cc2650/platform-cc2650.h @@ -29,6 +29,8 @@ #ifndef PLATFORM_H_ #define PLATFORM_H_ +#include +#include #include #include "openthread/types.h" diff --git a/examples/platforms/cc2652/Makefile.am b/examples/platforms/cc2652/Makefile.am index babadbfa2..b4c297427 100644 --- a/examples/platforms/cc2652/Makefile.am +++ b/examples/platforms/cc2652/Makefile.am @@ -44,6 +44,7 @@ libopenthread_cc2652_a_CPPFLAGS = \ libopenthread_cc2652_a_SOURCES = \ alarm.c \ flash.c \ + logging.c \ misc.c \ platform.c \ radio.c \ diff --git a/examples/platforms/cc2652/logging.c b/examples/platforms/cc2652/logging.c new file mode 100644 index 000000000..5a282d335 --- /dev/null +++ b/examples/platforms/cc2652/logging.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** +* @file logging.c +* Platform abstraction for the logging +* +*/ +#include +#include +#include + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + (void)aLogLevel; + (void)aLogRegion; + (void)aFormat; +} +#endif + diff --git a/examples/platforms/cc2652/openthread-core-cc2652-config.h b/examples/platforms/cc2652/openthread-core-cc2652-config.h index aac86e35a..c75f70384 100644 --- a/examples/platforms/cc2652/openthread-core-cc2652-config.h +++ b/examples/platforms/cc2652/openthread-core-cc2652-config.h @@ -60,13 +60,5 @@ */ #define SETTINGS_CONFIG_PAGE_NUM (2) -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - #endif /* OPENTHREAD_CORE_CC2650_CONFIG_H_ */ diff --git a/examples/platforms/cc2652/platform-cc2652.h b/examples/platforms/cc2652/platform-cc2652.h index 78d1ad40d..3d006a073 100644 --- a/examples/platforms/cc2652/platform-cc2652.h +++ b/examples/platforms/cc2652/platform-cc2652.h @@ -29,6 +29,8 @@ #ifndef PLATFORM_H_ #define PLATFORM_H_ +#include +#include #include #include "openthread/types.h" @@ -39,6 +41,11 @@ extern "C" { // Global OpenThread instance structure extern otInstance *sInstance; +/** + * Initialize the debug uart + */ +void cc2652DebugUartInit(void); + /** * This method initializes the alarm service used by OpenThread. * diff --git a/examples/platforms/cc2652/platform.c b/examples/platforms/cc2652/platform.c index 9b5282684..af06cb0ad 100644 --- a/examples/platforms/cc2652/platform.c +++ b/examples/platforms/cc2652/platform.c @@ -63,6 +63,9 @@ void PlatformInit(int argc, char *argv[]) */ } +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + cc2652DebugUartInit(); +#endif cc2652AlarmInit(); cc2652RandomInit(); cc2652RadioInit(); @@ -79,3 +82,4 @@ void PlatformProcessDrivers(otInstance *aInstance) cc2652RadioProcess(aInstance); cc2652AlarmProcess(aInstance); } + diff --git a/examples/platforms/cc2652/uart.c b/examples/platforms/cc2652/uart.c index e363d6eb3..b30165076 100644 --- a/examples/platforms/cc2652/uart.c +++ b/examples/platforms/cc2652/uart.c @@ -33,11 +33,19 @@ */ #include +#include +#include +#include #include -#include #include +#include +#include +#include + +#include "utils/code_utils.h" + #include #include @@ -48,6 +56,8 @@ /** * @note This will configure the uart for 115200 baud 8-N-1, no HW flow control * RX pin IOID_2 TX pin IOID_3. + * + * If the DEBUG UART is enabled, IOID_0 = debug tx, IOID_1 = debug rx */ enum @@ -64,29 +74,66 @@ static uint16_t sReceiveTailIdx = 0; void UART0_intHandler(void); +static void uart_power_control(uint32_t who_base, int turnon) +{ + uint32_t value; + + if (turnon) + { + /* UART0 is in the SERIAL domain + * UART1 is in the PERIPH domain. + * See: ti/devices/cc26x2/driverlib/pcrm.h, line: 658 + */ + value = (who_base == UART0_BASE) ? PRCM_DOMAIN_SERIAL : PRCM_DOMAIN_PERIPH; + PRCMPowerDomainOn(value); + + while (PRCMPowerDomainStatus(value) != PRCM_DOMAIN_POWER_ON); + + value = (who_base == UART0_BASE) ? PRCM_PERIPH_UART0 : PRCM_PERIPH_UART1; + PRCMPeripheralRunEnable(value); + PRCMPeripheralSleepEnable(value); + PRCMPeripheralDeepSleepEnable(value); + PRCMLoadSet(); + + while (!PRCMLoadGet()); + } + else + { + if (who_base == UART0_BASE) + { + PRCMPeripheralRunDisable(PRCM_PERIPH_UART0); + PRCMPeripheralSleepDisable(PRCM_PERIPH_UART0); + PRCMPeripheralDeepSleepDisable(PRCM_PERIPH_UART0); + PRCMLoadSet(); + PRCMPowerDomainOff(PRCM_DOMAIN_SERIAL); + } + else + { + /* we never turn the debug uart off */ + } + } +} + + /** * Function documented in platform/uart.h */ otError otPlatUartEnable(void) { - PRCMPowerDomainOn(PRCM_DOMAIN_SERIAL); - - while (PRCMPowerDomainStatus(PRCM_DOMAIN_SERIAL) != PRCM_DOMAIN_POWER_ON); - - PRCMPeripheralRunEnable(PRCM_PERIPH_UART0); - PRCMPeripheralSleepEnable(PRCM_PERIPH_UART0); - PRCMPeripheralDeepSleepEnable(PRCM_PERIPH_UART0); - PRCMLoadSet(); - - while (!PRCMLoadGet()); + uart_power_control(UART0_BASE, true); IOCPinTypeUart(UART0_BASE, IOID_2, IOID_3, IOID_UNUSED, IOID_UNUSED); - UARTConfigSetExpClk(UART0_BASE, SysCtrlClockGet(), 115200, UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); + + /* Note: UART1 could use IRQs + * However, for reasons of debug simplicity + * we do not use IRQs for the debug uart + */ UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT); UARTIntRegister(UART0_BASE, UART0_intHandler); UARTEnable(UART0_BASE); + return OT_ERROR_NONE; } @@ -101,15 +148,8 @@ otError otPlatUartDisable(void) IOCPortConfigureSet(IOID_2, IOC_PORT_GPIO, IOC_STD_INPUT); IOCPortConfigureSet(IOID_3, IOC_PORT_GPIO, IOC_STD_INPUT); - PRCMPeripheralRunDisable(PRCM_PERIPH_UART0); - PRCMPeripheralSleepDisable(PRCM_PERIPH_UART0); - PRCMPeripheralDeepSleepDisable(PRCM_PERIPH_UART0); - PRCMLoadSet(); - /** - * \warn this assumes that there are no other devices being used in the - * serial power domain - */ - PRCMPowerDomainOff(PRCM_DOMAIN_SERIAL); + uart_power_control(UART0_BASE, false); + return OT_ERROR_NONE; } @@ -201,3 +241,94 @@ void UART0_intHandler(void) } } +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + +/* + * Documented in platform-cc2652.h + */ +void +cc2652DebugUartInit(void) +{ + uart_power_control(UART1_BASE, true); + /* + * LaunchPad Pin29 = tx, Pin 30 = rxd + * + * The function IOCPinTypeUart() is hard coded to + * only support UART0 - and does not support UART1. + * + * Thus, these pins are configured using a different way. + */ + IOCPortConfigureSet(IOID_0, IOC_PORT_MCU_UART1_TX, IOC_STD_INPUT); + IOCPortConfigureSet(IOID_1, IOC_PORT_MCU_UART1_RX, IOC_STD_INPUT); + + UARTConfigSetExpClk(UART1_BASE, SysCtrlClockGet(), 115200, + UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE); + UARTEnable(UART1_BASE); +} + +/* This holds the last key pressed */ +static int debug_uart_ungetbuf; + +/* + * Documented in "src/core/common/debug_uart.h" + */ +int otPlatDebugUart_getc(void) +{ + int ch = -1; + + if (otPlatDebugUart_kbhit()) + { + /* get & clear 0x100 bit used below as flag */ + ch = debug_uart_ungetbuf & 0x0ff; + debug_uart_ungetbuf = 0; + } + + return ch; +} + +/* + * Documented in "src/core/common/debug_uart.h" + */ +int otPlatDebugUart_kbhit(void) +{ + int r; + + /* if something is in the unget buf... */ + r = !!debug_uart_ungetbuf; + + if (!r) + { + /* + * Driverlib code returns "-1", or "char" on something + * but it comes with flags in upper bits + */ + r = (int)UARTCharGetNonBlocking(UART1_BASE); + + if (r < 0) + { + r = 0; /* no key pressed */ + } + else + { + /* key was pressed, mask flags + * and set 0x100 bit, to distinguish + * the value "0x00" from "no-key-pressed" + */ + debug_uart_ungetbuf = ((r & 0x0ff) | 0x0100); + + r = 1; /* key pressed */ + } + } + + return r; +} + +/* + * Documented in "src/core/common/debug_uart.h" + */ +void otPlatDebugUart_putchar_raw(int b) +{ + UARTCharPut(UART1_BASE, b); +} + +#endif /* OPENTHREAD_CONFIG_ENABLE_DEBUG_UART */ diff --git a/examples/platforms/da15000/logging.c b/examples/platforms/da15000/logging.c index 2e400d6b9..5a282d335 100644 --- a/examples/platforms/da15000/logging.c +++ b/examples/platforms/da15000/logging.c @@ -31,12 +31,16 @@ * Platform abstraction for the logging * */ +#include +#include #include +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { (void)aLogLevel; (void)aLogRegion; (void)aFormat; } +#endif diff --git a/examples/platforms/da15000/openthread-core-da15000-config.h b/examples/platforms/da15000/openthread-core-da15000-config.h index cb26fb80c..464eab9e9 100644 --- a/examples/platforms/da15000/openthread-core-da15000-config.h +++ b/examples/platforms/da15000/openthread-core-da15000-config.h @@ -49,14 +49,6 @@ */ #define SETTINGS_CONFIG_BASE_ADDRESS (0x7B000) -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT * @@ -81,4 +73,13 @@ */ #define OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ENERGY_SCAN 1 +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The DA15000 platform provides an otPlatLog() function. + */ +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHERAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + #endif // OPENTHREAD_CORE_DA15000_CONFIG_H_ diff --git a/examples/platforms/da15000/platform-da15000.h b/examples/platforms/da15000/platform-da15000.h index b95afa601..302d789fd 100755 --- a/examples/platforms/da15000/platform-da15000.h +++ b/examples/platforms/da15000/platform-da15000.h @@ -29,6 +29,8 @@ #ifndef PLATFORM_DA15000_H_ #define PLATFORM_DA15000_H_ +#include +#include #include /** diff --git a/examples/platforms/efr32/logging.c b/examples/platforms/efr32/logging.c index a9971ee56..cd4e8cd69 100644 --- a/examples/platforms/efr32/logging.c +++ b/examples/platforms/efr32/logging.c @@ -33,12 +33,14 @@ */ #include +#include #include #include #include "utils/code_utils.h" +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { #if OPENTHREAD_ENABLE_CLI_LOGGING @@ -52,3 +54,4 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat (void)aFormat; #endif // OPENTHREAD_ENABLE_CLI_LOGGING } +#endif diff --git a/examples/platforms/efr32/openthread-core-efr32-config.h b/examples/platforms/efr32/openthread-core-efr32-config.h index 24c018d48..aa64191b7 100644 --- a/examples/platforms/efr32/openthread-core-efr32-config.h +++ b/examples/platforms/efr32/openthread-core-efr32-config.h @@ -35,6 +35,15 @@ #ifndef OPENTHREAD_CORE_EFR32_CONFIG_H_ #define OPENTHREAD_CORE_EFR32_CONFIG_H_ +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The efr32 platform provides an otPlatLog() function. + */ +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + /** * @def OPENTHREAD_CONFIG_PLATFORM_INFO * @@ -43,14 +52,6 @@ */ #define OPENTHREAD_CONFIG_PLATFORM_INFO "EFR32" -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - /* * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_RETRANSMIT * diff --git a/examples/platforms/efr32/platform-efr32.h b/examples/platforms/efr32/platform-efr32.h index 816d57906..5216ee020 100644 --- a/examples/platforms/efr32/platform-efr32.h +++ b/examples/platforms/efr32/platform-efr32.h @@ -35,6 +35,8 @@ #ifndef PLATFORM_EFR32_H_ #define PLATFORM_EFR32_H_ +#include +#include #include "em_device.h" #include "em_system.h" #include "core_cm4.h" diff --git a/examples/platforms/emsk/Makefile.am b/examples/platforms/emsk/Makefile.am index 83bf0e8a1..98697bc75 100644 --- a/examples/platforms/emsk/Makefile.am +++ b/examples/platforms/emsk/Makefile.am @@ -68,6 +68,7 @@ COMMONCPPFLAGS PLATFORM_SOURCES = \ alarm.c \ flash.c \ + logging.c \ misc.c \ platform.c \ radio.c \ diff --git a/examples/platforms/emsk/logging.c b/examples/platforms/emsk/logging.c index b436a40c9..2edeae529 100755 --- a/examples/platforms/emsk/logging.c +++ b/examples/platforms/emsk/logging.c @@ -32,12 +32,15 @@ * */ +#include +#include #include "openthread/platform/logging.h" +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { (void)aLogLevel; (void)aLogRegion; (void)aFormat; } - +#endif diff --git a/examples/platforms/emsk/openthread-core-emsk-config.h b/examples/platforms/emsk/openthread-core-emsk-config.h index 4002c0e7d..fab142f9f 100644 --- a/examples/platforms/emsk/openthread-core-emsk-config.h +++ b/examples/platforms/emsk/openthread-core-emsk-config.h @@ -34,6 +34,15 @@ #ifndef OPENTHREAD_CORE_EMSK_CONFIG_H_ #define OPENTHREAD_CORE_EMSK_CONFIG_H_ +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The emsk platform provides an otPlatLog() function. + */ +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + /** * @def OPENTHREAD_CONFIG_PLATFORM_INFO * @@ -42,14 +51,6 @@ */ #define OPENTHREAD_CONFIG_PLATFORM_INFO "EMSK" -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - /** * @def OPENTHREAD_CONFIG_ENABLE_SOFTWARE_ACK_TIMEOUT * diff --git a/examples/platforms/emsk/platform-emsk.h b/examples/platforms/emsk/platform-emsk.h index 217d84e32..038f72e48 100755 --- a/examples/platforms/emsk/platform-emsk.h +++ b/examples/platforms/emsk/platform-emsk.h @@ -35,6 +35,8 @@ #ifndef PLATFORM_EMSK_H_ #define PLATFORM_EMSK_H_ +#include +#include #include #include #include "openthread/types.h" diff --git a/examples/platforms/emsk/radio.c b/examples/platforms/emsk/radio.c index 047f55af7..87fdf5dd3 100644 --- a/examples/platforms/emsk/radio.c +++ b/examples/platforms/emsk/radio.c @@ -31,6 +31,8 @@ * This file implements the OpenThread platform abstraction for radio communication. * */ +#include +#include #include "openthread/types.h" @@ -246,7 +248,8 @@ void otPlatRadioSetPanId(otInstance *aInstance, uint16_t panid) void otPlatRadioSetExtendedAddress(otInstance *aInstance, const otExtAddress *address) { (void)aInstance; - mrf24j40_set_eui(address->m8); + /* cast to remove const, FIXME: perhaps the bsp library should be updated? */ + mrf24j40_set_eui((uint8_t *)(address->m8)); } void otPlatRadioSetShortAddress(otInstance *aInstance, uint16_t address) diff --git a/examples/platforms/gp712/logging.c b/examples/platforms/gp712/logging.c index 69358f1a6..01de39d7b 100644 --- a/examples/platforms/gp712/logging.c +++ b/examples/platforms/gp712/logging.c @@ -26,6 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include "platform_qorvo.h" #include @@ -51,6 +53,8 @@ offset += (unsigned int)charsWritten; \ otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) -1 ] = 0) +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) + int PlatOtLogLevelToSysLogLevel(otLogLevel aLogLevel) { int sysloglevel; @@ -105,3 +109,4 @@ exit: (void)aLogRegion; } +#endif diff --git a/examples/platforms/gp712/platform_qorvo.h b/examples/platforms/gp712/platform_qorvo.h index 7bfed1b95..006aa7659 100644 --- a/examples/platforms/gp712/platform_qorvo.h +++ b/examples/platforms/gp712/platform_qorvo.h @@ -35,6 +35,8 @@ #ifndef PLATFORM_QORVO_H_ #define PLATFORM_QORVO_H_ +#include +#include #include #include diff --git a/examples/platforms/kw41z/logging.c b/examples/platforms/kw41z/logging.c index 0e7c364a3..3ab8cfdce 100644 --- a/examples/platforms/kw41z/logging.c +++ b/examples/platforms/kw41z/logging.c @@ -36,6 +36,7 @@ #include "fsl_device_registers.h" #include +#include #include "openthread/platform/logging.h" #if OPENTHREAD_ENABLE_CLI_LOGGING @@ -49,6 +50,7 @@ #include #endif +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { #if OPENTHREAD_ENABLE_CLI_LOGGING @@ -62,3 +64,4 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat (void)aFormat; #endif // OPENTHREAD_ENABLE_CLI_LOGGING } +#endif diff --git a/examples/platforms/kw41z/openthread-core-kw41z-config.h b/examples/platforms/kw41z/openthread-core-kw41z-config.h index 33a279736..7dea49796 100644 --- a/examples/platforms/kw41z/openthread-core-kw41z-config.h +++ b/examples/platforms/kw41z/openthread-core-kw41z-config.h @@ -35,6 +35,15 @@ #ifndef OPENTHREAD_CORE_KW41Z_CONFIG_H_ #define OPENTHREAD_CORE_KW41Z_CONFIG_H_ +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The emsk platform provides an otPlatLog() function. + */ +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + /** * @def OPENTHREAD_CONFIG_PLATFORM_INFO * @@ -43,14 +52,6 @@ */ #define OPENTHREAD_CONFIG_PLATFORM_INFO "KW41Z" -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 - /** * @def SETTINGS_CONFIG_BASE_ADDRESS * diff --git a/examples/platforms/kw41z/platform-kw41z.h b/examples/platforms/kw41z/platform-kw41z.h index c65682523..aee52729d 100644 --- a/examples/platforms/kw41z/platform-kw41z.h +++ b/examples/platforms/kw41z/platform-kw41z.h @@ -35,6 +35,8 @@ #ifndef PLATFORM_KW41Z_H_ #define PLATFORM_KW41Z_H_ +#include +#include #include #include "openthread/types.h" diff --git a/examples/platforms/nrf52840/alarm.c b/examples/platforms/nrf52840/alarm.c index 9fd03f566..d235798ea 100644 --- a/examples/platforms/nrf52840/alarm.c +++ b/examples/platforms/nrf52840/alarm.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/diag.c b/examples/platforms/nrf52840/diag.c index f35b1461c..81c5fa814 100644 --- a/examples/platforms/nrf52840/diag.c +++ b/examples/platforms/nrf52840/diag.c @@ -26,6 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/flash.c b/examples/platforms/nrf52840/flash.c index 176ac6710..0c34b05cc 100644 --- a/examples/platforms/nrf52840/flash.c +++ b/examples/platforms/nrf52840/flash.c @@ -26,6 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/flash_nosd.c b/examples/platforms/nrf52840/flash_nosd.c index 198a8d741..c4f4eec3c 100644 --- a/examples/platforms/nrf52840/flash_nosd.c +++ b/examples/platforms/nrf52840/flash_nosd.c @@ -26,6 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/flash_sd.c b/examples/platforms/nrf52840/flash_sd.c index e829179ed..14fc34f8f 100644 --- a/examples/platforms/nrf52840/flash_sd.c +++ b/examples/platforms/nrf52840/flash_sd.c @@ -26,6 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/logging.c b/examples/platforms/nrf52840/logging.c index 8947cccf3..80806f8f8 100644 --- a/examples/platforms/nrf52840/logging.c +++ b/examples/platforms/nrf52840/logging.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include @@ -45,7 +48,7 @@ #include #include -#if (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0) +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) #include #if (LOG_RTT_COLOR_ENABLE == 1) @@ -174,4 +177,4 @@ exit: return; } -#endif // (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0) +#endif // (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) diff --git a/examples/platforms/nrf52840/misc.c b/examples/platforms/nrf52840/misc.c index f10747b6e..99e594db5 100644 --- a/examples/platforms/nrf52840/misc.c +++ b/examples/platforms/nrf52840/misc.c @@ -26,7 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include +#include #include #include diff --git a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h index 275f8c7d0..60ba17854 100644 --- a/examples/platforms/nrf52840/openthread-core-nrf52840-config.h +++ b/examples/platforms/nrf52840/openthread-core-nrf52840-config.h @@ -35,6 +35,23 @@ #ifndef OPENTHREAD_CORE_NRF52840_CONFIG_H_ #define OPENTHREAD_CORE_NRF52840_CONFIG_H_ +/* + * The GNU Autoconf system defines a PACKAGE macro which is the name + * of the software package. This name collides with PACKAGE field in + * the nRF52 Factory Information Configuration Registers (FICR) + * structure. + */ +#undef PACKAGE + +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * The nrf52840 platform provides an otPlatLog() function. + */ +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHERAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + /** * @def OPENTHREAD_CONFIG_PLATFORM_INFO * diff --git a/examples/platforms/nrf52840/platform.c b/examples/platforms/nrf52840/platform.c index c0f9cc154..fb9cb84dc 100644 --- a/examples/platforms/nrf52840/platform.c +++ b/examples/platforms/nrf52840/platform.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include @@ -54,7 +57,7 @@ void PlatformInit(int argc, char *argv[]) nrf_drv_clock_init(); -#if (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0) +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) nrf5LogInit(); #endif nrf5AlarmInit(); @@ -75,7 +78,7 @@ void PlatformDeinit(void) nrf5UartDeinit(); nrf5RandomDeinit(); nrf5AlarmDeinit(); -#if (OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT == 0) +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) nrf5LogDeinit(); #endif } diff --git a/examples/platforms/nrf52840/radio.c b/examples/platforms/nrf52840/radio.c index cc29e397a..2e6ab7292 100644 --- a/examples/platforms/nrf52840/radio.c +++ b/examples/platforms/nrf52840/radio.c @@ -33,10 +33,8 @@ */ #include -// NRF tools use #define PACKAGE - for other purposes -// ie: the physical package the chip comes in -// This conflicts with the GNU Autoconf "PACAKGE" define -#undef PACKAGE +#include +#include #include #include diff --git a/examples/platforms/nrf52840/random.c b/examples/platforms/nrf52840/random.c index d02d6fb57..322f4ca2a 100644 --- a/examples/platforms/nrf52840/random.c +++ b/examples/platforms/nrf52840/random.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/softdevice.c b/examples/platforms/nrf52840/softdevice.c index 6bf77e53c..e0435ad3a 100644 --- a/examples/platforms/nrf52840/softdevice.c +++ b/examples/platforms/nrf52840/softdevice.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include #include diff --git a/examples/platforms/nrf52840/uart.c b/examples/platforms/nrf52840/uart.c index a19539ff9..9cac2d71e 100644 --- a/examples/platforms/nrf52840/uart.c +++ b/examples/platforms/nrf52840/uart.c @@ -32,6 +32,9 @@ * */ +#include +#include + #include #include diff --git a/examples/platforms/posix/logging.c b/examples/platforms/posix/logging.c index 531c1d450..b906147ef 100644 --- a/examples/platforms/posix/logging.c +++ b/examples/platforms/posix/logging.c @@ -26,6 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include +#include #include "platform-posix.h" #include @@ -51,6 +53,8 @@ offset += (unsigned int)charsWritten; \ otEXPECT_ACTION(offset < sizeof(logString), logString[sizeof(logString) -1 ] = 0) + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_HOST_OS) || (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED) void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) { char logString[512]; @@ -79,3 +83,4 @@ exit: (void)aLogRegion; } +#endif diff --git a/examples/platforms/posix/openthread-core-posix-config.h b/examples/platforms/posix/openthread-core-posix-config.h index ddc5d3f03..a30bed1c2 100644 --- a/examples/platforms/posix/openthread-core-posix-config.h +++ b/examples/platforms/posix/openthread-core-posix-config.h @@ -44,12 +44,14 @@ #define OPENTHREAD_CONFIG_PLATFORM_INFO "POSIX" /** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT + * @def OPENTHREAD_CONFIG_LOG_OUTPUT * - * Define to 1 to enable default log output. + * Specify where the log output should go. * */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 +#ifndef OPENTHREAD_CONFIG_LOG_OUTPUT /* allow command line override */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_HOST_OS +#endif /** * @def OPENTHREAD_CONFIG_ENABLE_PLATFORM_USEC_TIMER diff --git a/examples/platforms/posix/platform-posix.h b/examples/platforms/posix/platform-posix.h index 138ff4d76..590743b86 100644 --- a/examples/platforms/posix/platform-posix.h +++ b/examples/platforms/posix/platform-posix.h @@ -36,6 +36,7 @@ #define PLATFORM_POSIX_H_ #include +#include #include #include diff --git a/examples/platforms/posix/uart-posix.c b/examples/platforms/posix/uart-posix.c index 57225f76b..b4364902e 100644 --- a/examples/platforms/posix/uart-posix.c +++ b/examples/platforms/posix/uart-posix.c @@ -38,6 +38,7 @@ #include #include +#include #include #include "utils/code_utils.h" @@ -285,3 +286,49 @@ void platformUartProcess(void) } } } + +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART && (OPENTHREAD_CONFIG_LOG_OUTPUT==OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) + +static FILE *posix_logfile; + +otError otPlatDebugUart_logfile(const char *filename) +{ + posix_logfile = fopen(filename, "wt"); + + return posix_logfile ? OT_ERROR_NONE : OT_ERROR_FAILED; +} + +void otPlatDebugUart_putchar_raw(int c) +{ + FILE *fp; + + /* note: log file will have a mix of cr/lf and + * in some/many cases duplicate cr because in + * some cases the log function {ie: Mbed} already + * includes the CR or LF... but other log functions + * do not include cr/lf and expect it appened + */ + fp = posix_logfile; + + if (fp != NULL) + { + /* log is lost ... until a file is setup */ + fputc(c, fp); + /* we could "fflush" but will not */ + } +} + +int otPlatDebugUart_kbhit(void) +{ + /* not supported */ + return 0; +} + +int otPlatDebugUart_getc(void) +{ + /* not supported */ + return -1; +} + +#endif + diff --git a/examples/platforms/utils/Makefile.am b/examples/platforms/utils/Makefile.am index 2dedb801e..220ead217 100644 --- a/examples/platforms/utils/Makefile.am +++ b/examples/platforms/utils/Makefile.am @@ -37,6 +37,7 @@ libopenthread_platform_utils_a_CPPFLAGS = \ $(NULL) libopenthread_platform_utils_a_SOURCES = \ + debug_uart.c \ settings.cpp \ $(NULL) diff --git a/examples/platforms/utils/debug_uart.c b/examples/platforms/utils/debug_uart.c new file mode 100644 index 000000000..ab93f281e --- /dev/null +++ b/examples/platforms/utils/debug_uart.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2017, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Implimentation note: + * These are all "weak" so that + * a platform may if it chooses + * override the instance. + */ + +OT_TOOL_WEAK +void otPlatDebugUart_printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + otPlatDebugUart_vprintf(fmt, ap); + va_end(ap); +} + +OT_TOOL_WEAK +void otPlatDebugUart_vprintf(const char *fmt, va_list ap) +{ + char buf[128]; + /* by standard ... + * vsnprintf() always null terminates + */ + vsnprintf(buf, sizeof(buf), fmt, ap); + /* however ... some platforms have bugs */ + buf[sizeof(buf) - 1] = 0; + otPlatDebugUart_puts_no_nl(buf); +} + +OT_TOOL_WEAK +void otPlatDebugUart_write_bytes(const uint8_t *pBytes, int nBytes) +{ + while (nBytes > 0) + { + otPlatDebugUart_putchar((int)(*pBytes)); + pBytes++; + nBytes--; + } +} + +OT_TOOL_WEAK +void otPlatDebugUart_puts_no_nl(const char *s) +{ + while (*s) + { + otPlatDebugUart_putchar(*s); + s++; + } +} + +OT_TOOL_WEAK +void otPlatDebugUart_puts(const char *s) +{ + otPlatDebugUart_puts_no_nl(s); + otPlatDebugUart_putchar('\n'); +} + +OT_TOOL_WEAK +void otPlatDebugUart_putchar(int c) +{ + /* map lf to crlf as needed */ + if (c == '\n') + { + otPlatDebugUart_putchar_raw('\r'); + } + + otPlatDebugUart_putchar_raw(c); +} + + +/* provide WEAK stubs for platforms that do not impliment all functions */ +OT_TOOL_WEAK +void otPlatDebugUart_putchar_raw(int c) +{ + OT_UNUSED_VARIABLE(c); +} + +OT_TOOL_WEAK +int otPlatDebugUart_kbhit(void) +{ + return 0; /* nothing */ +} + +OT_TOOL_WEAK +int otPlatDebugUart_getc(void) +{ + return -1; /* nothing */ +} + +OT_TOOL_WEAK +otError otPlatDebugUart_logfile(const char *filename) +{ + OT_UNUSED_VARIABLE(filename); + return OT_ERROR_FAILED; +} + +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) +/* this should not be a WEAK function */ +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + va_list ap; + uint32_t now; + + OT_UNUSED_VARIABLE(aLogLevel); + OT_UNUSED_VARIABLE(aLogRegion); + + now = otPlatAlarmMilliGetNow(); + otPlatDebugUart_printf("%3d.%03d | ", (int)(now / 1000), (int)(now % 1000)); + va_start(ap, aFormat); + otPlatDebugUart_vprintf(aFormat, ap); + va_end(ap); + + otPlatDebugUart_putchar('\n'); +} +#endif diff --git a/include/openthread-windows-config.h b/include/openthread-windows-config.h index f9aee519b..980c486f6 100644 --- a/include/openthread-windows-config.h +++ b/include/openthread-windows-config.h @@ -37,7 +37,7 @@ #define OPENTHREAD_ENABLE_MULTIPLE_INSTANCES 1 /* Define to 1 if you want to enable default log output. */ -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 1 +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_HOST_OS /* Define to 1 to enable the commissioner role. */ #define OPENTHREAD_ENABLE_COMMISSIONER 1 diff --git a/include/openthread/cli.h b/include/openthread/cli.h index 93d0a448d..e6b5575d1 100644 --- a/include/openthread/cli.h +++ b/include/openthread/cli.h @@ -36,7 +36,7 @@ #define CLI_H_ #include - +#include #include #ifdef __cplusplus @@ -93,6 +93,16 @@ void otCliConsoleInputLine(char *aBuf, uint16_t aBufLength); */ void otCliUartInit(otInstance *aInstance); +/** + * Callback to write the OpenThread Log to the CLI console + * + * @param[in] aLogLevel The log level. + * @param[in] aLogRegion The log region. + * @param[in] aFormat A pointer to the format string. + * @param[in] ap va_list matching aFormat. + */ +void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list ap); + /** * @} * diff --git a/include/openthread/ncp.h b/include/openthread/ncp.h index e1ddb471e..371a10801 100644 --- a/include/openthread/ncp.h +++ b/include/openthread/ncp.h @@ -36,6 +36,7 @@ #define NCP_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -201,6 +202,16 @@ void otNcpHandleDidReceiveNewLegacyUlaPrefix(const uint8_t *aUlaPrefix); */ void otNcpRegisterLegacyHandlers(const otNcpLegacyHandlers *aHandlers); +/** + * Callback to write the OpenThread Log to the NCP Spinel Tunnel. + * + * @param[in] aLogLevel The log level. + * @param[in] aLogRegion The log region. + * @param[in] aFormat A pointer to the format string. + * @param[in] ap va_list matching aFormat. + */ +void otNcpPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list ap); + /** * @} * diff --git a/include/openthread/platform/Makefile.am b/include/openthread/platform/Makefile.am index 3108989b7..56b93958a 100644 --- a/include/openthread/platform/Makefile.am +++ b/include/openthread/platform/Makefile.am @@ -45,6 +45,9 @@ ot_platform_headers =\ toolchain.h \ $(NULL) +noinst_HEADERS = \ + debug_uart.h + ot_platformdir = $(includedir)/openthread/platform dist_ot_platform_HEADERS = $(ot_platform_headers) diff --git a/include/openthread/platform/alarm-micro.h b/include/openthread/platform/alarm-micro.h index b3825e580..ff7ca670d 100644 --- a/include/openthread/platform/alarm-micro.h +++ b/include/openthread/platform/alarm-micro.h @@ -71,7 +71,7 @@ void otPlatAlarmMicroStop(otInstance *aInstance); /** * Get the current time. * - * @param[out] aNow The current time in microseconds. + * @returns The current time in microseconds. * */ uint32_t otPlatAlarmMicroGetNow(void); diff --git a/include/openthread/platform/debug_uart.h b/include/openthread/platform/debug_uart.h new file mode 100644 index 000000000..442e6037e --- /dev/null +++ b/include/openthread/platform/debug_uart.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef OPENTHREAD_PLATFORM_DEBUG_UART_H +#define OPENTHREAD_PLATFORM_DEBUG_UART_H + +#include + +/** + * @file + * + * Note: This is NOT a public thread API, and this header file is *NOT* + * installed as part of openthread, this is an pseudo-internal + * debug feature usable by developers during the course of development. + * + * This implements a very basic debug uart useful for logging + * messages when the primary uart is already engaged (example the NCP) + * and encapsulating logs is not practical. + * + * Implimentation Notes: + * + * Only 3 functions are required to be implimented by the platform. + * see/search for the word MUST in the comments below. + * + * The other functions (without MUST in the comment) are WEAK symbols + * that can optionally be overridden by the platform or the application. + * + * many of the other functions are simply convience functions to + * aid a developer during their normal course of work and are not + * intended to be present, or used in production system. + */ + +#if __cplusplus +extern "C" { +#endif + + /** + * @addtogroup internal-debug-api + * + * @{ + */ + + /** + * Standard printf() to the debug uart with no log decoration. + * + * @param[in] fmt printf formatter text + * + * This is a debug convience function that is not intended to be + * used in anything other then "debug scenarios" by a developer. + * + * lf -> cr/lf mapping is automatically handled via otPlatDebugUart_putchar() + * + * @sa otPlatDebugUart_vprintf() for limitations + * + * This is a WEAK symbol that can easily be overridden as needed. + */ + void otPlatDebugUart_printf(const char *fmt, ...); + + /** + * Stanard vprintf() to the debug uart, with no log decoration. + * + * @param[in] fmt printf formatter text + * @param[in] ap va_list value for print parameters. + * + * Implimentation limitation: this formats the text into + * a purposely small text buffer on the stack, thus long + * messages may be truncated. + * + * This is a WEAK symbol that can easily be overridden as needed. + * + * For example, some platforms might override this via a non-WEAK + * symbol because the platform provides a UART_vprintf() like + * function that can handle an arbitrary length output. + */ + void otPlatDebugUart_vprintf(const char *fmt, va_list ap); + + /** + * Platform specific write single byte to Debug Uart + * This should not perform CR/LF mapping. + * + * This function MUST be implimented by the platform + * + * @param[in] the_byte what to transmit + */ + void otPlatDebugUart_putchar_raw(int the_byte); + + /** + * Poll/test debug uart if a key has been pressed. + * It would be common to a stub function that returns 0. + * + * This function MUST be implimented by the platform + * + * @retval zero - nothing ready + * @retval nonzero - otPlatDebugUart_getc() will succeed. + */ + int otPlatDebugUart_kbhit(void); + + /** + * Poll/Read a byte from the debug uart + * + * This function MUST be implimented by the platform + * + * @retval (negative) no data available, @sa otPlatDebugUart_kbhit() + * @retval (0x00..0x0ff) data byte value + * + */ + int otPlatDebugUart_getc(void); + + /** + * Write byte to the uart, expand cr/lf as need. + * + * A WEAK default implimentation is provided + * that can be overridden as needed. + * + * @param[in] the_byte the byte to transmit + */ + void otPlatDebugUart_putchar(int the_byte); + + /** + * identical to "man 3 puts" - terminates with lf + * Which is then mapped to cr/lf as required + * + * A WEAK default implimentation is provided + * that can be overridden as needed. + * + * @param[in] s the string to print with a lf at the end + */ + void otPlatDebugUart_puts(const char *s); + + /** + * Write N bytes to the UART, mapping cr/lf + * + * @param[in] pBytes pointer to bytes to transmit. + * @param[in] nBytes how many bytes to transmit. + */ + void otPlatDebugUart_write_bytes(const uint8_t *pBytes, int nBytes); + + /** + * puts() without a terminal newline. + * see: "man 3 puts", without a adding a terminal lf + * + * @param[in] s the string to print without a lf at the end + * + * Note, the terminal "lf" mapped to cr/lf via + * the function otPlatDebugUart_putchar() + */ + void otPlatDebugUart_puts_no_nl(const char *s); + + /** + * Some platforms (posix) can log to a file. + * + * @returns OT_ERROR_NONE + * @returns OT_ERROR_FAILED + * + * Platforms that desire this MUST provide an implimentation. + * + */ + otError otPlatDebugUart_logfile(const char *filename); + + /** + * @} + * + */ + +#if __cplusplus +} // extern "C" +#endif + +#endif // OPENTHREAD_PLATFORM_DEBUG_UART_H + diff --git a/include/openthread/platform/logging-windows.h b/include/openthread/platform/logging-windows.h index b39f5ba2d..82a5aea9d 100644 --- a/include/openthread/platform/logging-windows.h +++ b/include/openthread/platform/logging-windows.h @@ -64,6 +64,7 @@ WPP_DEFINE_BIT(OT_NDIAG) /* 0x00020000 */ \ WPP_DEFINE_BIT(OT_COAP) /* 0x00040000 */ \ WPP_DEFINE_BIT(API_DEFAULT) /* 0x00080000 */ \ + WPP_DEFINE_BIT(OT_CLI) /* 0x00100000 */ \ ) #define WPP_LEVEL_FLAGS_LOGGER(lvl,flag) WPP_FLAG_LOGGER(flag) @@ -469,6 +470,34 @@ // otLogDebgCoap{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_COAP}(CTX, MSG, ...); // end_wpp +// ==CLI== + +// begin_wpp config +// USEPREFIX (otLogCritCli, "[%p]COAP%!SPACE!", &CTX); +// otLogCritCli{LEVEL=TRACE_LEVEL_ERROR,FLAGS=OT_COAP}(CTX, MSG, ...); +// end_wpp + +// begin_wpp config +// USEPREFIX (otLogWarnCli, "[%p]COAP%!SPACE!", &CTX); +// otLogWarnCli{LEVEL=TRACE_LEVEL_WARNING,FLAGS=OT_COAP}(CTX, MSG, ...); +// end_wpp + +// begin_wpp config +// USEPREFIX (otLogInfoCli, "[%p]COAP%!SPACE!", &CTX); +// otLogInfoCli{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_COAP}(CTX, MSG, ...); +// end_wpp + +// begin_wpp config +// USEPREFIX (otLogInfoCliErr, "[%p]COAP%!SPACE!", &CTX); +// otLogInfoCliErr{LEVEL=TRACE_LEVEL_INFORMATION,FLAGS=OT_COAP}(CTX, EXP, MSG, ...); +// USESUFFIX(otLogInfoCliErr, ", %!otError!", EXP); +// end_wpp + +// begin_wpp config +// USEPREFIX (otLogDebgCli, "[%p]COAP%!SPACE!", &CTX); +// otLogDebgCli{LEVEL=TRACE_LEVEL_VERBOSE,FLAGS=OT_COAP}(CTX, MSG, ...); +// end_wpp + // ==FUNC== // begin_wpp config diff --git a/include/openthread/platform/logging.h b/include/openthread/platform/logging.h index dd9ab4cc9..0f9e9c2fc 100644 --- a/include/openthread/platform/logging.h +++ b/include/openthread/platform/logging.h @@ -36,6 +36,9 @@ #define LOGGING_H_ #include +#include + +#include #ifdef __cplusplus extern "C" { @@ -53,35 +56,18 @@ extern "C" { /** * Log levels. + * + * Implimentation note: These exist as defines (not enums) so that + * embedded code can remove code at compile time via if/else/endif */ + #define OT_LOG_LEVEL_NONE 0 ///< None #define OT_LOG_LEVEL_CRIT 1 ///< Critical #define OT_LOG_LEVEL_WARN 2 ///< Warning #define OT_LOG_LEVEL_INFO 3 ///< Info #define OT_LOG_LEVEL_DEBG 4 ///< Debug -typedef uint8_t otLogLevel; - -/** - * This enum represents log regions. - * - */ -typedef enum otLogRegion -{ - OT_LOG_REGION_API = 1, ///< OpenThread API - OT_LOG_REGION_MLE = 2, ///< MLE - OT_LOG_REGION_ARP = 3, ///< EID-to-RLOC mapping. - OT_LOG_REGION_NET_DATA = 4, ///< Network Data - OT_LOG_REGION_ICMP = 5, ///< ICMPv6 - OT_LOG_REGION_IP6 = 6, ///< IPv6 - OT_LOG_REGION_MAC = 7, ///< IEEE 802.15.4 MAC - OT_LOG_REGION_MEM = 8, ///< Memory - OT_LOG_REGION_NCP = 9, ///< NCP - OT_LOG_REGION_MESH_COP = 10, ///< Mesh Commissioning Protocol - OT_LOG_REGION_NET_DIAG = 11, ///< Network Diagnostic - OT_LOG_REGION_PLATFORM = 12, ///< Platform - OT_LOG_REGION_COAP = 13, ///< CoAP -} otLogRegion; +/* note: The enum otLogRegion is found in 'openthread/types.h' */ /** * This function outputs logs. @@ -94,6 +80,17 @@ typedef enum otLogRegion */ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...); +/** + * This function outputs logs. + * + * @param[in] aLogLevel The log level. + * @param[in] aLogRegion The log region. + * @param[in] aFormat A pointer to the format string. + * @param[in] ap va_list matching information for aFormat + * + */ +void otPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list ap); + /** * @} * diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index 0af620710..0d827e616 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -38,6 +38,7 @@ #include +#include #include #ifdef __cplusplus diff --git a/include/openthread/platform/toolchain.h b/include/openthread/platform/toolchain.h index 7506e60cc..c2708d908 100644 --- a/include/openthread/platform/toolchain.h +++ b/include/openthread/platform/toolchain.h @@ -91,6 +91,27 @@ extern "C" { * */ +/** + * @def OT_TOOL_WEAK + * + * Compiler-specific weak symbol modifier. + * + */ + +/** + * @def OT_CALL + * + * Compiler-specific function modifier, ie: Win DLL support + * + */ + +/** + * @def OT_CDECL + * + * Compiler-specific function modifier, ie: Win DLL support + * + */ + // =========== TOOLCHAIN SELECTION : START =========== #if defined(__GNUC__) || defined(__clang__) || defined(__CC_ARM) || defined(__TI_ARM__) diff --git a/include/openthread/types.h b/include/openthread/types.h index 37a414df8..a95becb5d 100644 --- a/include/openthread/types.h +++ b/include/openthread/types.h @@ -35,6 +35,8 @@ #ifndef OPENTHREAD_TYPES_H_ #define OPENTHREAD_TYPES_H_ +#include + #include #include #ifdef OTDLL @@ -1095,6 +1097,40 @@ typedef void (OTCALL *otDeviceAvailabilityChangedCallback)(bool aAdded, const GU #endif // OTDLL +/** + * Log levels. + * + * Implimentation note: Log Levels are defines so that embedded + * implimentations can elimiate code at compile time via if/else/endif + * See openthread/platform/logging.h for details. + * + * @sa OT_LOG_LEVEL_NONE and related macros. + */ +typedef uint8_t otLogLevel; + +/** + * This enum represents log regions. + * + */ +typedef enum otLogRegion +{ + OT_LOG_REGION_API = 1, ///< OpenThread API + OT_LOG_REGION_MLE = 2, ///< MLE + OT_LOG_REGION_ARP = 3, ///< EID-to-RLOC mapping. + OT_LOG_REGION_NET_DATA = 4, ///< Network Data + OT_LOG_REGION_ICMP = 5, ///< ICMPv6 + OT_LOG_REGION_IP6 = 6, ///< IPv6 + OT_LOG_REGION_MAC = 7, ///< IEEE 802.15.4 MAC + OT_LOG_REGION_MEM = 8, ///< Memory + OT_LOG_REGION_NCP = 9, ///< NCP + OT_LOG_REGION_MESH_COP = 10, ///< Mesh Commissioning Protocol + OT_LOG_REGION_NET_DIAG = 11, ///< Network Diagnostic + OT_LOG_REGION_PLATFORM = 12, ///< Platform + OT_LOG_REGION_COAP = 13, ///< CoAP + OT_LOG_REGION_CLI = 14, ///< Cli +} otLogRegion; + + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/cli/README.md b/src/cli/README.md index eafb1c95e..11e765232 100644 --- a/src/cli/README.md +++ b/src/cli/README.md @@ -37,6 +37,7 @@ OpenThread test scripts use the CLI to execute test cases. * [leaderpartitionid](#leaderpartitionid) * [leaderweight](#leaderweight) * [linkquality](#linkquality-extaddr) +* [logfilename](#logfilename) * [macfilter](#macfilter) * [masterkey](#masterkey) * [mode](#mode) @@ -1033,6 +1034,15 @@ Set the link quality on the link to a given extended address. Done ``` +### logfilename FILENAME + +- Note: POSIX Platform Only, ie: `OPENTHREAD_EXAMPLES_POSIX` +- Requires `OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART` + +Specifies filename to capture otPlatLog() messages, useful when +debugging automated test scripts on Linux when logging disrupts +the automated test scripts. + ### masterkey Get the Thread Master Key value. diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 4f9f36f5a..bb2e10af8 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -77,6 +77,10 @@ #include "cli_coap.hpp" #endif +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX +#include +#endif + #include "common/encoding.hpp" using ot::Encoding::BigEndian::HostSwap16; @@ -124,6 +128,9 @@ const struct Command Interpreter::sCommands[] = { "eui64", &Interpreter::ProcessEui64 }, #ifdef OPENTHREAD_EXAMPLES_POSIX { "exit", &Interpreter::ProcessExit }, +#endif +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX + { "logfilename", &Interpreter::ProcessLogFilename }, #endif { "extaddr", &Interpreter::ProcessExtAddress }, { "extpanid", &Interpreter::ProcessExtPanId }, @@ -907,6 +914,27 @@ void Interpreter::ProcessExit(int argc, char *argv[]) } #endif +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX + +void Interpreter::ProcessLogFilename(int argc, char *argv[]) +{ + otError error = OT_ERROR_NONE; + + if (argc == 1) + { + error = otPlatDebugUart_logfile(argv[0]); + SuccessOrExit(error); + } + else + { + error = OT_ERROR_PARSE; + } + +exit: + AppendResult(error); +} +#endif + void Interpreter::ProcessExtPanId(int argc, char *argv[]) { otError error = OT_ERROR_NONE; diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index be5c5758a..9966e6c64 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -197,6 +197,9 @@ private: void ProcessEui64(int argc, char *argv[]); #ifdef OPENTHREAD_EXAMPLES_POSIX void ProcessExit(int argc, char *argv[]); +#endif +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && OPENTHREAD_EXAMPLES_POSIX + void ProcessLogFilename(int argc, char *argv[]); #endif void ProcessExtAddress(int argc, char *argv[]); void ProcessExtPanId(int argc, char *argv[]); diff --git a/src/cli/cli_uart.cpp b/src/cli/cli_uart.cpp index e106052b5..b7e20dfb0 100644 --- a/src/cli/cli_uart.cpp +++ b/src/cli/cli_uart.cpp @@ -49,6 +49,11 @@ #include "common/encoding.hpp" #include "common/new.hpp" #include "common/tasklet.hpp" +#include "common/logging.hpp" + +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART +#include +#endif namespace ot { namespace Cli { @@ -149,6 +154,34 @@ otError Uart::ProcessCommand(void) mRxBuffer[--mRxLength] = '\0'; } +#if OPENTHREAD_CONFIG_LOG_OUTPUT != OPENTHREAD_CONFIG_LOG_OUTPUT_NONE + /* + * Note this is here for this reason: + * + * TEXT (command) input ... in a test automation script occurs + * rapidly and often without gaps between the command and the + * terminal CR + * + * In contrast as a human is typing there is a delay between the + * last character of a command and the terminal CR which executes + * a command. + * + * During that human induced delay a tasklet may be scheduled and + * the LOG becomes confusing and it is hard to determine when + * something happened. Which happened first? the command-CR or + * the tasklet. + * + * Yes, while rare it is a race condition that is hard to debug. + * + * Thus this is here to afirmatively LOG exactly when the CLI + * command is being executed. + */ +#if OPENTHREAD_ENABLE_MULTIPLE_INSTANCES + /* TODO: how exactly do we get the instance here? */ +#else + otLogInfoCli(otGetInstance(), "execute command: %s", mRxBuffer); +#endif +#endif mInterpreter.ProcessLine(mRxBuffer, mRxLength, *this); mRxLength = 0; @@ -214,6 +247,10 @@ void Uart::Send(void) if (mSendLength > 0) { +#if OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + /* duplicate the output to the debug uart */ + otPlatDebugUart_write_bytes(reinterpret_cast(mTxBuffer + mTxHead), mSendLength); +#endif otPlatUartSend(reinterpret_cast(mTxBuffer + mTxHead), mSendLength); } @@ -235,30 +272,19 @@ void Uart::SendDoneTask(void) Send(); } -#if OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT -#ifdef __cplusplus -extern "C" { -#endif -void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +extern "C" void otCliPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list ap) { if (NULL == Uart::sUartServer) { return; } - va_list args; - va_start(args, aFormat); - Uart::sUartServer->OutputFormatV(aFormat, args); + Uart::sUartServer->OutputFormatV(aFormat, ap); Uart::sUartServer->OutputFormat("\r\n"); - va_end(args); OT_UNUSED_VARIABLE(aLogLevel); OT_UNUSED_VARIABLE(aLogRegion); } -#ifdef __cplusplus -} // extern "C" -#endif -#endif // OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT } // namespace Cli } // namespace ot diff --git a/src/core/common/logging.cpp b/src/core/common/logging.cpp index b94f534a9..b7ceeba0c 100644 --- a/src/core/common/logging.cpp +++ b/src/core/common/logging.cpp @@ -413,6 +413,16 @@ const char *otThreadErrorToString(otError aError) return retval; } +#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_NONE +/* this provides a stub, incase something uses the function */ +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) +{ + OT_UNUSED_VARIABLE(aLogLevel); + OT_UNUSED_VARIABLE(aLogRegion); + OT_UNUSED_VARIABLE(aFormat); +} +#endif + #ifdef __cplusplus }; #endif diff --git a/src/core/common/logging.hpp b/src/core/common/logging.hpp index 4ab4c4d96..1fb433796 100644 --- a/src/core/common/logging.hpp +++ b/src/core/common/logging.hpp @@ -739,6 +739,63 @@ extern "C" { #define otLogCertMeshCoP(aInstance, aFormat, ...) #endif +/** + * @def otLogCritCli + * + * This method generates a log with level critical for the CoAP region. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aFormat A pointer to the format string. + * @param[in] ... Arguments for the format specification. + * + */ + +/** + * @def otLogWarnCli + * + * This method generates a log with level warning for the CoAP region. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aFormat A pointer to the format string. + * @param[in] ... Arguments for the format specification. + * + */ + +/** + * @def otLogInfoCli + * + * This method generates a log with level info for the CoAP region. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aFormat A pointer to the format string. + * @param[in] ... Arguments for the format specification. + * + */ + +/** + * @def otLogDebgCli + * + * This method generates a log with level debug for the CoAP region. + * + * @param[in] aInstance A reference to the OpenThread instance. + * @param[in] aFormat A pointer to the format string. + * @param[in] ... Arguments for the format specification. + * + */ +#if OPENTHREAD_CONFIG_LOG_CLI == 1 +#define otLogCritCli(aInstance, aFormat, ...) otLogCrit(&aInstance, OT_LOG_REGION_COAP, aFormat, ## __VA_ARGS__) +#define otLogWarnCli(aInstance, aFormat, ...) otLogWarn(&aInstance, OT_LOG_REGION_COAP, aFormat, ## __VA_ARGS__) +#define otLogInfoCli(aInstance, aFormat, ...) otLogInfo(&aInstance, OT_LOG_REGION_COAP, aFormat, ## __VA_ARGS__) +#define otLogInfoCliErr(aInstance, aError, aFormat, ...) \ + otLogInfo(&aInstance, OT_LOG_REGION_COAP, "Error %s: " aFormat, otThreadErrorToString(aError), ## __VA_ARGS__) +#define otLogDebgCli(aInstance, aFormat, ...) otLogDebg(&aInstance, OT_LOG_REGION_COAP, aFormat, ## __VA_ARGS__) +#else +#define otLogCritCli(aInstance, aFormat, ...) +#define otLogWarnCli(aInstance, aFormat, ...) +#define otLogInfoCli(aInstance, aFormat, ...) +#define otLogInfoCliErr(aInstance, aError, aFormat, ...) +#define otLogDebgCli(aInstance, aFormat, ...) +#endif /** * @def otLogCritCoap diff --git a/src/core/openthread-core-default-config.h b/src/core/openthread-core-default-config.h index 365367bb8..0def911b4 100644 --- a/src/core/openthread-core-default-config.h +++ b/src/core/openthread-core-default-config.h @@ -565,6 +565,16 @@ #define OPENTHREAD_CONFIG_LOG_PLATFORM 0 #endif // OPENTHREAD_CONFIG_LOG_PLATFORM +/** + * @def OPENTHREAD_CONFIG_LOG_CLI + * + * Define to enable CLI logging. + * + */ +#ifndef OPENTHREAD_CONFIG_LOG_CLI +#define OPENTHREAD_CONFIG_LOG_CLI 1 +#endif // OPENTHREAD_CONFIG_LOG_CLI + /** * @def OPENTHREAD_CONFIG_LOG_COAP * @@ -615,18 +625,6 @@ #define OPENTHREAD_CONFIG_PLAT_LOG_FUNCTION otPlatLog #endif -/** - * @def OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT - * - * Define to 1 to enable default log output. - * - * When enabled OpenThread provides a default implementation for `otPlatLog()` which is tied to either NCP or CLI - * stream writes. - * - */ -#ifndef OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT -#define OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT 0 -#endif /** * @def OPENTHREAD_CONFIG_NUM_DHCP_PREFIXES @@ -851,7 +849,7 @@ #define OPENTHREAD_CONFIG_NCP_ENABLE_PEEK_POKE 0 #endif -/* +/** * @def OPENTHREAD_CONFIG_STAY_AWAKE_BETWEEN_FRAGMENTS * * Define as 1 to stay awake between fragments while transmitting a large packet, @@ -862,4 +860,75 @@ #define OPENTHREAD_CONFIG_STAY_AWAKE_BETWEEN_FRAGMENTS 0 #endif + +/* + * @def OPENTHREAD_CONFIG_ENABLE_DEBUG_UART + * + * Enable the "Debug Uart" platform feature. + * + * In the embedded world, the CLI application uses a UART as a console + * and the NCP application can be configured to use either a UART or + * a SPI type device to transfer data to the host. + * + * The Debug UART is or requires a second uart on the platform. + * + * The Debug Uart has two uses: + * + * Use #1 - for random 'debug printf' type messages a developer may need + * Use #2 (selected via DEBUG_LOG_OUTPUT) is a log output. + * + * See #include for more details + */ +#ifndef OPENTHREAD_CONFIG_ENABLE_DEBUG_UART +#define OPENTHREAD_CONFIG_ENABLE_DEBUG_UART 0 +#endif + +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT + * + * Selects if, and where the LOG output goes to. + * + * There are several options available + * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_NONE + * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED + * - @sa OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART + * - and others + * + * Note: + * + * 1) Because the default is: OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED + * The platform is expected to provide at least a stub for `otPlatLog()` + * + * 2) This is effectively an ENUM so it can be if/else/endif at compile time. + */ + +/** + * @def OPENTHREAD_CONFIG_LOG_OUTPUT Select the DEFAULT log output method. + */ +#if !defined(OPENTHREAD_CONFIG_LOG_OUTPUT) +#define OPENTHREAD_CONFIG_LOG_OUTPUT OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED +#endif + +/** Log output goes to the bit bucket (disabled) */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT_NONE 0 +/** Log output goes to the debug uart */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART 1 +/** Log output goes to the "application" provides otPlatLog() */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT_APP 2 +/** Log output goes to POSIX and WIN32 logging schemes */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT_HOST_OS 3 +/** Log output is handled by a platform defined function */ +#define OPENTHREAD_CONFIG_LOG_OUTPUT_PLATFORM_DEFINED 4 + +/* + * Verify debug uart dependency + * + * It is reasonable to only enable the debug uart + * and not enable logs to the DEBUG uart. + */ +#if (OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_DEBUG_UART) && (!OPENTHREAD_CONFIG_ENABLE_DEBUG_UART) +#error OPENTHREAD_CONFIG_ENABLE_DEBUG_UART_LOG requires OPENTHREAD_CONFIG_ENABLE_DEBUG_UART +#endif + + #endif // OPENTHREAD_CORE_DEFAULT_CONFIG_H_ diff --git a/src/core/utils/wrap_stdbool.h b/src/core/utils/wrap_stdbool.h index 644582827..d38f5f219 100644 --- a/src/core/utils/wrap_stdbool.h +++ b/src/core/utils/wrap_stdbool.h @@ -44,16 +44,17 @@ /* c++ has a built in bool */ #else +#if !defined(__bool_true_false_are_defined) +#define __bool_true_false_are_defined 1 +#define false 0 +#define true 1 + #if defined(_MSC_VER) #define bool _Bool #else typedef _Bool bool; #endif // visual studio has a bool -#if !defined(__bool_true_false_are_defined) -#define __bool_true_false_are_defined 1 -#define false 0 -#define true 1 #endif // bool defined #endif // __cplusplus diff --git a/src/ncp/ncp_base.cpp b/src/ncp/ncp_base.cpp index 1cbede3f4..f08438e91 100644 --- a/src/ncp/ncp_base.cpp +++ b/src/ncp/ncp_base.cpp @@ -2436,3 +2436,23 @@ otError otNcpStreamWrite(int aStreamId, const uint8_t *aDataPtr, int aDataLen) return error; } + + +extern "C" void otNcpPlatLogv(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, va_list ap) +{ + char logString[128]; + int charsWritten; + + if ((charsWritten = vsnprintf(logString, sizeof(logString), aFormat, ap)) > 0) + { + if (charsWritten > static_cast(sizeof(logString) - 1)) + { + charsWritten = static_cast(sizeof(logString) - 1); + } + + otNcpStreamWrite(0, reinterpret_cast(logString), charsWritten); + } + + OT_UNUSED_VARIABLE(aLogLevel); + OT_UNUSED_VARIABLE(aLogRegion); +} diff --git a/src/ncp/ncp_uart.cpp b/src/ncp/ncp_uart.cpp index b97bbb2f8..ef3089e1e 100644 --- a/src/ncp/ncp_uart.cpp +++ b/src/ncp/ncp_uart.cpp @@ -270,38 +270,6 @@ void NcpUart::HandleError(otError aError, uint8_t *aBuf, uint16_t aBufLength) otNcpStreamWrite(0, reinterpret_cast(hexbuf + 1), static_cast(strlen(hexbuf) - 1)); } -#if OPENTHREAD_CONFIG_ENABLE_DEFAULT_LOG_OUTPUT -#ifdef __cplusplus -extern "C" { -#endif -void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...) -{ - char logString[128]; - int charsWritten; - va_list args; - - va_start(args, aFormat); - - if ((charsWritten = vsnprintf(logString, sizeof(logString), aFormat, args)) > 0) - { - if (charsWritten > static_cast(sizeof(logString) - 1)) - { - charsWritten = static_cast(sizeof(logString) - 1); - } - - otNcpStreamWrite(0, reinterpret_cast(logString), charsWritten); - } - - va_end(args); - - OT_UNUSED_VARIABLE(aLogLevel); - OT_UNUSED_VARIABLE(aLogRegion); -} -#ifdef __cplusplus -} // extern "C" -#endif -#endif // OPENTHREAD_ENABLE_CLI_LOGGING - } // namespace Ncp } // namespace ot