From 90eac68ff5e4bac500597334adc5ff1302efdf2b Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 5 Aug 2016 11:56:01 -0700 Subject: [PATCH] Use placement-new to initialize static variables in CLI. (#341) --- src/cli/cli.cpp | 30 ++++++++++++++++++++++-------- src/cli/cli.hpp | 32 +++++++++++++++++++++++++++++--- src/cli/cli_uart.cpp | 1 + 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/cli/cli.cpp b/src/cli/cli.cpp index 31ae84d9f..fec2a72dd 100644 --- a/src/cli/cli.cpp +++ b/src/cli/cli.cpp @@ -41,6 +41,7 @@ #include "cli.hpp" #include "cli_dataset.hpp" #include +#include #include using Thread::Encoding::BigEndian::HostSwap16; @@ -89,14 +90,27 @@ const struct Command Interpreter::sCommands[] = otNetifAddress Interpreter::sAddress; -Ip6::IcmpEcho Interpreter::sIcmpEcho(&HandleEchoResponse, NULL); +static otDEFINE_ALIGNED_VAR(sIcmpEchoBuf, sizeof(Ip6::IcmpEcho), uint64_t); +Ip6::IcmpEcho *Interpreter::sIcmpEcho; + +static otDEFINE_ALIGNED_VAR(sPingTimerBuf, sizeof(Timer), uint64_t); +Timer *Interpreter::sPingTimer; + Ip6::SockAddr Interpreter::sSockAddr; Server *Interpreter::sServer; uint8_t Interpreter::sEchoRequest[1500]; -uint16_t Interpreter::sLength = 8; -uint16_t Interpreter::sCount = 1; -uint32_t Interpreter::sInterval = 1000; -Timer Interpreter::sPingTimer(&HandlePingTimer, NULL); +uint16_t Interpreter::sLength; +uint16_t Interpreter::sCount; +uint32_t Interpreter::sInterval; + +void Interpreter::Init(void) +{ + sIcmpEcho = new(&sIcmpEchoBuf) Ip6::IcmpEcho(&HandleEchoResponse, NULL); + sPingTimer = new(&sPingTimerBuf) Timer(&HandlePingTimer, NULL); + sLength = 8; + sCount = 1; + sInterval = 1000; +} int Interpreter::Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength) { @@ -810,7 +824,7 @@ void Interpreter::ProcessPing(int argc, char *argv[]) long value; VerifyOrExit(argc > 0, error = kThreadError_Parse); - VerifyOrExit(!sPingTimer.IsRunning(), error = kThreadError_Busy); + VerifyOrExit(!sPingTimer->IsRunning(), error = kThreadError_Busy); memset(&sSockAddr, 0, sizeof(sSockAddr)); SuccessOrExit(error = sSockAddr.GetAddress().FromString(argv[0])); @@ -859,12 +873,12 @@ void Interpreter::HandlePingTimer(void *aContext) uint32_t timestamp = HostSwap32(Timer::GetNow()); memcpy(sEchoRequest, ×tamp, sizeof(timestamp)); - sIcmpEcho.SendEchoRequest(sSockAddr, sEchoRequest, sLength); + sIcmpEcho->SendEchoRequest(sSockAddr, sEchoRequest, sLength); sCount--; if (sCount) { - sPingTimer.Start(sInterval); + sPingTimer->Start(sInterval); } (void)aContext; diff --git a/src/cli/cli.hpp b/src/cli/cli.hpp index f86406cff..dc1035060 100644 --- a/src/cli/cli.hpp +++ b/src/cli/cli.hpp @@ -68,6 +68,12 @@ struct Command class Interpreter { public: + /** + * This method initializes the CLI interpreter. + * + */ + static void Init(void); + /** * This method interprets a CLI command. * @@ -78,7 +84,27 @@ public: */ static void ProcessLine(char *aBuf, uint16_t aBufLength, Server &aServer); - static ThreadError ParseLong(char *argv, long &value); + /** + * This method parses an ASCII string as a long. + * + * @param[in] aString A pointer to the ASCII string. + * @param[out] aLong A reference to where the parsed long is placed. + * + * @retval kThreadError_None Successfully parsed the ASCII string. + * @retval kThreadError_Parse Could not parse the ASCII string. + * + */ + static ThreadError ParseLong(char *aString, long &aLong); + + /** + * This method converts a hex string to binary. + * + * @param[in] aHex A pointer to the hex string. + * @param[out] aBin A pointer to where the binary representation is placed. + * @param[in] aBinLength Maximum length of the binary representation. + * + * @returns The number of bytes in the binary representation. + */ static int Hex2Bin(const char *aHex, uint8_t *aBin, uint16_t aBinLength); private: @@ -139,13 +165,13 @@ private: static otNetifAddress sAddress; static Ip6::SockAddr sSockAddr; - static Ip6::IcmpEcho sIcmpEcho; + static Ip6::IcmpEcho *sIcmpEcho; static Server *sServer; static uint8_t sEchoRequest[]; static uint16_t sLength; static uint16_t sCount; static uint32_t sInterval; - static Timer sPingTimer; + static Timer *sPingTimer; }; } // namespace Cli diff --git a/src/cli/cli_uart.cpp b/src/cli/cli_uart.cpp index 74e919670..fccbce388 100644 --- a/src/cli/cli_uart.cpp +++ b/src/cli/cli_uart.cpp @@ -58,6 +58,7 @@ static otDEFINE_ALIGNED_VAR(sCliUartRaw, sizeof(Uart), uint64_t); extern "C" void otCliUartInit(void) { sServer = new(&sCliUartRaw) Uart; + Interpreter::Init(); } Uart::Uart(void)