diff --git a/.clang-format b/.clang-format index d934c5cc5..eeed4bea7 100644 --- a/.clang-format +++ b/.clang-format @@ -1,70 +1,71 @@ -AlignTrailingComments : true -AllowAllParametersOfDeclarationOnNextLine : true -AllowShortBlocksOnASingleLine : false -AllowShortFunctionsOnASingleLine : "None" -AllowShortIfStatementsOnASingleLine : false -AllowShortLoopsOnASingleLine : false -AlwaysBreakBeforeMultilineStrings : true -BasedOnStyle : "Google" +#https://releases.llvm.org/5.0.2/tools/clang/docs/ClangFormatStyleOptions.html +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: "Inline" +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: true +BasedOnStyle: "Google" #BinPackParameters : false -BreakBeforeBinaryOperators : false -BreakBeforeBraces : "Custom" -BreakBeforeTernaryOperators : false -ColumnLimit : 120 -ContinuationIndentWidth : 4 -DerivePointerAlignment : false -DisableFormat : false -IndentCaseLabels : true -IndentWrappedFunctionNames : false -IndentWidth : 4 -Language : "Cpp" -MaxEmptyLinesToKeep : 1 -PointerBindsToType : false -SpaceBeforeAssignmentOperators : true -SpaceBeforeParens : "ControlStatements" -SpacesBeforeTrailingComments : 1 -SpacesInCStyleCastParentheses : false -SpacesInParentheses : false -Standard : "Cpp03" -TabWidth : 1 -UseTab : "Never" -AccessModifierOffset : -4 -AlignAfterOpenBracket : "Align" -AlignEscapedNewlines : "Left" -AlignOperands : true -AllowShortCaseLabelsOnASingleLine : false -AllowShortFunctionsOnASingleLine : "Inline" -AlwaysBreakAfterReturnType : "None" -AlwaysBreakTemplateDeclarations : true -BreakBeforeInheritanceComma : false -BreakConstructorInitializers : "BeforeComma" -CompactNamespaces : false -ConstructorInitializerAllOnOneLineOrOnePerLine : false -ConstructorInitializerIndentWidth : 0 -Cpp11BracedListStyle : false -FixNamespaceComments : true -NamespaceIndentation : "None" -PointerAlignment : "Right" -SortIncludes : true -SortUsingDeclarations : true -SpacesInAngles : false -SpaceAfterCStyleCast : false -SpaceInEmptyParentheses : false -SpacesInSquareBrackets : false +BreakBeforeBinaryOperators: false +BreakBeforeBraces: "Custom" +BreakBeforeTernaryOperators: false +ColumnLimit: 120 +ContinuationIndentWidth: 4 +DerivePointerAlignment: false +DisableFormat: false +IndentCaseLabels: true +IndentWrappedFunctionNames: false +IndentWidth: 4 +Language: "Cpp" +MaxEmptyLinesToKeep: 1 +PointerBindsToType: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: "ControlStatements" +SpacesBeforeTrailingComments: 1 +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +Standard: "Cpp03" +TabWidth: 1 +UseTab: "Never" +AccessModifierOffset: -4 +AlignAfterOpenBracket: "Align" +AlignEscapedNewlines: "Left" +AlignOperands: true +AllowShortCaseLabelsOnASingleLine: false +AlwaysBreakAfterReturnType: "None" +AlwaysBreakTemplateDeclarations: true +BreakBeforeInheritanceComma: false +BreakConstructorInitializers: "BeforeComma" +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 0 +Cpp11BracedListStyle: false +FixNamespaceComments: true +NamespaceIndentation: "None" +PointerAlignment: "Right" +SortIncludes: true +SortUsingDeclarations: true +SpacesInAngles: false +SpaceAfterCStyleCast: false +SpaceInEmptyParentheses: false +SpacesInSquareBrackets: false KeepEmptyLinesAtTheStartOfBlocks: true BraceWrapping: - AfterClass: true + AfterClass: true AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: false + AfterEnum: true + AfterFunction: true + AfterNamespace: false AfterObjCDeclaration: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true +#IncludeBlocks: "Preserve" # for future version of clang IncludeCategories: - - Regex: '^<' # system includes - Priority: 10 - - Regex: '^"erpc_' # erpc public includes - Priority: 1 + - Regex: "^<" # system includes + Priority: 10 + - Regex: '^"erpc_' # erpc public includes + Priority: 1 diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 000000000..8c7729bae --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,15 @@ +name: clang-format lint + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: DoozyX/clang-format-lint-action@v0.10 + with: + source: '.' + exclude: 'test/common/gtest/gtest.h test/common/gtest/gtest.cpp erpcgen/src/cpptemplate/cpptempl.h erpcgen/src/cpptemplate/cpptempl.cpp erpcgen/src/cpptemplate/cpptempl_test.cpp' + clangFormatVersion: 10 diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 000000000..9ca791ea4 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,13 @@ +name: Greetings + +on: [pull_request, issues] + +jobs: + greeting: + runs-on: ubuntu-latest + steps: + - uses: actions/first-interaction@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + issue-message: 'Hi eRPC user. Thank you for your interest and welcome. We hope you will enjoy this framework well.' + pr-message: 'Hi eRPC user. Thank you for your PR. We are appreciating that and we will try to review it as soon as possible. We hope you are enjoying this framework so far.' diff --git a/.travis.yml b/.travis.yml index 2afb8843a..dcf702755 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,13 +7,13 @@ compiler: os: - linux - osx -osx_image: xcode8.3 # OS X 10.12 +osx_image: xcode10.3 # OS X 10.14 before_install: - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get update -qq; fi - if [ $TRAVIS_OS_NAME == linux ]; then sudo apt-get install python bison flex libboost-dev libboost-filesystem-dev libboost-system-dev python ; fi - if [ $TRAVIS_OS_NAME == linux ]; then pyenv install 2.7.12 ; pyenv global 2.7.12; fi - if [ $TRAVIS_OS_NAME == osx ]; then brew update; fi -- if [ $TRAVIS_OS_NAME == osx ]; then brew install python bison flex && brew upgrade boost || true; fi +- if [ $TRAVIS_OS_NAME == osx ]; then brew install python bison flex -v -f 2>&1 && brew upgrade boost || true; fi - if [ $TRAVIS_OS_NAME == osx ]; then curl "https://bootstrap.pypa.io/get-pip.py" | sudo python; fi install: diff --git a/LICENSE b/LICENSE index b6b0efa9a..a05f102ec 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ -Copyright (c) 2014-2016 Freescale Semiconductor, Inc. -Copyright 2016-2018 NXP +Copyright 2014-2016 Freescale Semiconductor, Inc. +Copyright 2016-2020 NXP All rights reserved. SPDX-License-Identifier: BSD-3-Clause diff --git a/README.md b/README.md index fb243b6ad..31ab66619 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ Client side usage: void example_client(void) { // Initialize client running over UART. erpc_client_init( - erpc_transport_cmsis_uart_init(UART0_NonBlocking_Driver); + erpc_transport_cmsis_uart_init(Driver_USART0), + erpc_mbf_dynamic_init()); // Now we can call the remote function to turn on the green LED. set_led(kGreen, true); @@ -43,7 +44,8 @@ void set_led(LEDName whichLed, bool onOrOff) { void example_server(void) { // Initialize server running over UART. erpc_server_init( - erpc_transport_uart_init(UART0_NonBlocking_Driver); + erpc_transport_cmsis_uart_init(Driver_USART0), + erpc_mbf_dynamic_init()); // Add the IO service. erpc_add_service_to_server(create_IO_service()); @@ -61,9 +63,12 @@ Supported transports: * NXP Kinetis SPI and DSPI * POSIX and Windows serial port * TCP/IP (mostly for testing) -* [NXP RPMsg-Lite](https://github.com/NXPmicro/rpmsg-lite) +* [NXP RPMsg-Lite / RPMsg TTY](https://github.com/NXPmicro/rpmsg-lite) +* SPIdev Linux +* USB CDC +* NXP Messaging Unit -eRPC is available with an unrestrictive BSD 3-clause license. See the LICENSE file for the full license text. +eRPC is available with an unrestrictive BSD 3-clause license. See the [LICENSE file](https://github.com/EmbeddedRPC/erpc/blob/develop/LICENSE) for the full license text. ## Releases @@ -71,10 +76,19 @@ eRPC is available with an unrestrictive BSD 3-clause license. See the LICENSE fi ## Documentation -[Documentation](https://github.com/EmbeddedRPC/erpc/wiki) is in the `wiki` section. Commit sha in wiki repository: 7199a9c00fef4b952a6b05a8e3b0257f788e4eeb. +[Documentation](https://github.com/EmbeddedRPC/erpc/wiki) is in the `wiki` section. + +[eRPC Infrastructure documentation](https://embeddedrpc.github.io/) + +## Examples [Example IDL](examples/README.md) is available in the `examples/` folder. +Plenty of eRPC multicore and multiprocessor examples can be also found in NXP MCUXpressoSDK packages. Visit [https://mcuxpresso.nxp.com](https://mcuxpresso.nxp.com) to configure, build and download these packages.
+To get the board list with multicore support (eRPC included) use filtering based on Middleware and search for 'multicore' string. Once the selected package with the multicore middleware is downloaded, see
+/boards//multicore_examples for eRPC multicore examples (RPMsg_Lite or Messaging Unit transports used) or
+/boards//multiprocessor_examples for eRPC multiprocessor examples (UART or SPI transports used).
+eRPC examples use 'erpc_' name prefix. ## Directories @@ -88,12 +102,16 @@ eRPC is available with an unrestrictive BSD 3-clause license. See the LICENSE fi `erpcgen` - Holds source code for erpcgen and makefiles or project files to build erpcgen on Windows, Linux, and OS X. +`erpcsniffer` - Holds source code for erpcsniffer application. + `examples` - Several example IDL files. `mk` - Contains common makefiles for building eRPC components. `test` - Client/server tests. These tests verify the entire communications path from client to server and back. +`utilities` - Holds utilities which bring additional benefit to eRPC apps developers. + ## Building and installing @@ -117,11 +135,11 @@ Steps are described in [`erpcgen/VisualStudio_v14/readme_erpcgen.txt`](erpcgen/V Install these packages: * bison: GNU yacc-compatible parser generator * flex: A fast lexical analyzer generator -* libboost-dev, libboost-filesystem-dev, libboost-system-dev: Boost C++ libraries (Linux needs to use libboost version 1.58.0) +* libboost-dev, libboost-filesystem-dev, libboost-system-dev: Boost C++ libraries (Linux needs to use libboost version 1.65.0) * make: the GNU version of the 'make' utility * python: Python language interpreter (either 2.7 or 3.5+ work) -* gcc-core: GNU Compiler Collection (C, OpenMP) -* gcc-g++: GNU Compiler Collection (C++) +* gcc-7: GNU C compiler (recommended version) +* g++-7: GNU C++ compiler (recommended version) Mandatory for case, when build for different architecture is needed * gcc-multilib, g++-multilib @@ -130,9 +148,9 @@ Mandatory for case, when build for different architecture is needed #### Mac OS X Install these packages with [homebrew](http://brew.sh/): -* bison: GNU yacc-compatible parser generator -* flex: A fast lexical analyzer generator -* boost: Boost C++ libraries +* bison: GNU yacc-compatible parser generator (version 3.7.3 is recommended) +* flex: A fast lexical analyzer generator (version 2.6.4 is recommended) +* boost: Boost C++ libraries (version 1.74 is recommended) ### Building @@ -157,6 +175,8 @@ List of top level Makefile targets: - `all`: build all of the above - `install`: install liberpc.a, erpcgen, and include files +eRPC code is validated with respect to the C++ 11 standard. + ### Installing for Python To install the Python infrastructure for eRPC, first change to the `erpc_python/` directory. Then run the setup.py script like this: @@ -165,10 +185,11 @@ To install the Python infrastructure for eRPC, first change to the `erpc_python/ After installation, the `erpc` package is available via normal import statements. See the [erpc_python folder readme](erpc_python/readme.md) for more. -## Code providing: +## Code providing Repository on Github contains two main branches. __Master__ and __develop__. Code is developed on __develop__ branch. Release version is created via merging __develop__ branch into __master__ branch. --- -Copyright © 2014-2016 Freescale Semiconductor, Inc. -Copyright © 2016-2017 NXP +Copyright 2014-2016 Freescale Semiconductor, Inc. + +Copyright 2016-2020 NXP diff --git a/doxygen/Doxyfile.erpc b/doxygen/Doxyfile.erpc index a76e2af5c..0ff74c944 100644 --- a/doxygen/Doxyfile.erpc +++ b/doxygen/Doxyfile.erpc @@ -38,7 +38,7 @@ PROJECT_NAME = "eRPC API Reference" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "Rev. 1.7.2" +PROJECT_NUMBER = "Rev. 1.8.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doxygen/Doxyfile.erpcgen b/doxygen/Doxyfile.erpcgen index c83ed08a9..e62412998 100644 --- a/doxygen/Doxyfile.erpcgen +++ b/doxygen/Doxyfile.erpcgen @@ -38,7 +38,7 @@ PROJECT_NAME = "eRPC Generator (erpcgen)" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "Rev. 1.7.2" +PROJECT_NUMBER = "Rev. 1.8.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doxygen/html_footer.html b/doxygen/html_footer.html index 99eff856b..dd02cae32 100644 --- a/doxygen/html_footer.html +++ b/doxygen/html_footer.html @@ -3,14 +3,14 @@ diff --git a/erpc_c/Makefile b/erpc_c/Makefile index 36b172ad9..9d67344bf 100644 --- a/erpc_c/Makefile +++ b/erpc_c/Makefile @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------- # Copyright (C) 2016 Freescale Semiconductor, Inc. -# Copyright 2016-2017 NXP +# Copyright 2016-2020 NXP # All rights reserved. # # THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESS OR IMPLIED @@ -60,11 +60,14 @@ SOURCES += $(ERPC_C_ROOT)/infra/erpc_arbitrated_client_manager.cpp \ $(ERPC_C_ROOT)/infra/erpc_server.cpp \ $(ERPC_C_ROOT)/infra/erpc_simple_server.cpp \ $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.cpp \ + $(ERPC_C_ROOT)/infra/erpc_pre_post_action.cpp \ $(ERPC_C_ROOT)/port/erpc_port_stdlib.cpp \ $(ERPC_C_ROOT)/port/erpc_threading_pthreads.cpp \ $(ERPC_C_ROOT)/port/erpc_serial.cpp \ $(ERPC_C_ROOT)/setup/erpc_arbitrated_client_setup.cpp \ $(ERPC_C_ROOT)/setup/erpc_client_setup.cpp \ + $(ERPC_C_ROOT)/setup/erpc_setup_mbf_dynamic.cpp \ + $(ERPC_C_ROOT)/setup/erpc_setup_mbf_static.cpp \ $(ERPC_C_ROOT)/setup/erpc_server_setup.cpp \ $(ERPC_C_ROOT)/setup/erpc_setup_serial.cpp \ $(ERPC_C_ROOT)/transports/erpc_inter_thread_buffer_transport.cpp \ @@ -87,12 +90,16 @@ HEADERS += $(ERPC_C_ROOT)/config/erpc_config.h \ $(ERPC_C_ROOT)/infra/erpc_static_queue.h \ $(ERPC_C_ROOT)/infra/erpc_transport_arbitrator.h \ $(ERPC_C_ROOT)/infra/erpc_transport.h \ + $(ERPC_C_ROOT)/infra/erpc_client_server_common.h \ + $(ERPC_C_ROOT)/infra/erpc_pre_post_action.h \ + $(ERPC_C_ROOT)/port/erpc_setup_extensions.h \ $(ERPC_C_ROOT)/port/erpc_config_internal.h \ $(ERPC_C_ROOT)/port/erpc_port.h \ $(ERPC_C_ROOT)/port/erpc_threading.h \ $(ERPC_C_ROOT)/port/erpc_serial.h \ $(ERPC_C_ROOT)/setup/erpc_arbitrated_client_setup.h \ $(ERPC_C_ROOT)/setup/erpc_client_setup.h \ + $(ERPC_C_ROOT)/setup/erpc_mbf_setup.h \ $(ERPC_C_ROOT)/setup/erpc_server_setup.h \ $(ERPC_C_ROOT)/setup/erpc_transport_setup.h \ $(ERPC_C_ROOT)/transports/erpc_inter_thread_buffer_transport.h \ diff --git a/erpc_c/config/erpc_config.h b/erpc_c/config/erpc_config.h index a8a1b84a0..fbde2753b 100644 --- a/erpc_c/config/erpc_config.h +++ b/erpc_c/config/erpc_config.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2018 NXP + * Copyright 2016-2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -26,6 +27,8 @@ #define ERPC_THREADS_PTHREADS (1) //!< POSIX pthreads. #define ERPC_THREADS_FREERTOS (2) //!< FreeRTOS. #define ERPC_THREADS_ZEPHYR (3) //!< ZEPHYR. +#define ERPC_THREADS_MBED (4) //!< Mbed OS +#define ERPC_THREADS_WIN32 (5) //!< WIN32 #define ERPC_NOEXCEPT_DISABLED (0) //!< Disabling noexcept feature. #define ERPC_NOEXCEPT_ENABLED (1) //!< Enabling noexcept feature. @@ -41,6 +44,12 @@ #define ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED (0) //!< Do not use MCMGR for MU ISR management. #define ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED (1) //!< Use MCMGR for MU ISR management. + +#define ERPC_PRE_POST_ACTION_DISABLED (0) //!< Pre post shim callbacks functions disabled. +#define ERPC_PRE_POST_ACTION_ENABLED (1) //!< Pre post shim callback functions enabled. + +#define ERPC_PRE_POST_ACTION_DEFAULT_DISABLED (0) //!< Pre post shim default callbacks functions disabled. +#define ERPC_PRE_POST_ACTION_DEFAULT_ENABLED (1) //!< Pre post shim default callback functions enabled. //@} //! @name Configuration options @@ -62,13 +71,13 @@ //! Uncomment to change the size of buffers allocated by one of MessageBufferFactory. //! (@ref client_setup and @ref server_setup). The default size is set to 256. //! For RPMsg transport layer, ERPC_DEFAULT_BUFFER_SIZE must be 2^n - 16. -//#define ERPC_DEFAULT_BUFFER_SIZE (256) +//#define ERPC_DEFAULT_BUFFER_SIZE (256U) //! @def ERPC_DEFAULT_BUFFERS_COUNT //! //! Uncomment to change the count of buffers allocated by one of statically allocated messages. //! Default value is set to 2. -//#define ERPC_DEFAULT_BUFFERS_COUNT (2) +//#define ERPC_DEFAULT_BUFFERS_COUNT (2U) //! @def ERPC_NOEXCEPT //! @@ -94,8 +103,9 @@ //! @def ERPC_MESSAGE_LOGGING //! -//! Enable eRPC message logging code through the eRPC. Take look into "message_logging.h". Can be used for base printing -//! messages, or sending data to another system for data analysis. Default set to ERPC_MESSAGE_LOGGING_DISABLED. +//! Enable eRPC message logging code through the eRPC. Take look into "erpc_message_loggers.h". Can be used for base +//! printing messages, or sending data to another system for data analysis. Default set to +//! ERPC_MESSAGE_LOGGING_DISABLED. //! //! Uncomment for using logging feature. //#define ERPC_MESSAGE_LOGGING (ERPC_MESSAGE_LOGGING_ENABLED) @@ -112,10 +122,26 @@ //! is part of the project, otherwise the ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED option is used. This settings can be //! overwritten from the erpc_config.h by uncommenting the ERPC_TRANSPORT_MU_USE_MCMGR macro definition. Do not forget //! to add the MCMGR library into your project when ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED option is used! See the -//! mu_transport.h for additional MU settings. +//! erpc_mu_transport.h for additional MU settings. //#define ERPC_TRANSPORT_MU_USE_MCMGR ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED //@} +//! @def ERPC_PRE_POST_ACTION +//! +//! Enable eRPC pre and post callback functions shim code. Take look into "erpc_pre_post_action.h". Can be used for +//! detection of eRPC call freeze, ... Default set to ERPC_PRE_POST_ACTION_DISABLED. +//! +//! Uncomment for using pre post callback feature. +//#define ERPC_PRE_POST_ACTION (ERPC_PRE_POST_ACTION_ENABLED) + +//! @def ERPC_PRE_POST_ACTION_DEFAULT +//! +//! Enable eRPC pre and post default callback functions. Take look into "erpc_setup_extensions.h". Can be used for +//! detection of eRPC call freeze, ... Default set to ERPC_PRE_POST_ACTION_DEFAULT_DISABLED. +//! +//! Uncomment for using pre post default callback feature. +//#define ERPC_PRE_POST_ACTION_DEFAULT (ERPC_PRE_POST_ACTION_DEFAULT_ENABLED) + /*! @} */ #endif // _ERPC_CONFIG_H_ //////////////////////////////////////////////////////////////////////////////// diff --git a/erpc_c/infra/erpc_arbitrated_client_manager.cpp b/erpc_c/infra/erpc_arbitrated_client_manager.cpp index 50c204636..bf9e0ffde 100644 --- a/erpc_c/infra/erpc_arbitrated_client_manager.cpp +++ b/erpc_c/infra/erpc_arbitrated_client_manager.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,9 +8,15 @@ */ #include "erpc_arbitrated_client_manager.h" + #include "erpc_transport_arbitrator.h" + #include "assert.h" +#if ERPC_THREADS_IS(NONE) +#error "Arbitrator code does not work in no-threading configuration." +#endif + using namespace erpc; //////////////////////////////////////////////////////////////////////////////// @@ -19,9 +25,11 @@ using namespace erpc; #if ERPC_NESTED_CALLS_DETECTION extern bool nestingDetection; +#ifndef _WIN32 #pragma weak nestingDetection bool nestingDetection = false; #endif +#endif void ArbitratedClientManager::setArbitrator(TransportArbitrator *arbitrator) { @@ -29,7 +37,7 @@ void ArbitratedClientManager::setArbitrator(TransportArbitrator *arbitrator) m_transport = arbitrator; } -erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &request) +void ArbitratedClientManager::performClientRequest(RequestContext &request) { assert(m_arbitrator && "arbitrator not set"); @@ -42,13 +50,15 @@ erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &requ #if ERPC_NESTED_CALLS_DETECTION if (nestingDetection) { - return kErpcStatus_NestedCallFailure; + request.getCodec()->updateStatus(kErpcStatus_NestedCallFailure); + return; } #endif token = m_arbitrator->prepareClientReceive(request); if (!token) { - return kErpcStatus_Fail; + request.getCodec()->updateStatus(kErpcStatus_Fail); + return; } } @@ -58,7 +68,8 @@ erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &requ err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -66,7 +77,8 @@ erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &requ err = m_arbitrator->send(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } if (!request.isOneway()) @@ -75,14 +87,16 @@ erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &requ err = m_arbitrator->clientReceive(token); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #if ERPC_MESSAGE_LOGGING err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -90,9 +104,10 @@ erpc_status_t ArbitratedClientManager::performClientRequest(RequestContext &requ err = verifyReply(request); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } } - return kErpcStatus_Success; + return; } diff --git a/erpc_c/infra/erpc_arbitrated_client_manager.h b/erpc_c/infra/erpc_arbitrated_client_manager.h index 194dad061..6b909f877 100644 --- a/erpc_c/infra/erpc_arbitrated_client_manager.h +++ b/erpc_c/infra/erpc_arbitrated_client_manager.h @@ -69,10 +69,10 @@ class ArbitratedClientManager : public ClientManager * * @param[in] request Request context to perform. */ - virtual erpc_status_t performClientRequest(RequestContext &request); + virtual void performClientRequest(RequestContext &request); //! @brief This method is not used with this class. - void setTransport(Transport *transport) {} + void setTransport(Transport *transport) { (void)transport; } }; } // namespace erpc diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp index 2b5349cdc..ff22d12ae 100644 --- a/erpc_c/infra/erpc_basic_codec.cpp +++ b/erpc_c/infra/erpc_basic_codec.cpp @@ -8,6 +8,7 @@ */ #include "erpc_basic_codec.h" + #include using namespace erpc; diff --git a/erpc_c/infra/erpc_basic_codec.h b/erpc_c/infra/erpc_basic_codec.h index 4032ee96f..07aa18249 100644 --- a/erpc_c/infra/erpc_basic_codec.h +++ b/erpc_c/infra/erpc_basic_codec.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__BASIC_SERIALIZATION_H_ #include "erpc_codec.h" + #include /*! diff --git a/erpc_c/infra/erpc_client_manager.cpp b/erpc_c/infra/erpc_client_manager.cpp index f5d38c3a1..2955c6edf 100644 --- a/erpc_c/infra/erpc_client_manager.cpp +++ b/erpc_c/infra/erpc_client_manager.cpp @@ -8,6 +8,7 @@ */ #include "erpc_client_manager.h" + #include "assert.h" using namespace erpc; @@ -18,9 +19,11 @@ using namespace erpc; #if ERPC_NESTED_CALLS_DETECTION extern bool nestingDetection; +#ifndef _WIN32 #pragma weak nestingDetection bool nestingDetection = false; #endif +#endif void ClientManager::setTransport(Transport *transport) { @@ -35,8 +38,15 @@ RequestContext ClientManager::createRequest(bool isOneway) return RequestContext(++m_sequence, codec, isOneway); } -erpc_status_t ClientManager::performRequest(RequestContext &request) +void ClientManager::performRequest(RequestContext &request) { + // Check the codec status + if (kErpcStatus_Success != (request.getCodec()->getStatus())) + { + // Do not perform the request + return; + } + #if ERPC_NESTED_CALLS assert(m_serverThreadId && "server thread id was not set"); if (Thread::getCurrentThreadId() == m_serverThreadId) @@ -47,12 +57,13 @@ erpc_status_t ClientManager::performRequest(RequestContext &request) return performClientRequest(request); } -erpc_status_t ClientManager::performClientRequest(RequestContext &request) +void ClientManager::performClientRequest(RequestContext &request) { #if ERPC_NESTED_CALLS_DETECTION if (!request.isOneway() && nestingDetection) { - return kErpcStatus_NestedCallFailure; + request.getCodec()->updateStatus(kErpcStatus_NestedCallFailure); + return; } #endif @@ -62,7 +73,8 @@ erpc_status_t ClientManager::performClientRequest(RequestContext &request) err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -70,7 +82,8 @@ erpc_status_t ClientManager::performClientRequest(RequestContext &request) err = m_transport->send(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } // If the request is oneway, then there is nothing more to do. @@ -80,14 +93,16 @@ erpc_status_t ClientManager::performClientRequest(RequestContext &request) err = m_transport->receive(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #if ERPC_MESSAGE_LOGGING err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -95,15 +110,16 @@ erpc_status_t ClientManager::performClientRequest(RequestContext &request) err = verifyReply(request); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } } - return kErpcStatus_Success; + return; } #if ERPC_NESTED_CALLS -erpc_status_t ClientManager::performNestedClientRequest(RequestContext &request) +void ClientManager::performNestedClientRequest(RequestContext &request) { assert(m_transport && "transport/arbitrator not set"); @@ -113,7 +129,8 @@ erpc_status_t ClientManager::performNestedClientRequest(RequestContext &request) err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -121,7 +138,8 @@ erpc_status_t ClientManager::performNestedClientRequest(RequestContext &request) err = m_transport->send(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } // If the request is oneway, then there is nothing more to do. @@ -132,14 +150,16 @@ erpc_status_t ClientManager::performNestedClientRequest(RequestContext &request) err = m_server->run(request); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #if ERPC_MESSAGE_LOGGING err = logMessage(request.getCodec()->getBuffer()); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } #endif @@ -147,11 +167,10 @@ erpc_status_t ClientManager::performNestedClientRequest(RequestContext &request) err = verifyReply(request); if (err) { - return err; + request.getCodec()->updateStatus(err); + return; } } - - return kErpcStatus_Success; } #endif diff --git a/erpc_c/infra/erpc_client_manager.h b/erpc_c/infra/erpc_client_manager.h index cc4f825ac..4c333c3e8 100644 --- a/erpc_c/infra/erpc_client_manager.h +++ b/erpc_c/infra/erpc_client_manager.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -11,11 +12,9 @@ #define _EMBEDDED_RPC__CLIENT_MANAGER_H_ #ifdef __cplusplus +#include "erpc_client_server_common.h" #include "erpc_codec.h" #include "erpc_config_internal.h" -#if ERPC_MESSAGE_LOGGING -#include "erpc_message_loggers.h" -#endif #if ERPC_NESTED_CALLS #include "erpc_server.h" #include "erpc_threading.h" @@ -51,11 +50,7 @@ class Server; * * @ingroup infra_client */ -#if ERPC_MESSAGE_LOGGING -class ClientManager : public MessageLoggers -#else -class ClientManager -#endif +class ClientManager : public ClientServerCommon { public: /*! @@ -64,7 +59,8 @@ class ClientManager * This function initializes object attributes. */ ClientManager(void) - : m_messageFactory(NULL) + : ClientServerCommon() + , m_messageFactory(NULL) , m_codecFactory(NULL) , m_transport(NULL) , m_sequence(0) @@ -72,9 +68,6 @@ class ClientManager #if ERPC_NESTED_CALLS , m_server(NULL) , m_serverThreadId(NULL) -#endif -#if ERPC_MESSAGE_LOGGING - , MessageLoggers() #endif { } @@ -119,7 +112,7 @@ class ClientManager * * @param[in] request Request context to perform. */ - virtual erpc_status_t performRequest(RequestContext &request); + virtual void performRequest(RequestContext &request); /*! * @brief This function releases request context. @@ -180,7 +173,7 @@ class ClientManager * * @param[in] request Request context to perform. */ - virtual erpc_status_t performClientRequest(RequestContext &request); + virtual void performClientRequest(RequestContext &request); #if ERPC_NESTED_CALLS /*! @@ -190,7 +183,7 @@ class ClientManager * * @param[in] request Request context to perform. */ - virtual erpc_status_t performNestedClientRequest(RequestContext &request); + virtual void performNestedClientRequest(RequestContext &request); #endif //! @brief Validate that an incoming message is a reply. @@ -207,8 +200,8 @@ class ClientManager Codec *createBufferAndCodec(void); private: - ClientManager(const ClientManager &); //!< Disable copy ctor. - ClientManager &operator=(const ClientManager &); //!< Disable copy ctor. + ClientManager(const ClientManager &other); //!< Disable copy ctor. + ClientManager &operator=(const ClientManager &other); //!< Disable copy ctor. }; /*! @@ -228,10 +221,10 @@ class RequestContext * @param[in] codec Set in inout codec. * @param[in] isOneway Set information if codec is only oneway or bidirectional. */ - RequestContext(uint32_t sequence, Codec *codec, bool isOneway) + RequestContext(uint32_t sequence, Codec *codec, bool argIsOneway) : m_sequence(sequence) , m_codec(codec) - , m_oneway(isOneway) + , m_oneway(argIsOneway) { } diff --git a/erpc_c/infra/erpc_client_server_common.h b/erpc_c/infra/erpc_client_server_common.h new file mode 100644 index 000000000..08d720bf5 --- /dev/null +++ b/erpc_c/infra/erpc_client_server_common.h @@ -0,0 +1,96 @@ +/* + * Copyright 2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _EMBEDDED_RPC__CLIENTSERVERCOMMON_H_ +#define _EMBEDDED_RPC__CLIENTSERVERCOMMON_H_ + +#include "erpc_config_internal.h" +#if ERPC_MESSAGE_LOGGING +#include "erpc_message_loggers.h" +#endif +#if ERPC_PRE_POST_ACTION +#include "erpc_pre_post_action.h" +#endif + +/*! + * @addtogroup infra_transport + * @{ + * @file + */ + +//////////////////////////////////////////////////////////////////////////////// +// Classes +//////////////////////////////////////////////////////////////////////////////// + +namespace erpc { + +/*! + * @brief Common class inheritand by client and server class. + * + * @ingroup infra_utility + */ +class ClientServerCommon +#if ERPC_MESSAGE_LOGGING +#ifdef ERPC_OTHER_INHERITANCE + , +#else +#define ERPC_OTHER_INHERITANCE 1 +: +#endif + public MessageLoggers +#endif +#if ERPC_PRE_POST_ACTION +#ifdef ERPC_OTHER_INHERITANCE + , +#else +#define ERPC_OTHER_INHERITANCE 1 +: +#endif + public PrePostAction +#endif +{ +public: + /*! + * @brief ClientServerCommon constructor. + */ + ClientServerCommon(void) +#ifdef ERPC_OTHER_INHERITANCE +#undef ERPC_OTHER_INHERITANCE +#endif +#if ERPC_MESSAGE_LOGGING +#ifdef ERPC_OTHER_INHERITANCE + , +#else +#define ERPC_OTHER_INHERITANCE 1 + : +#endif + MessageLoggers() +#endif +#if ERPC_PRE_POST_ACTION +#ifdef ERPC_OTHER_INHERITANCE + , +#else +#define ERPC_OTHER_INHERITANCE 1 + : +#endif + PrePostAction(void) +#endif + {}; + + /*! + * @brief ClientServerCommon destructor + */ + ~ClientServerCommon(void){}; +}; + +} // namespace erpc + +/*! @} */ + +#endif // _EMBEDDED_RPC__CLIENTSERVERCOMMON_H_ diff --git a/erpc_c/infra/erpc_codec.h b/erpc_c/infra/erpc_codec.h index 60956a76c..a8e3a9e93 100644 --- a/erpc_c/infra/erpc_codec.h +++ b/erpc_c/infra/erpc_codec.h @@ -13,6 +13,7 @@ #include "erpc_common.h" #include "erpc_message_buffer.h" #include "erpc_transport.h" + #include #include @@ -30,7 +31,8 @@ namespace erpc { /*! * @brief Types of messages that can be encoded. */ -typedef enum _message_type { +typedef enum _message_type +{ kInvocationMessage = 0, kOnewayMessage, kReplyMessage, diff --git a/erpc_c/infra/erpc_framed_transport.cpp b/erpc_c/infra/erpc_framed_transport.cpp index 63a709e91..9b865d229 100644 --- a/erpc_c/infra/erpc_framed_transport.cpp +++ b/erpc_c/infra/erpc_framed_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -9,6 +9,7 @@ #include "erpc_framed_transport.h" #include "erpc_message_buffer.h" + #include #include @@ -21,7 +22,7 @@ using namespace erpc; FramedTransport::FramedTransport(void) : Transport() , m_crcImpl(NULL) -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) , m_sendLock() , m_receiveLock() #endif @@ -42,7 +43,7 @@ erpc_status_t FramedTransport::receive(MessageBuffer *message) Header h; { -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Mutex::Guard lock(m_receiveLock); #endif @@ -53,6 +54,12 @@ erpc_status_t FramedTransport::receive(MessageBuffer *message) return ret; } + // received size can't be zero. + if (h.m_messageSize == 0) + { + return kErpcStatus_ReceiveFailed; + } + // received size can't be larger then buffer length. if (h.m_messageSize > message->getLength()) { @@ -81,7 +88,7 @@ erpc_status_t FramedTransport::receive(MessageBuffer *message) erpc_status_t FramedTransport::send(MessageBuffer *message) { assert(m_crcImpl && "Uninitialized Crc16 object."); -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Mutex::Guard lock(m_sendLock); #endif diff --git a/erpc_c/infra/erpc_framed_transport.h b/erpc_c/infra/erpc_framed_transport.h index bd5ac87dd..52139d186 100644 --- a/erpc_c/infra/erpc_framed_transport.h +++ b/erpc_c/infra/erpc_framed_transport.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -13,9 +13,10 @@ #include "erpc_config_internal.h" #include "erpc_message_buffer.h" #include "erpc_transport.h" + #include -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) #include "erpc_threading.h" #endif @@ -110,7 +111,7 @@ class FramedTransport : public Transport protected: Crc16 *m_crcImpl; /*!< CRC object. */ -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Mutex m_sendLock; //!< Mutex protecting send. Mutex m_receiveLock; //!< Mutex protecting receive. #endif diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h index feed514ae..a096eacd1 100644 --- a/erpc_c/infra/erpc_manually_constructed.h +++ b/erpc_c/infra/erpc_manually_constructed.h @@ -52,11 +52,11 @@ class ManuallyConstructed T *get(void) { return reinterpret_cast(&m_storage); } const T *get(void) const { return reinterpret_cast(&m_storage); } T *operator->(void) { return get(); } - const T *operator->(void)const { return get(); } + const T *operator->(void) const { return get(); } T &operator*(void) { return *get(); } - const T &operator*(void)const { return *get(); } + const T &operator*(void) const { return *get(); } operator T *(void) { return get(); } - operator const T *(void)const { return get(); } + operator const T *(void) const { return get(); } //@} //! @name Explicit construction methods @@ -91,6 +91,12 @@ class ManuallyConstructed { new (m_storage) T(a1, a2, a3, a4, a5); } + + template + void construct(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6) + { + new (m_storage) T(a1, a2, a3, a4, a5, a6); + } //@} /*! diff --git a/erpc_c/infra/erpc_message_buffer.cpp b/erpc_c/infra/erpc_message_buffer.cpp index f2c1cd96a..5549e6a1a 100644 --- a/erpc_c/infra/erpc_message_buffer.cpp +++ b/erpc_c/infra/erpc_message_buffer.cpp @@ -8,6 +8,7 @@ */ #include "erpc_message_buffer.h" + #include #include diff --git a/erpc_c/infra/erpc_message_buffer.h b/erpc_c/infra/erpc_message_buffer.h index 3a5f9e22e..79a4652f4 100644 --- a/erpc_c/infra/erpc_message_buffer.h +++ b/erpc_c/infra/erpc_message_buffer.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__MESSAGE_BUFFER_H_ #include "erpc_common.h" + #include #include @@ -166,7 +167,7 @@ class MessageBuffer /*! * @brief Casting operator return local buffer. */ - operator const uint8_t *(void)const { return m_buf; } + operator const uint8_t *(void) const { return m_buf; } /*! * @brief Array operator return value of buffer at given index. @@ -276,7 +277,7 @@ class MessageBuffer /*! * @brief Casting operator return local buffer. */ - operator const uint8_t *(void)const { return m_pos; } + operator const uint8_t *(void) const { return m_pos; } /*! * @brief Array operator return value of buffer at given index. diff --git a/erpc_c/infra/erpc_message_loggers.cpp b/erpc_c/infra/erpc_message_loggers.cpp index 7295c23a5..82e49d7fb 100644 --- a/erpc_c/infra/erpc_message_loggers.cpp +++ b/erpc_c/infra/erpc_message_loggers.cpp @@ -7,6 +7,7 @@ */ #include "erpc_message_loggers.h" + #include using namespace erpc; diff --git a/erpc_c/infra/erpc_pre_post_action.cpp b/erpc_c/infra/erpc_pre_post_action.cpp new file mode 100644 index 000000000..7ab85fc26 --- /dev/null +++ b/erpc_c/infra/erpc_pre_post_action.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_pre_post_action.h" + +#include "erpc_config_internal.h" +#if ERPC_PRE_POST_ACTION_DEFAULT +#include "erpc_setup_extensions.h" +#endif + +using namespace erpc; +using namespace std; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +void PrePostAction::addPreCB(pre_post_action_cb preCB) +{ + if (preCB) + { + m_preCB = preCB; + } +#if ERPC_PRE_POST_ACTION_DEFAULT + else + { + m_preCB = erpc_pre_cb_default; + } +#endif +} + +void PrePostAction::addPostCB(pre_post_action_cb postCB) +{ + if (postCB) + { + m_postCB = postCB; + } +#if ERPC_PRE_POST_ACTION_DEFAULT + else + { + m_postCB = erpc_post_cb_default; + } +#endif +} \ No newline at end of file diff --git a/erpc_c/infra/erpc_pre_post_action.h b/erpc_c/infra/erpc_pre_post_action.h new file mode 100644 index 000000000..f38a0be9b --- /dev/null +++ b/erpc_c/infra/erpc_pre_post_action.h @@ -0,0 +1,95 @@ +/* + * Copyright 2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _EMBEDDED_RPC__PREPOSTACTION_H_ +#define _EMBEDDED_RPC__PREPOSTACTION_H_ + +#ifdef __cplusplus +#include +/*! + * @addtogroup infra_transport + * @{ + * @file + */ +extern "C" { +#endif + +typedef void (*pre_post_action_cb)(void); + +#ifdef __cplusplus +} + +//////////////////////////////////////////////////////////////////////////////// +// Classes +//////////////////////////////////////////////////////////////////////////////// + +namespace erpc { + +/*! + * @brief Client and server may used cb functions before and after rpc call. + * + * @ingroup infra_utility + */ +class PrePostAction +{ +public: + /*! + * @brief PrePostAction constructor. + */ + PrePostAction(void) + : m_preCB(NULL) + , m_postCB(NULL){}; + + /*! + * @brief This function sets "before eRPC call start" callback function. + * + * @param[in] preCB Pointer for callback function. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ + void addPreCB(pre_post_action_cb preCB); + + /*! + * @brief This function sets "after eRPC call finish" callback function. + * + * @param[in] postCB Pointer for callback function. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ + void addPostCB(pre_post_action_cb postCB); + + /*! + * @brief This function returns "before eRPC call start" callback function. + * + * @return preCB Pointer for callback function. + */ + pre_post_action_cb getPreCB(void) { return m_preCB; } + + /*! + * @brief This function returns "after eRPC call finish" callback function. + * + * @return postCB Pointer for callback function. + */ + pre_post_action_cb getPostCB(void) { return m_postCB; } + + /*! + * @brief PrePostAction destructor + */ + ~PrePostAction(void){}; + +protected: + pre_post_action_cb m_preCB; /*!< Pointer to "before eRPC call start" callback function. */ + pre_post_action_cb m_postCB; /*!< Pointer to after eRPC call finish" callback function. */ +}; + +} // namespace erpc + +/*! @} */ + +#endif + +#endif // _EMBEDDED_RPC__PREPOSTACTION_H_ diff --git a/erpc_c/infra/erpc_server.cpp b/erpc_c/infra/erpc_server.cpp index 5e3b98a97..86097cf9b 100644 --- a/erpc_c/infra/erpc_server.cpp +++ b/erpc_c/infra/erpc_server.cpp @@ -8,6 +8,7 @@ */ #include "erpc_server.h" + #include "assert.h" using namespace erpc; @@ -17,6 +18,7 @@ using namespace erpc; //////////////////////////////////////////////////////////////////////////////// #if ERPC_NESTED_CALLS_DETECTION +extern bool nestingDetection; bool nestingDetection = false; #endif @@ -42,6 +44,26 @@ void Server::addService(Service *service) link->setNext(service); } +void Server::removeService(Service *service) +{ + Service *link = m_firstService; + + if (link == service) + { + m_firstService = link->getNext(); + return; + } + while (link != NULL) + { + if (link->getNext() == service) + { + link->setNext(link->getNext()->getNext()); + return; + } + link = link->getNext(); + } +} + erpc_status_t Server::readHeadOfMessage(Codec *codec, message_type_t &msgType, uint32_t &serviceId, uint32_t &methodId, uint32_t &sequence) { diff --git a/erpc_c/infra/erpc_server.h b/erpc_c/infra/erpc_server.h index c9c8c2220..0712b970f 100644 --- a/erpc_c/infra/erpc_server.h +++ b/erpc_c/infra/erpc_server.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -10,14 +11,12 @@ #ifndef _EMBEDDED_RPC__SERVER_H_ #define _EMBEDDED_RPC__SERVER_H_ +#include "erpc_client_server_common.h" #include "erpc_codec.h" #include "erpc_config_internal.h" #if ERPC_NESTED_CALLS #include "erpc_client_manager.h" #endif -#if ERPC_MESSAGE_LOGGING -#include "erpc_message_loggers.h" -#endif /*! * @addtogroup infra_server @@ -101,11 +100,7 @@ class Service * * @ingroup infra_server */ -#if ERPC_MESSAGE_LOGGING -class Server : public MessageLoggers -#else -class Server -#endif +class Server : public ClientServerCommon { public: /*! @@ -114,13 +109,11 @@ class Server * This function initializes object attributes. */ Server(void) - : m_messageFactory() + : ClientServerCommon() + , m_messageFactory() , m_codecFactory() , m_transport() , m_firstService() -#if ERPC_MESSAGE_LOGGING - , MessageLoggers() -#endif { } @@ -159,6 +152,13 @@ class Server */ void addService(Service *service); + /*! + * @brief Remove service. + * + * @param[in] service Service to remove. + */ + void removeService(Service *service); + /*! * @brief This function runs the server. */ @@ -226,8 +226,8 @@ class Server private: // Disable copy ctor. - Server(const Server &); /*!< Disable copy ctor. */ - Server &operator=(const Server &); /*!< Disable copy ctor. */ + Server(const Server &other); /*!< Disable copy ctor. */ + Server &operator=(const Server &other); /*!< Disable copy ctor. */ }; } // namespace erpc diff --git a/erpc_c/infra/erpc_simple_server.cpp b/erpc_c/infra/erpc_simple_server.cpp index bb70639ae..c9a90b8d6 100644 --- a/erpc_c/infra/erpc_simple_server.cpp +++ b/erpc_c/infra/erpc_simple_server.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2014, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -15,16 +16,6 @@ using namespace erpc; // Code //////////////////////////////////////////////////////////////////////////////// -SimpleServer::~SimpleServer(void) -{ - while (m_firstService != NULL) - { - Service *firstService = m_firstService; - m_firstService = m_firstService->getNext(); - delete firstService; - } -} - void SimpleServer::disposeBufferAndCodec(Codec *codec) { if (codec) @@ -71,6 +62,15 @@ erpc_status_t SimpleServer::runInternalBegin(Codec **codec, MessageBuffer &buff, // Receive the next invocation request. erpc_status_t err = m_transport->receive(&buff); + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb preCB = this->getPreCB(void); + if (preCB) + { + preCB(); + } +#endif + if (err) { // Dispose of buffers. @@ -142,6 +142,14 @@ erpc_status_t SimpleServer::runInternalEnd(Codec *codec, message_type_t msgType, // Dispose of buffers and codecs. disposeBufferAndCodec(codec); +#if ERPC_PRE_POST_ACTION + pre_post_action_cb postCB = this->getPostCB(); + if (postCB) + { + postCB(); + } +#endif + return err; } @@ -170,7 +178,7 @@ erpc_status_t SimpleServer::run(RequestContext &request) uint32_t methodId; uint32_t sequence; - erpc_status_t err = runInternalBegin(&codec, buff, msgType, serviceId, methodId, sequence); + err = runInternalBegin(&codec, buff, msgType, serviceId, methodId, sequence); if (err) { diff --git a/erpc_c/infra/erpc_simple_server.h b/erpc_c/infra/erpc_simple_server.h index 01942e2d9..2326f0fff 100644 --- a/erpc_c/infra/erpc_simple_server.h +++ b/erpc_c/infra/erpc_simple_server.h @@ -41,11 +41,6 @@ class SimpleServer : public Server { } - /*! - * @brief SimpleServer destructor - */ - virtual ~SimpleServer(void); - /*! * @brief Run server in infinite loop. * diff --git a/erpc_c/infra/erpc_static_queue.h b/erpc_c/infra/erpc_static_queue.h index c55f8683f..52d8ee3f5 100644 --- a/erpc_c/infra/erpc_static_queue.h +++ b/erpc_c/infra/erpc_static_queue.h @@ -103,12 +103,12 @@ class StaticQueue } protected: - uint64_t m_storage[elementCount][(sizeof(T) + sizeof(uint64_t) - 1) / - sizeof(uint64_t)]; /*!< Preallocated space based on data type size and elements - count. */ - uint32_t m_capacity; /*!< Capacity of queue */ - uint32_t volatile m_head; /*!< Index to free slot */ - uint32_t volatile m_tail; /*!< Index to slot with m_data */ + uint64_t m_storage[elementCount] + [(sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t)]; /*!< Preallocated space based on data + type size and elements count. */ + uint32_t m_capacity; /*!< Capacity of queue */ + uint32_t volatile m_head; /*!< Index to free slot */ + uint32_t volatile m_tail; /*!< Index to slot with m_data */ }; } // namespace erpc diff --git a/erpc_c/infra/erpc_transport.h b/erpc_c/infra/erpc_transport.h index c3b3edc87..a670ec79d 100644 --- a/erpc_c/infra/erpc_transport.h +++ b/erpc_c/infra/erpc_transport.h @@ -13,6 +13,7 @@ #include "erpc_common.h" #include "erpc_crc16.h" #include "erpc_message_buffer.h" + #include /*! @@ -83,7 +84,7 @@ class Transport * * @param[in] crcImpl Object containing crc-16 compute function. */ - virtual void setCrc16(Crc16 *crcImpl){}; + virtual void setCrc16(Crc16 *crcImpl) { (void)crcImpl; } }; /*! diff --git a/erpc_c/infra/erpc_transport_arbitrator.cpp b/erpc_c/infra/erpc_transport_arbitrator.cpp index 846a5645a..07c5763da 100644 --- a/erpc_c/infra/erpc_transport_arbitrator.cpp +++ b/erpc_c/infra/erpc_transport_arbitrator.cpp @@ -1,17 +1,23 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_transport_arbitrator.h" + #include "erpc_config_internal.h" + #include #include #include +#if ERPC_THREADS_IS(NONE) +#error "Arbitrator code does not work in no-threading configuration." +#endif + using namespace erpc; //////////////////////////////////////////////////////////////////////////////// @@ -52,9 +58,20 @@ erpc_status_t TransportArbitrator::receive(MessageBuffer *message) erpc_status_t err = m_sharedTransport->receive(message); if (err) { + // if we timeout, we must unblock all pending client(s) + if (err == kErpcStatus_Timeout) + { + PendingClientInfo *client = m_clientList; + for (; client; client = client->m_next) + { + if (client->m_isValid) + { + client->m_sem.put(); + } + } + } return err; } - m_codec->setBuffer(*message); // Parse the message header. @@ -115,12 +132,11 @@ erpc_status_t TransportArbitrator::send(MessageBuffer *message) TransportArbitrator::client_token_t TransportArbitrator::prepareClientReceive(RequestContext &request) { PendingClientInfo *info = addPendingClient(); - if (!info) + if (NULL != info) { - return kErpcStatus_Fail; + info->m_request = &request; + info->m_isValid = true; } - info->m_request = &request; - info->m_isValid = true; return reinterpret_cast(info); } diff --git a/erpc_c/infra/erpc_version.h b/erpc_c/infra/erpc_version.h index 94964efc1..65ca7397b 100644 --- a/erpc_c/infra/erpc_version.h +++ b/erpc_c/infra/erpc_version.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -20,9 +20,9 @@ //////////////////////////////////////////////////////////////////////////////// //! @brief String version of eRPC. -#define ERPC_VERSION "1.7.2" +#define ERPC_VERSION "1.8.0" //! @brief Integer version of eRPC. -#define ERPC_VERSION_NUMBER 10702 +#define ERPC_VERSION_NUMBER 10800 /*! @} */ diff --git a/erpc_c/port/erpc_config_internal.h b/erpc_c/port/erpc_config_internal.h index 7f3a83bfc..9205bd2d5 100644 --- a/erpc_c/port/erpc_config_internal.h +++ b/erpc_c/port/erpc_config_internal.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -28,6 +29,15 @@ #endif #endif +// Determine if we are targeting WIN32 environment +#if !defined(ERPC_HAS_WIN32) + #if defined(_WIN32) + #define ERPC_HAS_WIN32 (1) + #else + #define ERPC_HAS_WIN32 (0) + #endif +#endif + // Safely detect FreeRTOSConfig.h. #define ERPC_HAS_FREERTOSCONFIG_H (0) #if defined(__has_include) @@ -45,6 +55,8 @@ #elif ERPC_HAS_FREERTOSCONFIG_H // Use FreeRTOS if we can auto detect it. #define ERPC_THREADS (ERPC_THREADS_FREERTOS) + #elif ERPC_HAS_WIN32 + #define ERPC_THREADS (ERPC_THREADS_WIN32) #else // Otherwise default to no threads. #define ERPC_THREADS (ERPC_THREADS_NONE) @@ -58,13 +70,13 @@ // Set default buffer size. #if !defined(ERPC_DEFAULT_BUFFER_SIZE) //! @brief Size of buffers allocated by BasicMessageBufferFactory in setup functions. - #define ERPC_DEFAULT_BUFFER_SIZE (256) + #define ERPC_DEFAULT_BUFFER_SIZE (256U) #endif // Set default buffers count. #if !defined(ERPC_DEFAULT_BUFFERS_COUNT) //! @brief Count of buffers allocated by StaticMessageBufferFactory. - #define ERPC_DEFAULT_BUFFERS_COUNT (2) + #define ERPC_DEFAULT_BUFFERS_COUNT (2U) #endif // Disable/enable noexcept. @@ -106,7 +118,7 @@ #define ERPC_MESSAGE_LOGGING (ERPC_MESSAGE_LOGGING_DISABLED) #endif -#if defined(__CC_ARM) /* Keil MDK */ +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) /* Keil MDK */ #define THROW_BADALLOC throw(std::bad_alloc) #define THROW throw() #else @@ -130,6 +142,16 @@ #endif #endif +// Disabling pre and post callback function related code. +#if !defined(ERPC_PRE_POST_ACTION) + #define ERPC_PRE_POST_ACTION (ERPC_PRE_POST_ACTION_DISABLED) +#endif + +// Disabling pre and post default callback function code. +#if !defined(ERPC_PRE_POST_ACTION_DEFAULT) + #define ERPC_PRE_POST_ACTION_DEFAULT (ERPC_PRE_POST_ACTION_DEFAULT_DISABLED) +#endif + /* clang-format on */ #endif // _ERPC_DETECT_H_ //////////////////////////////////////////////////////////////////////////////// diff --git a/erpc_c/port/erpc_port.h b/erpc_c/port/erpc_port.h index 34ad36fd1..6b5c7927c 100644 --- a/erpc_c/port/erpc_port.h +++ b/erpc_c/port/erpc_port.h @@ -45,7 +45,7 @@ void *erpc_malloc(size_t size); void erpc_free(void *ptr); #ifdef __cplusplus -}; +} #endif /*! @} */ diff --git a/erpc_c/port/erpc_port_freertos.cpp b/erpc_c/port/erpc_port_freertos.cpp index 984396a05..884c0f376 100644 --- a/erpc_c/port/erpc_port_freertos.cpp +++ b/erpc_c/port/erpc_port_freertos.cpp @@ -8,6 +8,7 @@ */ #include "erpc_port.h" + #include extern "C" { @@ -40,7 +41,7 @@ void *operator new[](std::size_t count, const std::nothrow_t &tag) THROW return p; } -void operator delete(void *ptr) THROW +void operator delete(void *ptr)THROW { erpc_free(ptr); } @@ -63,7 +64,7 @@ void erpc_free(void *ptr) /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) -extern "C" void __cxa_pure_virtual() +extern "C" void __cxa_pure_virtual(void) { while (1) ; diff --git a/erpc_c/port/erpc_port_mbed.cpp b/erpc_c/port/erpc_port_mbed.cpp new file mode 100644 index 000000000..b8c66dfb9 --- /dev/null +++ b/erpc_c/port/erpc_port_mbed.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020, Embedded Planet, Inc + * All rights reserved. + * + * For supporting transports and examples see: + * https://github.com/EmbeddedPlanet/mbed-rpc + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_port.h" + +#if ERPC_THREADS_IS(MBED) + +#include + +using namespace std; + +void *erpc_malloc(size_t size) +{ + void *p = malloc(size); + return p; +} + +void erpc_free(void *ptr) +{ + free(ptr); +} +#endif diff --git a/erpc_c/port/erpc_port_memmanager.cpp b/erpc_c/port/erpc_port_memmanager.cpp index 353b8f9df..7c60ba43f 100644 --- a/erpc_c/port/erpc_port_memmanager.cpp +++ b/erpc_c/port/erpc_port_memmanager.cpp @@ -7,6 +7,7 @@ */ #include "erpc_port.h" + #include extern "C" { @@ -42,7 +43,7 @@ void *operator new[](std::size_t count, const std::nothrow_t &tag) THROW NOEXCEP return p; } -void operator delete(void *ptr) THROW +void operator delete(void *ptr)THROW { erpc_free(ptr); } @@ -65,7 +66,7 @@ void erpc_free(void *ptr) /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) -extern "C" void __cxa_pure_virtual() +extern "C" void __cxa_pure_virtual(void) { while (1) ; diff --git a/erpc_c/port/erpc_port_mqx.cpp b/erpc_c/port/erpc_port_mqx.cpp index eecc40a8e..709bd9d8b 100644 --- a/erpc_c/port/erpc_port_mqx.cpp +++ b/erpc_c/port/erpc_port_mqx.cpp @@ -8,6 +8,7 @@ */ #include "erpc_port.h" + #include extern "C" { @@ -40,7 +41,7 @@ void *operator new[](std::size_t count, const std::nothrow_t &tag) THROW return p; } -void operator delete(void *ptr) THROW +void operator delete(void *ptr)THROW { erpc_free(ptr); } @@ -63,7 +64,7 @@ void erpc_free(void *ptr) /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) -extern "C" void __cxa_pure_virtual() +extern "C" void __cxa_pure_virtual(void) { while (1) ; diff --git a/erpc_c/port/erpc_port_stdlib.cpp b/erpc_c/port/erpc_port_stdlib.cpp index 8155d3417..6d5a3e4b0 100644 --- a/erpc_c/port/erpc_port_stdlib.cpp +++ b/erpc_c/port/erpc_port_stdlib.cpp @@ -8,6 +8,7 @@ */ #include "erpc_port.h" + #include #include @@ -21,6 +22,7 @@ void *operator new(size_t count) THROW_BADALLOC void *operator new(size_t count, const nothrow_t &tag) THROW NOEXCEPT { + (void)tag; void *p = erpc_malloc(count); return p; } @@ -33,12 +35,19 @@ void *operator new[](size_t count) THROW_BADALLOC void *operator new[](size_t count, const nothrow_t &tag) THROW NOEXCEPT { + (void)tag; void *p = erpc_malloc(count); return p; } -void operator delete(void *ptr) THROW NOEXCEPT +void operator delete(void *ptr)THROW NOEXCEPT +{ + erpc_free(ptr); +} + +void operator delete(void *ptr, std::size_t count)THROW NOEXCEPT { + (void)count; erpc_free(ptr); } @@ -47,6 +56,12 @@ void operator delete[](void *ptr) THROW NOEXCEPT erpc_free(ptr); } +void operator delete[](void *ptr, std::size_t count) THROW NOEXCEPT +{ + (void)count; + erpc_free(ptr); +} + void *erpc_malloc(size_t size) { void *p = malloc(size); @@ -60,7 +75,7 @@ void erpc_free(void *ptr) /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) -extern "C" void __cxa_pure_virtual() +extern "C" void __cxa_pure_virtual(void) { while (1) ; diff --git a/erpc_c/port/erpc_port_zephyr.cpp b/erpc_c/port/erpc_port_zephyr.cpp index 6990bb976..5e894a696 100644 --- a/erpc_c/port/erpc_port_zephyr.cpp +++ b/erpc_c/port/erpc_port_zephyr.cpp @@ -7,6 +7,7 @@ */ #include "erpc_port.h" + #include extern "C" { @@ -39,7 +40,7 @@ void *operator new[](std::size_t count, const std::nothrow_t &tag) THROW return p; } -void operator delete(void *ptr) THROW +void operator delete(void *ptr)THROW { erpc_free(ptr); } @@ -62,7 +63,7 @@ void erpc_free(void *ptr) /* Provide function for pure virtual call to avoid huge demangling code being linked in ARM GCC */ #if ((defined(__GNUC__)) && (defined(__arm__))) -extern "C" void __cxa_pure_virtual() +extern "C" void __cxa_pure_virtual(void) { while (1) ; diff --git a/erpc_c/port/erpc_serial.cpp b/erpc_c/port/erpc_serial.cpp index e0cbe77ad..14d05bf2f 100644 --- a/erpc_c/port/erpc_serial.cpp +++ b/erpc_c/port/erpc_serial.cpp @@ -38,40 +38,55 @@ #include "erpc_serial.h" +#ifdef _WIN32 +static OVERLAPPED s_writeOverlap; +static OVERLAPPED s_readOverlap; +#define TX_BUF_BYTES 1024U +#define RX_BUF_BYTES 1024U +#endif + int serial_setup(int fd, speed_t speed) { -#ifdef WIN32 +#ifdef _WIN32 COMMTIMEOUTS timeouts; DCB dcb = { 0 }; HANDLE hCom = (HANDLE)fd; - dcb.DCBlength = sizeof(dcb); + DWORD errors; + COMSTAT status; + + ClearCommError(hCom, &errors, &status); + PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); - dcb.BaudRate = speed; + memset(&timeouts, 0, sizeof(timeouts)); + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.WriteTotalTimeoutConstant = 500; + + if (!SetCommTimeouts(hCom, &timeouts)) + { + return -1; + } + + dcb.DCBlength = sizeof(dcb); + dcb.BaudRate = 115200; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; + dcb.fBinary = TRUE; + dcb.fDtrControl = DTR_CONTROL_ENABLE; + dcb.fRtsControl = RTS_CONTROL_ENABLE; if (!SetCommState(hCom, &dcb)) { return -1; } - // These timeouts mean: - // read: return immediately with whatever data is available, if any - // write: timeouts not used - // reference: http://www.robbayer.com/files/serial-win.pdf - timeouts.ReadIntervalTimeout = MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier = 0; - timeouts.ReadTotalTimeoutConstant = 0; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; + s_writeOverlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + s_readOverlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!SetCommTimeouts(hCom, &timeouts)) - { - return -1; - } + SetCommMask(hCom, EV_RXCHAR); #else + (void)speed; struct termios tty; memset(&tty, 0x00, sizeof(tty)); @@ -82,7 +97,7 @@ int serial_setup(int fd, speed_t speed) tty.c_oflag = 0; tty.c_lflag = 0; -#ifdef LINUX +#ifdef __linux__ switch (speed) { case 9600: @@ -118,56 +133,18 @@ int serial_setup(int fd, speed_t speed) return -1; } -#ifdef MACOSX +#ifdef __APPLE__ return ioctl(fd, IOSSIOSPEED, &speed); -#endif //#ifdef MACOSX +#endif //#ifdef __APPLE__ -#endif // WIN32 +#endif // _WIN32 return 0; } int serial_set_read_timeout(int fd, uint8_t vtime, uint8_t vmin) { -#ifdef WIN32 - COMMTIMEOUTS timeouts; - HANDLE hCom = (HANDLE)fd; - - // These timeouts mean: - // read: return if: - // 1. Inter-character timeout exceeds ReadIntervalTimeout - // 2. Total timeout exceeds (ReadIntervalTimeout*ReadTotalTimeoutMultiplier*number of characters) + - // ReadTotalTimeoutConstant - // In practice it seems that no matter how many characters you ask for, if no characters appear on the interface - // then - // only ReadTotalTimeoutConstant applies. - // write: timeouts not used - // reference: http://www.robbayer.com/files/serial-win.pdf - if (timeoutMs != 0) - { - timeouts.ReadIntervalTimeout = 1000; - timeouts.ReadTotalTimeoutMultiplier = 10; - timeouts.ReadTotalTimeoutConstant = timeoutMs; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; - } - else - { - // Need a separate case for timeoutMs == 0 - // setting all these values to 0 results in no timeout - // so set them to a minimum value, this will return immediately - // if there is no data available - timeouts.ReadIntervalTimeout = 1; - timeouts.ReadTotalTimeoutMultiplier = 1; - timeouts.ReadTotalTimeoutConstant = 1; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; - } - - if (!SetCommTimeouts(hCom, &timeouts)) - { - return -1; - } - +#ifdef _WIN32 + // TODO #else struct termios tty; /*memset(&tty, 0x00, sizeof(tty)); @@ -190,24 +167,37 @@ int serial_set_read_timeout(int fd, uint8_t vtime, uint8_t vmin) return -1; } -#endif // WIN32 +#endif // _WIN32 return 0; } int serial_write(int fd, char *buf, int size) { -#ifdef WIN32 +#ifdef _WIN32 HANDLE hCom = (HANDLE)fd; + DWORD errors; + COMSTAT status; unsigned long bwritten = 0; - if (!WriteFile(hCom, buf, size, &bwritten, NULL)) - { - return 0; - } - else + ClearCommError(hCom, &errors, &status); + if (!WriteFile(hCom, buf, size, &bwritten, &s_writeOverlap)) { - return bwritten; + if (GetLastError() == ERROR_IO_PENDING) + { + if (!GetOverlappedResult(hCom, &s_writeOverlap, &bwritten, TRUE)) + { + return 0; + } + } + else + { + return 0; + ; + } } + ClearCommError(hCom, &errors, &status); + + return bwritten; #else return write(fd, buf, size); #endif @@ -215,18 +205,61 @@ int serial_write(int fd, char *buf, int size) int serial_read(int fd, char *buf, int size) { -#ifdef WIN32 +#ifdef _WIN32 HANDLE hCom = (HANDLE)fd; unsigned long bread = 0; + char temp[RX_BUF_BYTES] = { 0 }; + DWORD errors; + DWORD bytesToRead = 0; + DWORD bytesRead = 0; + DWORD ret = 0; - if (!ReadFile(hCom, buf, size, &bread, NULL)) - { - return 0; - } - else + while (bytesToRead != size) { - return bread; + do + { + + ClearCommError(hCom, &errors, NULL); + + if (!ReadFile(hCom, temp, RX_BUF_BYTES - bytesToRead, &bytesRead, &s_readOverlap)) + { + if (GetLastError() == ERROR_IO_PENDING) + { + ret = WaitForSingleObject(s_readOverlap.hEvent, INFINITE); + + if (WAIT_OBJECT_0 == ret) + { + if (!GetOverlappedResult(hCom, &s_readOverlap, &bytesRead, FALSE)) + { + bytesRead = 0; + bytesToRead = 0; + } + } + else + { + bytesRead = 0; + bytesToRead = 0; + } + } + else + { + bytesRead = 0; + bytesToRead = 0; + } + } + + bytesToRead += bytesRead; + + if (bytesRead) + { + memcpy(buf, temp, bytesRead); + buf += bytesRead; + } + + } while ((bytesRead > 0) && (RX_BUF_BYTES >= bytesToRead)); } + + return bytesToRead; #else int len = 0; int ret = 0; @@ -262,19 +295,21 @@ int serial_read(int fd, char *buf, int size) int serial_open(const char *port) { int fd; -#ifdef WIN32 +#ifdef _WIN32 static char full_path[32] = { 0 }; HANDLE hCom = NULL; - if (port[0] != '\\') + if (memcmp(port, "\\\\.\\", 4)) { _snprintf(full_path, sizeof(full_path) - 1, "\\\\.\\%s", port); - port = full_path; + } + else + { + memcpy(full_path, port, strnlen_s(port, sizeof(full_path) - 1)); } -#pragma warning(suppress : 6053) - hCom = CreateFileA(port, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + hCom = CreateFileA(full_path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (!hCom || hCom == INVALID_HANDLE_VALUE) { @@ -297,7 +332,7 @@ int serial_open(const char *port) int serial_close(int fd) { -#ifdef WIN32 +#ifdef _WIN32 HANDLE hCom = (HANDLE)fd; CloseHandle(hCom); diff --git a/erpc_c/port/erpc_serial.h b/erpc_c/port/erpc_serial.h index 2b5a996a2..ee9d40efe 100644 --- a/erpc_c/port/erpc_serial.h +++ b/erpc_c/port/erpc_serial.h @@ -23,7 +23,7 @@ #ifndef MYSERIAL_H_ #define MYSERIAL_H_ -#ifdef MACOSX +#ifdef __APPLE__ #include #include @@ -34,7 +34,7 @@ #include -#ifdef WIN32 +#ifdef _WIN32 #include #include diff --git a/erpc_c/port/erpc_setup_extensions.h b/erpc_c/port/erpc_setup_extensions.h new file mode 100644 index 000000000..d49dbe8b3 --- /dev/null +++ b/erpc_c/port/erpc_setup_extensions.h @@ -0,0 +1,94 @@ +/* + * Copyright 2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _EMBEDDED_RPC__SETUP_EXTENSIONS_H_ +#define _EMBEDDED_RPC__SETUP_EXTENSIONS_H_ + +#include "erpc_config_internal.h" + +#include + +#if !ERPC_THREADS_IS(NONE) + +#if ERPC_THREADS_IS(FREERTOS) +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#endif + +#endif // ERPC_THREADS + +/*! + * @addtogroup port_setup_extensions + * @{ + * @file + */ + +//////////////////////////////////////////////////////////////////////////////// +// Declarations +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus + +namespace erpc { +/*! + * @brief This function is used for default pre erpc call action. + */ +void erpc_pre_cb_default(void); + +/*! + * @brief This function is used for default post erpc call action. + */ +void erpc_post_cb_default(void); +} // namespace erpc + +extern "C" { +#endif + +#if ERPC_THREADS_IS(FREERTOS) +typedef TimerCallbackFunction_t erpc_call_timer_cb_default_t; +#else +typedef void *erpc_call_timer_cb_default_t; +#endif + +/*! + * @brief This function is used for initializing variables for task freeze detection. + * + * @param[in] erpc_call_timer_cb Callback function called when eRPC call freeze. + * When NULL default callback will be used. + * @param[in] waitTimeMs Platform specific time to throw error cb in case of eRPC call freeze in [ms]. + */ +void erpc_init_call_progress_detection_default(erpc_call_timer_cb_default_t erpc_call_timer_cb, uint32_t waitTimeMs); + +/*! + * @brief This function is used for deinitialization variables for task freeze detection. + */ +void erpc_deinit_call_progress_detection_default(void); + +/*! + * @brief This function returns default eRPC call progress status. + * + * @return True if eRPC call is in progress, otherwise False. + */ +bool erpc_is_call_in_progress_default(void); + +/*! + * @brief This function resets eRPC state. + * + * Can be used when user reinitialize communication between client and server. + */ +void erpc_reset_in_progress_state_default(void); + +#ifdef __cplusplus +} +#endif + +/*! @} */ + +#endif // _EMBEDDED_RPC__SETUP_EXTENSIONS_H_ diff --git a/erpc_c/port/erpc_sysgpio.h b/erpc_c/port/erpc_sysgpio.h new file mode 100644 index 000000000..3012e98ce --- /dev/null +++ b/erpc_c/port/erpc_sysgpio.h @@ -0,0 +1,31 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _ERPC_SYSGPIO_H_ +#define _ERPC_SYSGPIO_H_ + +#if __cplusplus +extern "C" { +#endif + +#define ERPC_SYSGPIO_STATUS_SUCCESS 0 + +int gpio_export(int gpio); +int gpio_direction(int gpio, int direction); +int gpio_set_edge(int gpio, char *edge); +int gpio_read(int gpio); + +int gpio_open(int gpio); +int gpio_close(int fd); +int gpio_poll(int fd, int timeout); + +#if __cplusplus +} +#endif + +#endif /* _ERPC_SYSGPIO_H_ */ diff --git a/erpc_c/port/erpc_threading.h b/erpc_c/port/erpc_threading.h index c932f0f0a..dd2130177 100644 --- a/erpc_c/port/erpc_threading.h +++ b/erpc_c/port/erpc_threading.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -11,10 +11,11 @@ #define __embedded_rpc__thread__ #include "erpc_config_internal.h" + #include // Exclude the rest of the file if threading is disabled. -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) #if ERPC_THREADS_IS(PTHREADS) #include @@ -24,7 +25,16 @@ #include "task.h" #elif ERPC_THREADS_IS(ZEPHYR) #include "kernel.h" -#endif // ERPC_THREADS_IS +#elif ERPC_THREADS_IS(MBED) +#if MBED_CONF_RTOS_PRESENT +#include "rtos.h" +#else +#warning mbed-rpc: Threading is enabled but Mbed RTOS is not present! +#endif +#elif ERPC_THREADS_IS(WIN32) +#include "windows.h" + +#endif // ERPC_THREADS /*! * @addtogroup port_threads @@ -136,6 +146,10 @@ class Thread return reinterpret_cast(m_task); #elif ERPC_THREADS_IS(ZEPHYR) return reinterpret_cast(m_thread); +#elif ERPC_THREADS_IS(MBED) + return reinterpret_cast(m_thread->get_id()); +#elif ERPC_THREADS_IS(WIN32) + return reinterpret_cast(m_thread); #endif } @@ -152,6 +166,10 @@ class Thread return reinterpret_cast(xTaskGetCurrentTaskHandle()); #elif ERPC_THREADS_IS(ZEPHYR) return reinterpret_cast(k_current_get()); +#elif ERPC_THREADS_IS(MBED) + return reinterpret_cast(rtos::ThisThread::get_id()); +#elif ERPC_THREADS_IS(WIN32) + return reinterpret_cast(GetCurrentThread()); #endif } @@ -203,6 +221,17 @@ class Thread #elif ERPC_THREADS_IS(ZEPHYR) struct k_thread m_thread; /*!< Current thread. */ k_thread_stack_t *m_stack; /*!< Pointer to stack. */ +#elif ERPC_THREADS_IS(MBED) + rtos::Thread *m_thread; /*!< Underlying Thread instance */ + Thread *m_next; /*!< Pointer to next Thread. */ + static Thread *s_first; /*!< Pointer to first Thread. */ +#elif ERPC_THREADS_IS(WIN32) + HANDLE m_thread; + unsigned int m_thrdaddr; + Thread *m_next; /*!< Pointer to next Thread. */ + static Thread *s_first; /*!< Pointer to first Thread. */ + static CRITICAL_SECTION m_critical_section; + static BOOL m_critical_section_inited; #endif #if ERPC_THREADS_IS(PTHREADS) @@ -231,6 +260,25 @@ class Thread * @param[in] arg3 */ static void *threadEntryPointStub(void *arg1, void *arg2, void *arg3); + +#elif ERPC_THREADS_IS(MBED) + + /*! + * @brief This function execute threadEntryPoint function. + * + * @param[in] arg Thread to execute. + */ + static void threadEntryPointStub(void *arg); + +#elif ERPC_THREADS_IS(WIN32) + + /*! + * @brief This function execute threadEntryPoint function. + * + * @param[in] arg Thread to execute. + */ + static unsigned WINAPI threadEntryPointStub(void *arg); + #endif private: @@ -334,6 +382,10 @@ class Mutex SemaphoreHandle_t m_mutex; /*!< Mutex.*/ #elif ERPC_THREADS_IS(ZEPHYR) struct k_mutex m_mutex; /*!< Mutex.*/ +#elif ERPC_THREADS_IS(MBED) + rtos::Mutex *m_mutex; /*!< Mutex. */ +#elif ERPC_THREADS_IS(WIN32) + HANDLE m_mutex; #endif private: @@ -415,6 +467,13 @@ class Semaphore SemaphoreHandle_t m_sem; /*!< Semaphore. */ #elif ERPC_THREADS_IS(ZEPHYR) struct k_sem m_sem; /*!< Semaphore. */ +#elif ERPC_THREADS_IS(MBED) + rtos::Semaphore *m_sem; /*!< Semaphore. */ + int m_count; /*!< Semaphore count number. */ +#elif ERPC_THREADS_IS(WIN32) + Mutex m_mutex; /*!< Mutext. */ + int m_count; + HANDLE m_sem; #endif private: diff --git a/erpc_c/port/erpc_threading_freertos.cpp b/erpc_c/port/erpc_threading_freertos.cpp index ac2a86179..2401974bd 100644 --- a/erpc_c/port/erpc_threading_freertos.cpp +++ b/erpc_c/port/erpc_threading_freertos.cpp @@ -8,6 +8,7 @@ */ #include "erpc_threading.h" + #include #include @@ -66,16 +67,17 @@ void Thread::start(void *arg) // which will scan the linked list. taskENTER_CRITICAL(); - (void)xTaskCreate(threadEntryPointStub, (m_name ? m_name : "task"), - ((m_stackSize + sizeof(uint32_t) - 1) / sizeof(uint32_t)), // Round up number of words. - this, m_priority, &m_task); - - // Link in this thread to the list. - if (s_first) + if (pdPASS == xTaskCreate(threadEntryPointStub, (m_name ? m_name : "task"), + ((m_stackSize + sizeof(uint32_t) - 1) / sizeof(uint32_t)), // Round up number of words. + this, m_priority, &m_task)) { - m_next = s_first; + // Link in this thread to the list. + if (NULL != s_first) + { + m_next = s_first; + } + s_first = this; } - s_first = this; taskEXIT_CRITICAL(); } @@ -85,7 +87,7 @@ bool Thread::operator==(Thread &o) return m_task == o.m_task; } -Thread *Thread::getCurrentThread() +Thread *Thread::getCurrentThread(void) { TaskHandle_t thisTask = xTaskGetCurrentTaskHandle(); @@ -174,7 +176,7 @@ void Thread::threadEntryPointStub(void *arg) Mutex::Mutex(void) : m_mutex(0) { - m_mutex = xSemaphoreCreateMutex(); + m_mutex = xSemaphoreCreateRecursiveMutex(); } Mutex::~Mutex(void) @@ -234,7 +236,10 @@ bool Semaphore::get(uint32_t timeout) timeout = portMAX_DELAY - 1; } #endif - (void)xSemaphoreTake(m_sem, timeout / 1000 / portTICK_PERIOD_MS); + if (pdTRUE != xSemaphoreTake(m_sem, timeout / 1000 / portTICK_PERIOD_MS)) + { + return false; + } return true; } diff --git a/erpc_c/port/erpc_threading_mbed.cpp b/erpc_c/port/erpc_threading_mbed.cpp new file mode 100644 index 000000000..aef9df8da --- /dev/null +++ b/erpc_c/port/erpc_threading_mbed.cpp @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2019, Embedded Planet, Inc + * All rights reserved. + * + * For supporting transports and examples see: + * https://github.com/EmbeddedPlanet/mbed-rpc + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_threading.h" + +#include "platform/CriticalSectionLock.h" +#include "platform/mbed_assert.h" + +#if ERPC_THREADS_IS(MBED) + +namespace erpc { + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +Thread *Thread::s_first = NULL; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +Thread::Thread(const char *name) +: m_name(name) +, m_entry(0) +, m_arg(0) +, m_stackSize(0) +, m_priority(0) +, m_thread(NULL) +, m_next(NULL) +{ +} + +Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name) +: m_name(name) +, m_entry(entry) +, m_arg(0) +, m_stackSize(stackSize) +, m_priority(priority) +, m_thread(NULL) +, m_next(NULL) +{ +} + +Thread::~Thread(void) +{ + if (m_thread != NULL) + { + delete m_thread; + m_thread = NULL; + } +} + +void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize) +{ + m_entry = entry; + m_stackSize = stackSize; + m_priority = priority; + m_thread = + new rtos::Thread(osPriorityNormal, // Ignore priority because erpc does not map their priority to anything + ((m_stackSize + sizeof(uint32_t) - 1) / sizeof(uint32_t)), // Round up number of words + NULL, m_name); +} + +void Thread::start(void *arg) +{ + m_arg = arg; + + // Enter a critical section to disable preemptive scheduling until we add the newly + // created thread to the linked list. This prevents a race condition if the new thread is + // higher priority than the current thread, and the new thread calls getCurrenThread(), + // which will scan the linked list. + mbed::CriticalSectionLock::enable(); + + if (s_first) + { + m_next = s_first; + } + s_first = this; + + // Start the thread + m_thread->start(mbed::callback(&erpc::Thread::threadEntryPointStub, this)); + + mbed::CriticalSectionLock::disable(); +} + +bool Thread::operator==(Thread &o) +{ + return (this->getThreadId() == o.getThreadId()); +} + +Thread *Thread::getCurrentThread() +{ + osThreadId_t currentThreadId = rtos::ThisThread::get_id(); + + // Walk the threads list to find the Thread object for the current task. + mbed::CriticalSectionLock::enable(); + Thread *it = s_first; + while (it) + { + if (it->getThreadId() == currentThreadId) + { + break; + } + it = it->m_next; + } + mbed::CriticalSectionLock::disable(); + return it; +} + +void Thread::sleep(uint32_t usecs) +{ + rtos::ThisThread::sleep_for(usecs / 1000); +} + +void Thread::threadEntryPoint(void) +{ + if (m_entry) + { + m_entry(m_arg); + } +} + +void Thread::threadEntryPointStub(void *arg) +{ + Thread *_this = reinterpret_cast(arg); + MBED_ASSERT(_this); // Reinterpreting 'void *arg' to 'Thread *' failed. + _this->threadEntryPoint(); + + // Remove this thread from the linked list. + mbed::CriticalSectionLock::enable(); + Thread *it = s_first; + Thread *prev = NULL; + while (it) + { + if (it == _this) + { + if (it == s_first) + { + s_first = _this->m_next; + } + else if (prev) + { + prev->m_next = _this->m_next; + } + _this->m_next = NULL; + + break; + } + prev = it; + it = it->m_next; + } + mbed::CriticalSectionLock::disable(); +} + +Mutex::Mutex(void) +{ + // Having a member variable mutex + // was causing memory alignment issues... + m_mutex = new rtos::Mutex(); +} + +Mutex::~Mutex(void) +{ + if (m_mutex != NULL) + { + delete m_mutex; + m_mutex = NULL; + } +} + +bool Mutex::tryLock(void) +{ + // Pass a zero timeout to poll the mutex. + return m_mutex->trylock(); +} + +bool Mutex::lock(void) +{ + return m_mutex->lock(); +} + +bool Mutex::unlock(void) +{ + return m_mutex->unlock(); +} + +Semaphore::Semaphore(int count) +: m_count(count) +{ + m_sem = new rtos::Semaphore(m_count); +} + +Semaphore::~Semaphore(void) +{ + if (m_sem != NULL) + { + delete m_sem; + m_sem = NULL; + } +} + +void Semaphore::put(void) +{ + m_sem->release(); +} + +bool Semaphore::get(uint32_t timeout) +{ + m_count = m_sem->wait(timeout); + if (m_count < 0) + { + return true; + } + else + { + return false; + } +} + +int Semaphore::getCount(void) const +{ + return m_count; +} + +} // namespace erpc + +#endif diff --git a/erpc_c/port/erpc_threading_pthreads.cpp b/erpc_c/port/erpc_threading_pthreads.cpp index 3594f14b3..d3833a09b 100644 --- a/erpc_c/port/erpc_threading_pthreads.cpp +++ b/erpc_c/port/erpc_threading_pthreads.cpp @@ -8,6 +8,7 @@ */ #include "erpc_threading.h" + #include #include #include @@ -83,8 +84,10 @@ Thread *Thread::getCurrentThread(void) void Thread::sleep(uint32_t usecs) { // Sleep for the requested number of microseconds. - struct timespec rq = { .tv_sec = usecs / 1000000, .tv_nsec = (usecs % 1000000) * 1000 }; - struct timespec actual = { 0 }; + struct timespec rq; + rq.tv_sec = usecs / 1000000; + rq.tv_nsec = (usecs % 1000000) * 1000; + struct timespec actual = { 0, 0 }; // Keep sleeping until the requested time elapses even if we get interrupted by a signal. while (nanosleep(&rq, &actual) == EINTR) @@ -190,7 +193,9 @@ bool Semaphore::get(uint32_t timeout) // Create an absolute timeout time. struct timeval tv; gettimeofday(&tv, NULL); - struct timespec wait = { .tv_sec = tv.tv_sec + (timeout / 1000000), .tv_nsec = (timeout % 1000000) * 1000 }; + struct timespec wait; + wait.tv_sec = tv.tv_sec + (timeout / 1000000); + wait.tv_nsec = (timeout % 1000000) * 1000; err = pthread_cond_timedwait(&m_cond, m_mutex.getPtr(), &wait); if (err) { diff --git a/erpc_c/port/erpc_threading_zephyr.cpp b/erpc_c/port/erpc_threading_zephyr.cpp deleted file mode 100644 index 312ff892e..000000000 --- a/erpc_c/port/erpc_threading_zephyr.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2017 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "erpc_threading.h" -#include - -#if ERPC_THREADS_IS(ZEPHYR) - -using namespace erpc; - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -Thread::Thread(const char *name) -: m_name(name) -, m_entry(0) -, m_arg(0) -, m_stackSize(0) -, m_priority(0) -, m_thread(0) -, m_stack(0) -{ -} - -Thread::Thread(thread_entry_t entry, uint32_t priority, uint32_t stackSize, const char *name) -: m_name(name) -, m_entry(entry) -, m_arg(0) -, m_stackSize(stackSize) -, m_priority(priority) -, m_thread(0) -, m_stack(0) -{ -} - -Thread::~Thread(void) {} - -void Thread::init(thread_entry_t entry, uint32_t priority, uint32_t stackSize) -{ - m_entry = entry; - m_stackSize = stackSize; - m_priority = priority; -} - -void Thread::start(void *arg) -{ - m_arg = arg; - - assert(m_stack && "Set stack address"); - k_thread_create(&m_thread, m_stack, m_stackSize, threadEntryPointStub, this, NULL, NULL, m_priority, 0, K_NO_WAIT); -} - -bool Thread::operator==(Thread &o) -{ - return m_thread == o.m_thread; -} - -Thread *Thread::getCurrentThread(void) -{ - return reinterpret_cast(k_thread_custom_data_get()); -} - -void Thread::sleep(uint32_t usecs) -{ - k_sleep(usecs / 1000); -} - -void Thread::threadEntryPoint(void) -{ - if (m_entry) - { - m_entry(m_arg); - } -} - -void *Thread::threadEntryPointStub(void *arg1, void *arg2, void *arg3) -{ - Thread *_this = reinterpret_cast(arg1); - assert(_this && "Reinterpreting 'void *arg1' to 'Thread *' failed."); - k_thread_custom_data_set(arg1); - _this->threadEntryPoint(); - - // Handle a task returning from its function. - k_thread_abort(k_current_get()); -} - -Mutex::Mutex(void) -: m_mutex(0) -{ - k_mutex_init(&m_mutex); -} - -Mutex::~Mutex(void) {} - -bool Mutex::tryLock(void) -{ - return (k_mutex_lock(&m_mutex, K_NO_WAIT) == 0); -} - -bool Mutex::lock(void) -{ - return (k_mutex_lock(&m_mutex, K_FOREVER) == 0); -} - -bool Mutex::unlock(void) -{ - k_mutex_unlock(&m_mutex); - return true; -} - -Semaphore::Semaphore(int count) -: m_sem(0) -{ - // Set max count to highest signed int. - k_sem_init(&m_sem, count, 0x7fffffff); -} - -Semaphore::~Semaphore(void) {} - -void Semaphore::put(void) -{ - k_sem_give(&m_sem); -} - -bool Semaphore::get(uint32_t timeout) -{ - return (k_sem_take(&m_sem, timeout / 1000) == 0); -} - -int Semaphore::getCount(void) const -{ - return k_sem_count_get(m_sem)); -} -#endif /* ERPC_THREADS_IS(FREERTOS) */ - -//////////////////////////////////////////////////////////////////////////////// -// EOF -//////////////////////////////////////////////////////////////////////////////// diff --git a/erpc_c/port/port.dox b/erpc_c/port/port.dox index 2966f6089..9ee43cca0 100644 --- a/erpc_c/port/port.dox +++ b/erpc_c/port/port.dox @@ -20,3 +20,15 @@ @brief Serial port @ingroup port */ + +/*! +@defgroup port_spidev SPIdev +@brief SPIdev port +@ingroup port +*/ + +/*! +@defgroup port_sysgpio SysGPIO +@brief SysGPIO port +@ingroup port +*/ \ No newline at end of file diff --git a/erpc_c/setup/erpc_arbitrated_client_setup.cpp b/erpc_c/setup/erpc_arbitrated_client_setup.cpp index b03e75ba2..e9f0da010 100644 --- a/erpc_c/setup/erpc_arbitrated_client_setup.cpp +++ b/erpc_c/setup/erpc_arbitrated_client_setup.cpp @@ -1,117 +1,140 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "erpc_arbitrated_client_setup.h" -#include "erpc_arbitrated_client_manager.h" -#include "erpc_basic_codec.h" -#include "erpc_manually_constructed.h" -#include "erpc_message_buffer.h" -#include "erpc_transport_arbitrator.h" -#if ERPC_NESTED_CALLS -#include "erpc_threading.h" -#endif -#include - -using namespace erpc; - -//////////////////////////////////////////////////////////////////////////////// -// Variables -//////////////////////////////////////////////////////////////////////////////// - -// global client variables -static ManuallyConstructed s_client; -ClientManager *g_client = NULL; - -static ManuallyConstructed s_codecFactory; -static ManuallyConstructed s_arbitrator; -static ManuallyConstructed s_codec; -static ManuallyConstructed s_crc16; - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -erpc_transport_t erpc_arbitrated_client_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory) -{ - assert(transport); - - // Init factories. - s_codecFactory.construct(); - - // Create codec used by the arbitrator. - s_codec.construct(); - - // Init the arbitrator using the passed in transport. - s_arbitrator.construct(); - Transport *castedTransport = reinterpret_cast(transport); - s_crc16.construct(); - castedTransport->setCrc16(s_crc16.get()); - s_arbitrator->setSharedTransport(castedTransport); - s_arbitrator->setCodec(s_codec); - - // Init the client manager. - s_client.construct(); - s_client->setArbitrator(s_arbitrator); - s_client->setCodecFactory(s_codecFactory); - s_client->setMessageBufferFactory(reinterpret_cast(message_buffer_factory)); - g_client = s_client; - - return reinterpret_cast(s_arbitrator.get()); -} - -void erpc_arbitrated_client_set_error_handler(client_error_handler_t error_handler) -{ - if (g_client != NULL) - { - g_client->setErrorHandler(error_handler); - } -} - -void erpc_arbitrated_client_set_crc(uint32_t crcStart) -{ - s_crc16->setCrcStart(crcStart); -} - -#if ERPC_NESTED_CALLS -void erpc_arbitrated_client_set_server(erpc_server_t server) -{ - if (g_client != NULL) - { - g_client->setServer(reinterpret_cast(server)); - } -} - -void erpc_arbitrated_client_set_server_thread_id(void *serverThreadId) -{ - if (g_client != NULL) - { - g_client->setServerThreadId(reinterpret_cast(serverThreadId)); - } -} -#endif - -#if ERPC_MESSAGE_LOGGING -bool erpc_arbitrated_client_add_message_logger(erpc_transport_t transport) -{ - if (g_client != NULL) - { - return g_client->addMessageLogger(reinterpret_cast(transport)); - } - return false; -} -#endif - -void erpc_arbitrated_client_deinit(void) -{ - s_client.destroy(); - s_codecFactory.destroy(); - s_codec.destroy(); - s_arbitrator.destroy(); - g_client = NULL; -} +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_arbitrated_client_setup.h" + +#include "erpc_arbitrated_client_manager.h" +#include "erpc_basic_codec.h" +#include "erpc_manually_constructed.h" +#include "erpc_message_buffer.h" +#include "erpc_transport_arbitrator.h" +#if ERPC_NESTED_CALLS +#include "erpc_threading.h" +#endif +#include + +#if ERPC_THREADS_IS(NONE) +#error "Arbitrator code does not work in no-threading configuration." +#endif + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +// global client variables +static ManuallyConstructed s_client; +extern ClientManager *g_client; +ClientManager *g_client = NULL; + +static ManuallyConstructed s_codecFactory; +static ManuallyConstructed s_arbitrator; +static ManuallyConstructed s_codec; +static ManuallyConstructed s_crc16; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +erpc_transport_t erpc_arbitrated_client_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory) +{ + assert(transport); + + // Init factories. + s_codecFactory.construct(); + + // Create codec used by the arbitrator. + s_codec.construct(); + + // Init the arbitrator using the passed in transport. + s_arbitrator.construct(); + Transport *castedTransport = reinterpret_cast(transport); + s_crc16.construct(); + castedTransport->setCrc16(s_crc16.get()); + s_arbitrator->setSharedTransport(castedTransport); + s_arbitrator->setCodec(s_codec); + + // Init the client manager. + s_client.construct(); + s_client->setArbitrator(s_arbitrator); + s_client->setCodecFactory(s_codecFactory); + s_client->setMessageBufferFactory(reinterpret_cast(message_buffer_factory)); + g_client = s_client; + + return reinterpret_cast(s_arbitrator.get()); +} + +void erpc_arbitrated_client_set_error_handler(client_error_handler_t error_handler) +{ + if (g_client != NULL) + { + g_client->setErrorHandler(error_handler); + } +} + +void erpc_arbitrated_client_set_crc(uint32_t crcStart) +{ + s_crc16->setCrcStart(crcStart); +} + +#if ERPC_NESTED_CALLS +void erpc_arbitrated_client_set_server(erpc_server_t server) +{ + if (g_client != NULL) + { + g_client->setServer(reinterpret_cast(server)); + } +} + +void erpc_arbitrated_client_set_server_thread_id(void *serverThreadId) +{ + if (g_client != NULL) + { + g_client->setServerThreadId(reinterpret_cast(serverThreadId)); + } +} +#endif + +#if ERPC_MESSAGE_LOGGING +bool erpc_arbitrated_client_add_message_logger(erpc_transport_t transport) +{ + if (g_client != NULL) + { + return g_client->addMessageLogger(reinterpret_cast(transport)); + } + return false; +} +#endif + +#if ERPC_PRE_POST_ACTION +void erpc_arbitrated_client_add_pre_cb_action(pre_post_action_cb preCB) +{ + assert(g_client); + + g_client->addPreCB(preCB); +} + +void erpc_arbitrated_client_add_post_cb_action(pre_post_action_cb postCB) +{ + assert(g_client); + + g_client->addPostCB(postCB); +} +#endif + +void erpc_arbitrated_client_deinit(void) +{ + s_client.destroy(); + s_codecFactory.destroy(); + s_codec.destroy(); + s_arbitrator.destroy(); + g_client = NULL; +} diff --git a/erpc_c/setup/erpc_arbitrated_client_setup.h b/erpc_c/setup/erpc_arbitrated_client_setup.h index 333a40e5c..7b3a9f99a 100644 --- a/erpc_c/setup/erpc_arbitrated_client_setup.h +++ b/erpc_c/setup/erpc_arbitrated_client_setup.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -13,6 +14,9 @@ #include "erpc_common.h" #include "erpc_config_internal.h" #include "erpc_mbf_setup.h" +#if ERPC_PRE_POST_ACTION +#include "erpc_pre_post_action.h" +#endif #if ERPC_NESTED_CALLS #include "erpc_server_setup.h" #endif @@ -33,6 +37,7 @@ extern "C" { #endif +#include #include //! @name Arbitrated client setup @@ -106,6 +111,24 @@ void erpc_arbitrated_client_set_server_thread_id(void *serverThreadId); bool erpc_arbitrated_client_add_message_logger(erpc_transport_t transport); #endif +#if ERPC_PRE_POST_ACTION +/*! + * @brief This function set callback function executed at the beginning of eRPC call. + * + * @param[in] preCB Callback used at the beginning of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_arbitrated_client_add_pre_cb_action(pre_post_action_cb preCB); + +/*! + * @brief This function set callback function executed at the end of eRPC call. + * + * @param[in] postCB Callback used at the end of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_arbitrated_client_add_post_cb_action(pre_post_action_cb postCB); +#endif + /*! * @brief This function de-initializes client. * diff --git a/erpc_c/setup/erpc_client_setup.cpp b/erpc_c/setup/erpc_client_setup.cpp index 0b5c6137c..2fb0b9536 100644 --- a/erpc_c/setup/erpc_client_setup.cpp +++ b/erpc_c/setup/erpc_client_setup.cpp @@ -1,104 +1,124 @@ -/* - * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "erpc_client_setup.h" -#include "erpc_basic_codec.h" -#include "erpc_client_manager.h" -#include "erpc_crc16.h" -#include "erpc_manually_constructed.h" -#include "erpc_message_buffer.h" -#include "erpc_transport.h" -#include -#if ERPC_NESTED_CALLS -#include "erpc_threading.h" -#endif - -using namespace erpc; - -//////////////////////////////////////////////////////////////////////////////// -// Variables -//////////////////////////////////////////////////////////////////////////////// - -// global client variables -static ManuallyConstructed s_client; -ClientManager *g_client = NULL; -static ManuallyConstructed s_codecFactory; -static ManuallyConstructed s_crc16; - -//////////////////////////////////////////////////////////////////////////////// -// Code -//////////////////////////////////////////////////////////////////////////////// - -void erpc_client_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory) -{ - assert(transport); - - // Init factories. - s_codecFactory.construct(); - - // Init client manager with the provided transport. - s_client.construct(); - Transport *castedTransport = reinterpret_cast(transport); - s_crc16.construct(); - castedTransport->setCrc16(s_crc16.get()); - s_client->setTransport(castedTransport); - s_client->setCodecFactory(s_codecFactory); - s_client->setMessageBufferFactory(reinterpret_cast(message_buffer_factory)); - g_client = s_client; -} - -void erpc_client_set_error_handler(client_error_handler_t error_handler) -{ - if (g_client != NULL) - { - g_client->setErrorHandler(error_handler); - } -} - -void erpc_client_set_crc(uint32_t crcStart) -{ - s_crc16->setCrcStart(crcStart); -} - -#if ERPC_NESTED_CALLS -void erpc_client_set_server(erpc_server_t server) -{ - if (g_client != NULL) - { - g_client->setServer(reinterpret_cast(server)); - } -} - -void erpc_client_set_server_thread_id(void *serverThreadId) -{ - if (g_client != NULL) - { - g_client->setServerThreadId(reinterpret_cast(serverThreadId)); - } -} -#endif - -#if ERPC_MESSAGE_LOGGING -bool erpc_client_add_message_logger(erpc_transport_t transport) -{ - if (g_client != NULL) - { - return g_client->addMessageLogger(reinterpret_cast(transport)); - } - return false; -} -#endif - -void erpc_client_deinit(void) -{ - s_crc16.destroy(); - s_client.destroy(); - s_codecFactory.destroy(); - g_client = NULL; -} +/* + * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_client_setup.h" + +#include "erpc_basic_codec.h" +#include "erpc_client_manager.h" +#include "erpc_crc16.h" +#include "erpc_manually_constructed.h" +#include "erpc_message_buffer.h" +#include "erpc_transport.h" + +#include +#if ERPC_NESTED_CALLS +#include "erpc_threading.h" +#endif + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +// global client variables +static ManuallyConstructed s_client; +extern ClientManager *g_client; +ClientManager *g_client = NULL; +static ManuallyConstructed s_codecFactory; +static ManuallyConstructed s_crc16; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +void erpc_client_init(erpc_transport_t transport, erpc_mbf_t message_buffer_factory) +{ + assert(transport); + + // Init factories. + s_codecFactory.construct(); + + // Init client manager with the provided transport. + s_client.construct(); + Transport *castedTransport = reinterpret_cast(transport); + s_crc16.construct(); + castedTransport->setCrc16(s_crc16.get()); + s_client->setTransport(castedTransport); + s_client->setCodecFactory(s_codecFactory); + s_client->setMessageBufferFactory(reinterpret_cast(message_buffer_factory)); + g_client = s_client; +} + +void erpc_client_set_error_handler(client_error_handler_t error_handler) +{ + if (g_client != NULL) + { + g_client->setErrorHandler(error_handler); + } +} + +void erpc_client_set_crc(uint32_t crcStart) +{ + s_crc16->setCrcStart(crcStart); +} + +#if ERPC_NESTED_CALLS +void erpc_client_set_server(erpc_server_t server) +{ + if (g_client != NULL) + { + g_client->setServer(reinterpret_cast(server)); + } +} + +void erpc_client_set_server_thread_id(void *serverThreadId) +{ + if (g_client != NULL) + { + g_client->setServerThreadId(reinterpret_cast(serverThreadId)); + } +} +#endif + +#if ERPC_MESSAGE_LOGGING +bool erpc_client_add_message_logger(erpc_transport_t transport) +{ + if (g_client != NULL) + { + return g_client->addMessageLogger(reinterpret_cast(transport)); + } + return false; +} +#endif + +#if ERPC_PRE_POST_ACTION +void erpc_client_add_pre_cb_action(pre_post_action_cb preCB) +{ + assert(g_client); + + g_client->addPreCB(preCB); +} + +void erpc_client_add_post_cb_action(pre_post_action_cb postCB) +{ + assert(g_client); + + g_client->addPostCB(postCB); +} +#endif + +void erpc_client_deinit(void) +{ + s_crc16.destroy(); + s_client.destroy(); + s_codecFactory.destroy(); + g_client = NULL; +} diff --git a/erpc_c/setup/erpc_client_setup.h b/erpc_c/setup/erpc_client_setup.h index 16e0ae402..d49696cb3 100644 --- a/erpc_c/setup/erpc_client_setup.h +++ b/erpc_c/setup/erpc_client_setup.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -13,6 +14,9 @@ #include "erpc_common.h" #include "erpc_config_internal.h" #include "erpc_mbf_setup.h" +#if ERPC_PRE_POST_ACTION +#include "erpc_pre_post_action.h" +#endif #if ERPC_NESTED_CALLS #include "erpc_server_setup.h" #endif @@ -33,6 +37,7 @@ extern "C" { #endif +#include #include //! @name Client setup @@ -96,6 +101,24 @@ void erpc_client_set_server_thread_id(void *serverThreadId); bool erpc_client_add_message_logger(erpc_transport_t transport); #endif +#if ERPC_PRE_POST_ACTION +/*! + * @brief This function set callback function executed at the beginning of eRPC call. + * + * @param[in] preCB Callback used at the beginning of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_client_add_pre_cb_action(pre_post_action_cb preCB); + +/*! + * @brief This function set callback function executed at the end of eRPC call. + * + * @param[in] postCB Callback used at the end of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_client_add_post_cb_action(pre_post_action_cb postCB); +#endif + /*! * @brief This function de-initializes client. * diff --git a/erpc_c/setup/erpc_server_setup.cpp b/erpc_c/setup/erpc_server_setup.cpp index ac9984150..8057f301e 100644 --- a/erpc_c/setup/erpc_server_setup.cpp +++ b/erpc_c/setup/erpc_server_setup.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -8,12 +9,14 @@ */ #include "erpc_server_setup.h" + #include "erpc_basic_codec.h" #include "erpc_crc16.h" #include "erpc_manually_constructed.h" #include "erpc_message_buffer.h" #include "erpc_simple_server.h" #include "erpc_transport.h" + #include using namespace erpc; @@ -24,6 +27,7 @@ using namespace erpc; // global server variables static ManuallyConstructed s_server; +extern SimpleServer *g_server; SimpleServer *g_server = NULL; static ManuallyConstructed s_codecFactory; static ManuallyConstructed s_crc16; @@ -67,6 +71,14 @@ void erpc_add_service_to_server(void *service) } } +void erpc_remove_service_from_server(void *service) +{ + if (g_server != NULL && service != NULL) + { + g_server->removeService(static_cast(service)); + } +} + void erpc_server_set_crc(uint32_t crcStart) { s_crc16->setCrcStart(crcStart); @@ -108,3 +120,19 @@ bool erpc_server_add_message_logger(erpc_transport_t transport) return false; } #endif + +#if ERPC_PRE_POST_ACTION +void erpc_client_add_pre_cb_action(pre_post_action_cb preCB) +{ + assert(g_server); + + g_server->addPreCB(preCB); +} + +void erpc_client_add_post_cb_action(pre_post_action_cb postCB) +{ + assert(g_server); + + g_server->addPostCB(postCB); +} +#endif diff --git a/erpc_c/setup/erpc_server_setup.h b/erpc_c/setup/erpc_server_setup.h index a91dda711..cbee335c0 100644 --- a/erpc_c/setup/erpc_server_setup.h +++ b/erpc_c/setup/erpc_server_setup.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright 2020 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -14,6 +15,9 @@ #include "erpc_config_internal.h" #include "erpc_mbf_setup.h" #include "erpc_transport_setup.h" +#if ERPC_PRE_POST_ACTION +#include "erpc_pre_post_action.h" +#endif /*! * @addtogroup server_setup @@ -63,6 +67,13 @@ void erpc_server_deinit(void); */ void erpc_add_service_to_server(void *service); +/*! + * @brief This function removes service from server. + * + * @param[in] service Service which contains implementations of functions called from client to server. + */ +void erpc_remove_service_from_server(void *service); + /*! * @brief Can be used to set own crcStart number. * @@ -117,6 +128,24 @@ void erpc_server_stop(void); bool erpc_server_add_message_logger(erpc_transport_t transport); #endif +#if ERPC_PRE_POST_ACTION +/*! + * @brief This function set callback function executed at the beginning of eRPC call. + * + * @param[in] preCB Callback used at the beginning of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_server_add_pre_cb_action(pre_post_action_cb preCB); + +/*! + * @brief This function set callback function executed at the end of eRPC call. + * + * @param[in] postCB Callback used at the end of eRPC call. When NULL and ERPC_PRE_POST_ACTION_DEFAULT + * is enabled then default function will be set. + */ +void erpc_server_add_post_cb_action(pre_post_action_cb postCB); +#endif + //@} #ifdef __cplusplus diff --git a/erpc_c/setup/erpc_setup_mbf_dynamic.cpp b/erpc_c/setup/erpc_setup_mbf_dynamic.cpp index 14ece5e90..d559b28e3 100644 --- a/erpc_c/setup/erpc_setup_mbf_dynamic.cpp +++ b/erpc_c/setup/erpc_setup_mbf_dynamic.cpp @@ -11,6 +11,7 @@ #include "erpc_manually_constructed.h" #include "erpc_mbf_setup.h" #include "erpc_message_buffer.h" + #include #include @@ -27,7 +28,7 @@ using namespace erpc; class DynamicMessageBufferFactory : public MessageBufferFactory { public: - virtual MessageBuffer create() + virtual MessageBuffer create(void) { uint8_t *buf = new (nothrow) uint8_t[ERPC_DEFAULT_BUFFER_SIZE]; return MessageBuffer(buf, ERPC_DEFAULT_BUFFER_SIZE); diff --git a/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp b/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp index 37c8a257d..8c80bf957 100644 --- a/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp +++ b/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp @@ -12,7 +12,9 @@ #include "erpc_mbf_setup.h" #include "erpc_message_buffer.h" #include "erpc_rpmsg_lite_base_transport.h" + #include "rpmsg_lite.h" + #include using namespace erpc; @@ -47,7 +49,7 @@ class RPMsgMessageBufferFactory : public MessageBufferFactory virtual MessageBuffer create(void) { void *buf = NULL; - unsigned long size = 0; + uint32_t size = 0; buf = rpmsg_lite_alloc_tx_buffer(m_rpmsg, &size, RL_BLOCK); assert(NULL != buf); @@ -65,7 +67,7 @@ class RPMsgMessageBufferFactory : public MessageBufferFactory void *tmp = (void *)buf->get(); if (tmp) { - int ret; + int32_t ret; ret = rpmsg_lite_release_rx_buffer(m_rpmsg, tmp); if (ret != RL_SUCCESS) { diff --git a/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp b/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp index beef233c4..f9fe37c61 100644 --- a/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp +++ b/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp @@ -13,7 +13,9 @@ #include "erpc_mbf_setup.h" #include "erpc_message_buffer.h" #include "erpc_rpmsg_lite_base_transport.h" + #include "rpmsg_lite.h" + #include using namespace erpc; @@ -50,7 +52,7 @@ class RPMsgTTYMessageBufferFactory : public MessageBufferFactory virtual MessageBuffer create(void) { void *buf = NULL; - unsigned long size = 0; + uint32_t size = 0; buf = rpmsg_lite_alloc_tx_buffer(m_rpmsg, &size, TIMEOUT_MS); assert(NULL != buf); @@ -69,7 +71,7 @@ class RPMsgTTYMessageBufferFactory : public MessageBufferFactory void *tmp = (void *)buf->get(); if (tmp) { - int ret; + int32_t ret; ret = rpmsg_lite_release_rx_buffer(m_rpmsg, (void *)(((uint8_t *)tmp) - sizeof(FramedTransport::Header))); if (ret != RL_SUCCESS) { diff --git a/erpc_c/setup/erpc_setup_mbf_static.cpp b/erpc_c/setup/erpc_setup_mbf_static.cpp index cd554405e..a97ecf12f 100644 --- a/erpc_c/setup/erpc_setup_mbf_static.cpp +++ b/erpc_c/setup/erpc_setup_mbf_static.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -11,9 +11,10 @@ #include "erpc_manually_constructed.h" #include "erpc_mbf_setup.h" #include "erpc_message_buffer.h" + #include -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) #include "erpc_threading.h" #endif @@ -33,7 +34,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory * @brief Constructor. */ StaticMessageBufferFactory(void) -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) : m_semaphore(1) #endif { @@ -57,7 +58,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory virtual MessageBuffer create(void) { uint8_t idx = 0; -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) m_semaphore.get(); #endif while (((m_freeBufferBitmap[idx >> 3] & (1 << (idx & 0x7))) == 0) && (idx < ERPC_DEFAULT_BUFFERS_COUNT)) @@ -68,7 +69,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory assert(idx < ERPC_DEFAULT_BUFFERS_COUNT); m_freeBufferBitmap[idx >> 3] &= ~(1 << (idx & 0x7)); -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) m_semaphore.put(); #endif @@ -91,7 +92,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory if (tmp) { uint8_t idx = 0; -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) m_semaphore.get(); #endif while ((tmp != (uint8_t *)m_buffers[idx]) && (idx < ERPC_DEFAULT_BUFFERS_COUNT)) @@ -102,7 +103,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory { m_freeBufferBitmap[idx >> 3] |= 1 << (idx & 0x7); } -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) m_semaphore.put(); #endif } @@ -112,7 +113,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory uint8_t m_freeBufferBitmap[(ERPC_DEFAULT_BUFFERS_COUNT >> 3) + 1]; /*!< Bitmat of used/not used buffers. */ uint64_t m_buffers[ERPC_DEFAULT_BUFFERS_COUNT] [(ERPC_DEFAULT_BUFFER_SIZE + sizeof(uint64_t) - 1) / sizeof(uint64_t)]; /*!< Static buffers. */ -#if !ERPC_THREADS_IS(ERPC_THREADS_NONE) +#if !ERPC_THREADS_IS(NONE) Semaphore m_semaphore; /*!< Semaphore.*/ #endif }; diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp index a4401cbec..fa24806b5 100644 --- a/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp +++ b/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -18,7 +18,7 @@ using namespace erpc; //////////////////////////////////////////////////////////////////////////////// #if !defined(SH_MEM_TOTAL_SIZE) -#define SH_MEM_TOTAL_SIZE (6144) +#define SH_MEM_TOTAL_SIZE (6144U) #endif #if defined(__ICCARM__) /* IAR Workbench */ @@ -38,8 +38,7 @@ static ManuallyConstructed s_transport; // Code //////////////////////////////////////////////////////////////////////////////// -erpc_transport_t erpc_transport_rpmsg_lite_master_init(unsigned long src_addr, unsigned long dst_addr, - int rpmsg_link_id) +erpc_transport_t erpc_transport_rpmsg_lite_master_init(uint32_t src_addr, uint32_t dst_addr, uint32_t rpmsg_link_id) { s_transport.construct(); if (s_transport->init(src_addr, dst_addr, rpmsg_lite_base, SH_MEM_TOTAL_SIZE, rpmsg_link_id) == kErpcStatus_Success) diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp index a2813d8e6..efdb5c350 100644 --- a/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp +++ b/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -23,8 +23,8 @@ static ManuallyConstructed s_transport; // Code //////////////////////////////////////////////////////////////////////////////// -erpc_transport_t erpc_transport_rpmsg_lite_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready, +erpc_transport_t erpc_transport_rpmsg_lite_remote_init(uint32_t src_addr, uint32_t dst_addr, void *start_address, + uint32_t rpmsg_link_id, rpmsg_ready_cb ready, char *nameservice_name) { s_transport.construct(); diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp index a5f076672..fc2de7618 100644 --- a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp +++ b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -17,7 +17,7 @@ using namespace erpc; //////////////////////////////////////////////////////////////////////////////// #if !defined(SH_MEM_TOTAL_SIZE) -#define SH_MEM_TOTAL_SIZE (6144) +#define SH_MEM_TOTAL_SIZE (6144U) #endif #if defined(__ICCARM__) /* IAR Workbench */ @@ -25,7 +25,7 @@ using namespace erpc; char rpmsg_lite_base[SH_MEM_TOTAL_SIZE]; #elif defined(__CC_ARM) || defined(__ARMCC_VERSION) /* Keil MDK */ char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section("rpmsg_sh_mem_section"))); -#elif defined(__GNUC__) /* LPCXpresso */ +#elif defined(__GNUC__) char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section(".noinit.$rpmsg_sh_mem"))); #else #error "RPMsg: Please provide your definition of rpmsg_lite_base[]!" @@ -37,8 +37,8 @@ static ManuallyConstructed s_transport; // Code //////////////////////////////////////////////////////////////////////////////// -erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(unsigned long src_addr, unsigned long dst_addr, - int rpmsg_link_id) +erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(uint32_t src_addr, uint32_t dst_addr, + uint32_t rpmsg_link_id) { s_transport.construct(); if (s_transport->init(src_addr, dst_addr, rpmsg_lite_base, SH_MEM_TOTAL_SIZE, rpmsg_link_id) == kErpcStatus_Success) diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp index 0b2bf7e6f..517e3e315 100644 --- a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp +++ b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -23,9 +23,9 @@ static ManuallyConstructed s_transport; // Code //////////////////////////////////////////////////////////////////////////////// -erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, - rpmsg_ready_cb ready, char *nameservice_name) +erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(uint32_t src_addr, uint32_t dst_addr, void *start_address, + uint32_t rpmsg_link_id, rpmsg_ready_cb ready, + char *nameservice_name) { s_transport.construct(); if (s_transport->init(src_addr, dst_addr, start_address, rpmsg_link_id, ready, nameservice_name) == diff --git a/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp index 3f3b048a0..19c93f86e 100644 --- a/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp +++ b/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -23,8 +24,8 @@ static ManuallyConstructed s_transport; // Code //////////////////////////////////////////////////////////////////////////////// -erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, +erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(uint32_t src_addr, uint32_t dst_addr, + void *start_address, uint32_t rpmsg_link_id, rpmsg_ready_cb ready, char *nameservice_name) { s_transport.construct(); @@ -35,3 +36,8 @@ erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(unsigned long sr } return NULL; } + +void erpc_transport_rpmsg_lite_tty_rtos_deinit(void) +{ + s_transport.destroy(); +} diff --git a/erpc_c/setup/erpc_setup_spidev_master.cpp b/erpc_c/setup/erpc_setup_spidev_master.cpp new file mode 100644 index 000000000..2c7054118 --- /dev/null +++ b/erpc_c/setup/erpc_setup_spidev_master.cpp @@ -0,0 +1,30 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_manually_constructed.h" +#include "erpc_spidev_master_transport.h" +#include "erpc_transport_setup.h" + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +static ManuallyConstructed s_transport; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +erpc_transport_t erpc_transport_spidev_master_init(const char *spidev, uint32_t speed_Hz) +{ + s_transport.construct(spidev, speed_Hz); + s_transport->init(); + return reinterpret_cast(s_transport.get()); +} diff --git a/erpc_c/setup/erpc_setup_tcp.cpp b/erpc_c/setup/erpc_setup_tcp.cpp new file mode 100644 index 000000000..9532aa0d0 --- /dev/null +++ b/erpc_c/setup/erpc_setup_tcp.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2020 (c) Sierra Wireless + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_manually_constructed.h" +#include "erpc_tcp_transport.h" +#include "erpc_transport_setup.h" + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +static ManuallyConstructed s_transport; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +erpc_transport_t erpc_transport_tcp_init(const char *host, uint16_t port, bool isServer) +{ + s_transport.construct(host, port, isServer); + if (kErpcStatus_Success == s_transport->open()) + { + return reinterpret_cast(s_transport.get()); + } + return NULL; +} + +void erpc_transport_tcp_close(void) +{ + s_transport.get()->close(true); +} diff --git a/erpc_c/setup/erpc_setup_usb_cdc.cpp b/erpc_c/setup/erpc_setup_usb_cdc.cpp new file mode 100644 index 000000000..7e361f2c5 --- /dev/null +++ b/erpc_c/setup/erpc_setup_usb_cdc.cpp @@ -0,0 +1,36 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_manually_constructed.h" +#include "erpc_transport_setup.h" +#include "erpc_usb_cdc_transport.h" + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +static ManuallyConstructed s_usb_transport; + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +erpc_transport_t erpc_transport_usb_cdc_init(void *serialHandle, void *serialConfig, void *usbCdcConfig, + uint8_t *usbRingBuffer, uint32_t usbRingBufferLength) +{ + s_usb_transport.construct((serial_handle_t)serialHandle, (serial_manager_config_t *)serialConfig, + (serial_port_usb_cdc_config_t *)usbCdcConfig, (uint8_t *)usbRingBuffer, + (uint32_t)usbRingBufferLength); + if (s_usb_transport->init() == kErpcStatus_Success) + { + return reinterpret_cast(s_usb_transport.get()); + } + return NULL; +} diff --git a/erpc_c/setup/erpc_transport_setup.h b/erpc_c/setup/erpc_transport_setup.h index c845ec737..27b020fb9 100644 --- a/erpc_c/setup/erpc_transport_setup.h +++ b/erpc_c/setup/erpc_transport_setup.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -33,6 +34,7 @@ typedef void (*rpmsg_ready_cb)(void); extern "C" { #endif +#include #include //! @name Transport setup @@ -44,8 +46,8 @@ extern "C" { /*! * @brief Create a CMSIS UART transport. * - * Create a CMSIS UART transport instance, to be used on both the server - * and the client side. + * Create a CMSIS UART transport instance, to be used on both the server + * and the client side. * * @param[in] uartDrv CMSIS USART driver structure address (Driver Control Block). * @@ -60,7 +62,7 @@ erpc_transport_t erpc_transport_cmsis_uart_init(void *uartDrv); /*! * @brief Create a host PC serial port transport. * - * Create a host PC serial port transport instance. + * Create a host PC serial port transport instance. * * @param[in] portName Port name. * @param[in] baudRate Baud rate. @@ -76,7 +78,7 @@ erpc_transport_t erpc_transport_serial_init(const char *portName, long baudRate) /*! * @brief Create a SPI master transport. * - * Create SPI master transport instance, to be used at master core. + * Create SPI master transport instance, to be used at master core. * * @param[in] baseAddr Base address of SPI peripheral used in this transport layer. * @param[in] baudRate SPI baud rate. @@ -89,7 +91,7 @@ erpc_transport_t erpc_transport_spi_master_init(void *baseAddr, uint32_t baudRat /*! * @brief Create a SPI slave transport. * - * Create SPI slave transport instance, to be used at slave core. + * Create SPI slave transport instance, to be used at slave core. * * @param[in] baseAddr Base address of SPI peripheral used in this transport layer. * @param[in] baudRate SPI baud rate. @@ -106,7 +108,7 @@ erpc_transport_t erpc_transport_spi_slave_init(void *baseAddr, uint32_t baudRate /*! * @brief Create a DSPI master transport. * - * Create DSPI master transport instance, to be used at master core. + * Create DSPI master transport instance, to be used at master core. * * @param[in] baseAddr Base address of DSPI peripheral used in this transport layer. * @param[in] baudRate DSPI baud rate. @@ -119,7 +121,7 @@ erpc_transport_t erpc_transport_dspi_master_init(void *baseAddr, uint32_t baudRa /*! * @brief Create a DSPI slave transport. * - * Create DSPI slave transport instance, to be used at slave core. + * Create DSPI slave transport instance, to be used at slave core. * * @param[in] baseAddr Base address of DSPI peripheral used in this transport layer. * @param[in] baudRate DSPI baud rate. @@ -130,14 +132,30 @@ erpc_transport_t erpc_transport_dspi_master_init(void *baseAddr, uint32_t baudRa erpc_transport_t erpc_transport_dspi_slave_init(void *baseAddr, uint32_t baudRate, uint32_t srcClock_Hz); //@} +//! @name SPIdev transport setup +//@{ + +/*! + * @brief Create a SPIdev transport. + * + * Create SPIdev master transport instance, to be used at master core. + * + * @param[in] spidev SPI device name. + * @param[in] speed_Hz SPI clock speed in Hz. + * + * @return Return NULL or erpc_transport_t instance pointer. + */ +erpc_transport_t erpc_transport_spidev_master_init(const char *spidev, uint32_t speed_Hz); +//@} + //! @name MU transport setup //@{ /*! * @brief Create an MU transport. * - * Create Messaging Unit (MU) transport instance, to be used on both the server - * and the client side. Base address of the MU peripheral needs to be passed. + * Create Messaging Unit (MU) transport instance, to be used on both the server + * and the client side. Base address of the MU peripheral needs to be passed. * * @param[in] baseAddr Base address of MU peripheral. * @@ -161,8 +179,7 @@ erpc_transport_t erpc_transport_mu_init(void *baseAddr); * * @return Return NULL or erpc_transport_t instance pointer. */ -erpc_transport_t erpc_transport_rpmsg_lite_master_init(unsigned long src_addr, unsigned long dst_addr, - int rpmsg_link_id); +erpc_transport_t erpc_transport_rpmsg_lite_master_init(uint32_t src_addr, uint32_t dst_addr, uint32_t rpmsg_link_id); /*! * @brief Create an RPMsg-Lite transport. @@ -183,8 +200,8 @@ erpc_transport_t erpc_transport_rpmsg_lite_master_init(unsigned long src_addr, u * * @return Return NULL or erpc_transport_t instance pointer. */ -erpc_transport_t erpc_transport_rpmsg_lite_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, rpmsg_ready_cb ready, +erpc_transport_t erpc_transport_rpmsg_lite_remote_init(uint32_t src_addr, uint32_t dst_addr, void *start_address, + uint32_t rpmsg_link_id, rpmsg_ready_cb ready, char *nameservice_name); /*! @@ -199,8 +216,8 @@ erpc_transport_t erpc_transport_rpmsg_lite_remote_init(unsigned long src_addr, u * * @return Return NULL or erpc_transport_t instance pointer. */ -erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(unsigned long src_addr, unsigned long dst_addr, - int rpmsg_link_id); +erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(uint32_t src_addr, uint32_t dst_addr, + uint32_t rpmsg_link_id); /*! * @brief Create an RPMsg-Lite RTOS transport. @@ -220,9 +237,9 @@ erpc_transport_t erpc_transport_rpmsg_lite_rtos_master_init(unsigned long src_ad * * @return Return NULL or erpc_transport_t instance pointer. */ -erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, - rpmsg_ready_cb ready, char *nameservice_name); +erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(uint32_t src_addr, uint32_t dst_addr, void *start_address, + uint32_t rpmsg_link_id, rpmsg_ready_cb ready, + char *nameservice_name); /*! * @brief Create an RPMsg-Lite TTY transport. @@ -243,9 +260,16 @@ erpc_transport_t erpc_transport_rpmsg_lite_rtos_remote_init(unsigned long src_ad * * @return Return NULL or erpc_transport_t instance pointer. */ -erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(unsigned long src_addr, unsigned long dst_addr, - void *start_address, int rpmsg_link_id, +erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(uint32_t src_addr, uint32_t dst_addr, + void *start_address, uint32_t rpmsg_link_id, rpmsg_ready_cb ready, char *nameservice_name); + +/*! + * @brief Deinitialize an RPMSG lite tty rtos transport. + * + * This function deinitializes the RPMSG lite tty rtos transport. + */ +void erpc_transport_rpmsg_lite_tty_rtos_deinit(void); //@} //! @name Linux RPMSG endpoint setup @@ -255,7 +279,7 @@ erpc_transport_t erpc_transport_rpmsg_lite_tty_rtos_remote_init(unsigned long sr * @brief Create an Linux RPMSG endpoint transport. * * This function is using RPMSG endpoints based on this implementation: - * https://github.com/NXPmicro/rpmsg-sysfs/tree/0aa1817545a765c200b1b2f9b6680a420dcf9171 . + * github.com/NXPmicro/rpmsg-sysfs/tree/0aa1817545a765c200b1b2f9b6680a420dcf9171 . * * When local/remote address is set to '-1', then default addresses will be used. * When type is set to '0', then Datagram model will be used, else Stream. @@ -276,6 +300,62 @@ erpc_transport_t erpc_transport_rpmsg_linux_init(int16_t local_addr, int8_t type void erpc_transport_rpmsg_linux_deinit(void); //@} +//! @name TCP transport setup +//@{ + +/*! + * @brief Create and open TCP transport + * + * For server, create a TCP listen socket and wait for connections + * For client, connect to server + * + * @param[in] host hostname/IP address to listen on or server to connect to + * @param[in] port port to listen on or server to connect to + * @param[in] isServer true if we are a server + * + * @return Return NULL or erpc_transport_t instance pointer. + */ +erpc_transport_t erpc_transport_tcp_init(const char *host, uint16_t port, bool isServer); + +/*! + * @brief Close TCP connection + * + * For server, stop listening and close all sockets. Note that the server mode + * uses and accept() which is a not-recommended blocking method so we can't exit + * until a connection attempts is made. This is a deadlock but assuming that TCP + * code is supposed to be for test, I assume it's acceptable. Otherwise a non-blocking + * socket or select() shoudl be used + * For client, close server connection + * + * @return Return TRUE if listen/connection successful + */ +void erpc_transport_tcp_close(void); +//@} + +//! @name USB CDC transport setup +//@{ + +/*! + * @brief Create an USB CDC transport. + * + * Create an USB CDC transport instance. + * + * @param[in] serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the + * caller, see serial manager header file. + * @param[in] serialConfig Pointer to user-defined configuration structure allocated by the caller, see serial manager + * header file. + * @param[in] usbCdcConfig Pointer to serial port usb config structure allocated by the caller, see serial manager + * header file. + * @param[in] usbRingBuffer Pointer to point serial manager ring buffer allocated by the caller, see serial manager + * header file. + * @param[in] usbRingBufferLength Serial manager ring buffer size. + * + * @return Return NULL or erpc_transport_t instance pointer. + */ +erpc_transport_t erpc_transport_usb_cdc_init(void *serialHandle, void *serialConfig, void *usbCdcConfig, + uint8_t *usbRingBuffer, uint32_t usbRingBufferLength); +//@} + //@} #ifdef __cplusplus diff --git a/erpc_c/setup/setup.dox b/erpc_c/setup/setup.dox index d0793ce72..bfaa43d71 100644 --- a/erpc_c/setup/setup.dox +++ b/erpc_c/setup/setup.dox @@ -15,8 +15,20 @@ @brief Client side setup functions. */ +/*! +@defgroup message_buffer_factory_setup Message Buffer Factory Setup +@ingroup setup +@brief Message Buffer Factory setup functions. +*/ + /*! @defgroup transport_setup Transport Setup @ingroup setup @brief Transport layer initialization. */ + +/*! +@defgroup port_setup_extensions Extension Setup +@ingroup setup +@brief Extension setup functions. +*/ diff --git a/erpc_c/transports/erpc_dspi_master_transport.cpp b/erpc_c/transports/erpc_dspi_master_transport.cpp index 9dfa08d46..0266feeb0 100644 --- a/erpc_c/transports/erpc_dspi_master_transport.cpp +++ b/erpc_c/transports/erpc_dspi_master_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,14 +8,29 @@ */ #include "erpc_dspi_master_transport.h" + #include "board.h" #include "fsl_dspi.h" #include "fsl_gpio.h" #include "fsl_port.h" + #include using namespace erpc; +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER1 0xAB +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER2 0xCD +#else +#ifndef ERPC_BOARD_DSPI_INT_GPIO +#error "Please define the ERPC_BOARD_DSPI_INT_GPIO used to notify when the DSPI Slave is ready to transmit" +#endif +#endif + //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// @@ -26,6 +41,64 @@ static volatile bool s_isSlaveReady = false; // Code //////////////////////////////////////////////////////////////////////////////// +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +/* @brief Initialize the GPIO used to notify the SPI Master */ +static inline void DSpiMasterTransport_NotifyTransferGpioInit(void) +{ + gpio_pin_config_t gpioConfig; + + gpioConfig.pinDirection = kGPIO_DigitalInput; + + PORT_SetPinInterruptConfig(ERPC_BOARD_DSPI_INT_PORT, ERPC_BOARD_DSPI_INT_PIN, kPORT_InterruptFallingEdge); + EnableIRQ(ERPC_BOARD_DSPI_INT_PIN_IRQ); + + GPIO_PinInit(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN, &gpioConfig); + if (!GPIO_PinRead(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN)) + { + s_isSlaveReady = true; + } +} + +static inline void DSpidevMasterTransport_WaitForSlaveReadyGpio(void) +{ + while (!s_isSlaveReady) + { + } +} +#else +static inline void DSpidevMasterTransport_WaitForSlaveReadyMarker(SPI_Type *spiBaseAddr) +{ + uint8_t detected = 0; + uint8_t data; + dspi_transfer_t masterXferSlaveReadyMarker; + + while (1) + { + masterXferSlaveReadyMarker.txData = NULL; + masterXferSlaveReadyMarker.rxData = &data; + masterXferSlaveReadyMarker.dataSize = 1; + masterXferSlaveReadyMarker.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs0; + + if (kStatus_Success == DSPI_MasterTransferBlocking(spiBaseAddr, &masterXferSlaveReadyMarker)) + { + if (ERPC_BOARD_SPI_SLAVE_READY_MARKER1 == data) + { + detected = 1; + } + else if (detected && (ERPC_BOARD_SPI_SLAVE_READY_MARKER2 == data)) + { + break; + } + else + { + detected = 0; + // Thread::sleep(100); + } + } + } +} +#endif + DspiMasterTransport::DspiMasterTransport(SPI_Type *spiBaseAddr, uint32_t baudRate, uint32_t srcClock_Hz) : m_spiBaseAddr(spiBaseAddr) , m_baudRate(baudRate) @@ -41,22 +114,14 @@ DspiMasterTransport::~DspiMasterTransport(void) erpc_status_t DspiMasterTransport::init(void) { dspi_master_config_t dspiConfig; - gpio_pin_config_t gpioConfig; DSPI_MasterGetDefaultConfig(&dspiConfig); dspiConfig.ctarConfig.baudRate = m_baudRate; DSPI_MasterInit(m_spiBaseAddr, &dspiConfig, m_srcClock_Hz); - gpioConfig.pinDirection = kGPIO_DigitalInput; - - PORT_SetPinInterruptConfig(ERPC_BOARD_DSPI_INT_PORT, ERPC_BOARD_DSPI_INT_PIN, kPORT_InterruptFallingEdge); - EnableIRQ(ERPC_BOARD_DSPI_INT_PIN_IRQ); - - GPIO_PinInit(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN, &gpioConfig); - if (!GPIO_PinRead(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN)) - { - s_isSlaveReady = true; - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiMasterTransport_NotifyTransferGpioInit(); +#endif return kErpcStatus_Success; } @@ -71,12 +136,16 @@ erpc_status_t DspiMasterTransport::underlyingReceive(uint8_t *data, uint32_t siz masterXfer.dataSize = size; masterXfer.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs0; - while (!s_isSlaveReady) - { - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpidevMasterTransport_WaitForSlaveReadyGpio(); +#else + DSpidevMasterTransport_WaitForSlaveReadyMarker(m_spiBaseAddr); +#endif status = DSPI_MasterTransferBlocking(m_spiBaseAddr, &masterXfer); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO s_isSlaveReady = false; +#endif return status != kStatus_Success ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; } @@ -91,16 +160,19 @@ erpc_status_t DspiMasterTransport::underlyingSend(const uint8_t *data, uint32_t masterXfer.dataSize = size; masterXfer.configFlags = kDSPI_MasterCtar0 | kDSPI_MasterPcs0; - while (!s_isSlaveReady) - { - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpidevMasterTransport_WaitForSlaveReadyGpio(); +#endif status = DSPI_MasterTransferBlocking(m_spiBaseAddr, &masterXfer); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO s_isSlaveReady = false; +#endif return status != kStatus_Success ? kErpcStatus_SendFailed : kErpcStatus_Success; } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO extern "C" { void ERPC_BOARD_DSPI_INT_PIN_IRQ_HANDLER(void) { @@ -109,3 +181,4 @@ void ERPC_BOARD_DSPI_INT_PIN_IRQ_HANDLER(void) s_isSlaveReady = true; } } +#endif diff --git a/erpc_c/transports/erpc_dspi_master_transport.h b/erpc_c/transports/erpc_dspi_master_transport.h index a7cdcda0a..77914e725 100644 --- a/erpc_c/transports/erpc_dspi_master_transport.h +++ b/erpc_c/transports/erpc_dspi_master_transport.h @@ -11,7 +11,9 @@ #define _EMBEDDED_RPC__DSPI_MASTER_TRANSPORT_H_ #include "erpc_framed_transport.h" + #include "fsl_dspi.h" + #include /*! diff --git a/erpc_c/transports/erpc_dspi_slave_transport.cpp b/erpc_c/transports/erpc_dspi_slave_transport.cpp index 2f797456b..7fde066a9 100644 --- a/erpc_c/transports/erpc_dspi_slave_transport.cpp +++ b/erpc_c/transports/erpc_dspi_slave_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,13 +8,30 @@ */ #include "erpc_dspi_slave_transport.h" + #include "board.h" #include "fsl_dspi.h" #include "fsl_gpio.h" + #include +#include +using namespace std; using namespace erpc; +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN 2 +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER1 0xAB +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER2 0xCD +#else +#ifndef ERPC_BOARD_DSPI_INT_GPIO +#error "Please define the ERPC_BOARD_DSPI_INT_GPIO used to notify when the DSPI Slave is ready to transmit" +#endif +#endif + //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// @@ -26,9 +43,33 @@ static volatile bool s_isTransferCompleted = false; // Code //////////////////////////////////////////////////////////////////////////////// -void DSPI_SlaveUserCallback(SPI_Type *base, dspi_slave_handle_t *handle, erpc_status_t status, void *userData) +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +/* @brief Initialize the GPIO used to notify the SPI Master */ +static inline void DSpiSlaveTransport_NotifyTransferGpioInit(void) +{ + gpio_pin_config_t gpioConfig; + + gpioConfig.pinDirection = kGPIO_DigitalOutput; + gpioConfig.outputLogic = 1U; + + GPIO_PinInit(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN, &gpioConfig); +} + +/* @brief Notify the SPI Master that the Slave is ready for a new transfer */ +static inline void DSpiSlaveTransport_NotifyTransferGpioReady(void) +{ + GPIO_PortClear(ERPC_BOARD_DSPI_INT_GPIO, 1U << ERPC_BOARD_DSPI_INT_PIN); +} + +/* @brief Notify the SPI Master that the Slave has finished the transfer */ +static inline void DSpiSlaveTransport_NotifyTransferGpioCompleted(void) { GPIO_PortSet(ERPC_BOARD_DSPI_INT_GPIO, 1U << ERPC_BOARD_DSPI_INT_PIN); +} +#endif + +static void DSPI_SlaveUserCallback(SPI_Type *base, dspi_slave_handle_t *handle, erpc_status_t status, void *userData) +{ s_isTransferCompleted = true; } @@ -44,25 +85,26 @@ DspiSlaveTransport::~DspiSlaveTransport(void) { if (m_isInited) { - GPIO_PortClear(ERPC_BOARD_DSPI_INT_GPIO, 1U << ERPC_BOARD_DSPI_INT_PIN); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif + DSPI_Deinit(m_spiBaseAddr); + m_isInited = false; } - DSPI_Deinit(m_spiBaseAddr); } erpc_status_t DspiSlaveTransport::init(void) { dspi_slave_config_t dspiConfig; - gpio_pin_config_t gpioConfig; DSPI_SlaveGetDefaultConfig(&dspiConfig); DSPI_SlaveInit(m_spiBaseAddr, &dspiConfig); DSPI_SlaveTransferCreateHandle(m_spiBaseAddr, &g_s_handle, DSPI_SlaveUserCallback, NULL); - gpioConfig.pinDirection = kGPIO_DigitalOutput; - gpioConfig.outputLogic = 1U; - - GPIO_PinInit(ERPC_BOARD_DSPI_INT_GPIO, ERPC_BOARD_DSPI_INT_PIN, &gpioConfig); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioInit(); +#endif m_isInited = true; return kErpcStatus_Success; @@ -81,9 +123,17 @@ erpc_status_t DspiSlaveTransport::underlyingReceive(uint8_t *data, uint32_t size status = DSPI_SlaveTransferNonBlocking(m_spiBaseAddr, &g_s_handle, &slaveXfer); - GPIO_PortClear(ERPC_BOARD_DSPI_INT_GPIO, 1U << ERPC_BOARD_DSPI_INT_PIN); - while (!s_isTransferCompleted) + if (kStatus_Success == status) { +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioReady(); +#endif + while (!s_isTransferCompleted) + { + } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif } return status != kStatus_Success ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; @@ -93,19 +143,49 @@ erpc_status_t DspiSlaveTransport::underlyingSend(const uint8_t *data, uint32_t s { erpc_status_t status; dspi_transfer_t slaveXfer; + s_isTransferCompleted = false; +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO slaveXfer.txData = (uint8_t *)data; slaveXfer.rxData = NULL; slaveXfer.dataSize = size; slaveXfer.configFlags = kDSPI_SlaveCtar0; - s_isTransferCompleted = false; +#else + uint8_t *dspiData = new (nothrow) uint8_t[size + ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN]; + if (dspiData != NULL) + { + dspiData[0] = ERPC_BOARD_SPI_SLAVE_READY_MARKER1; + dspiData[1] = ERPC_BOARD_SPI_SLAVE_READY_MARKER2; + memcpy(&dspiData[ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN], data, size); + } + else + { + return kErpcStatus_SendFailed; + } + + slaveXfer.txData = dspiData; + slaveXfer.rxData = NULL; + slaveXfer.dataSize = size + ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN; + slaveXfer.configFlags = kDSPI_SlaveCtar0; +#endif status = DSPI_SlaveTransferNonBlocking(m_spiBaseAddr, &g_s_handle, &slaveXfer); - GPIO_PortClear(ERPC_BOARD_DSPI_INT_GPIO, 1U << ERPC_BOARD_DSPI_INT_PIN); - while (!s_isTransferCompleted) + if (kStatus_Success == status) { +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioReady(); +#endif + while (!s_isTransferCompleted) + { + } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + DSpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif } +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + delete[] dspiData; +#endif return status != kStatus_Success ? kErpcStatus_SendFailed : kErpcStatus_Success; } diff --git a/erpc_c/transports/erpc_dspi_slave_transport.h b/erpc_c/transports/erpc_dspi_slave_transport.h index 4fbd79c51..ab8e9f8e1 100644 --- a/erpc_c/transports/erpc_dspi_slave_transport.h +++ b/erpc_c/transports/erpc_dspi_slave_transport.h @@ -11,7 +11,9 @@ #define _EMBEDDED_RPC__DSPI_SLAVE_TRANSPORT_H_ #include "erpc_framed_transport.h" + #include "fsl_dspi.h" + #include /*! diff --git a/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp b/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp index 940d80d35..724382d30 100644 --- a/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp +++ b/erpc_c/transports/erpc_inter_thread_buffer_transport.cpp @@ -8,6 +8,7 @@ */ #include "erpc_inter_thread_buffer_transport.h" + #include using namespace erpc; diff --git a/erpc_c/transports/erpc_mu_transport.cpp b/erpc_c/transports/erpc_mu_transport.cpp index bb332d772..f86337b93 100644 --- a/erpc_c/transports/erpc_mu_transport.cpp +++ b/erpc_c/transports/erpc_mu_transport.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * All rights reserved. * * @@ -7,7 +7,9 @@ */ #include "erpc_mu_transport.h" + #include "erpc_config_internal.h" + #include "board.h" using namespace erpc; @@ -77,7 +79,7 @@ MUTransport::MUTransport(void) , m_txMsgSize(0) , m_txCntBytes(0) , m_txBuffer(NULL) -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) , m_rxSemaphore() , m_txSemaphore() , m_sendLock() @@ -144,7 +146,7 @@ void MUTransport::rx_cb(void) if (m_rxCntBytes >= m_rxMsgSize) { m_rxBuffer = NULL; -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) MU_DisableInterrupts(m_muBase, (1U << (MU_CR_RIEn_SHIFT + MU_RR_COUNT - MU_REG_COUNT))); m_rxSemaphore.putFromISR(); #endif @@ -175,7 +177,7 @@ void MUTransport::tx_cb(void) // unblock caller of the send function m_txBuffer = NULL; -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) m_txSemaphore.putFromISR(); #endif } @@ -188,7 +190,7 @@ erpc_status_t MUTransport::receive(MessageBuffer *message) return kErpcStatus_ReceiveFailed; } -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Mutex::Guard lock(m_receiveLock); #endif @@ -200,7 +202,7 @@ erpc_status_t MUTransport::receive(MessageBuffer *message) MU_EnableInterrupts(m_muBase, (1U << (MU_CR_RIEn_SHIFT + MU_RR_COUNT - MU_REG_COUNT))); // wait until the receiving is not complete -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) m_rxSemaphore.get(); #else while (m_rxBuffer) @@ -221,7 +223,7 @@ erpc_status_t MUTransport::send(MessageBuffer *message) return kErpcStatus_SendFailed; } -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Mutex::Guard lock(m_sendLock); #endif @@ -251,7 +253,7 @@ erpc_status_t MUTransport::send(MessageBuffer *message) // enable MU tx empty irq from the last mu tx reg MU_EnableInterrupts(m_muBase, (1U << (MU_CR_TIEn_SHIFT + MU_TR_COUNT - MU_REG_COUNT))); // wait until the sending is not complete -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) m_txSemaphore.get(); #else while (m_txBuffer) diff --git a/erpc_c/transports/erpc_mu_transport.h b/erpc_c/transports/erpc_mu_transport.h index 60b040e64..034e2e74d 100644 --- a/erpc_c/transports/erpc_mu_transport.h +++ b/erpc_c/transports/erpc_mu_transport.h @@ -1,5 +1,5 @@ /* - * Copyright 2017 NXP + * Copyright 2017-2020 NXP * All rights reserved. * * @@ -10,11 +10,12 @@ #define _EMBEDDED_RPC__MU_TRANSPORT_H_ #include "erpc_config_internal.h" -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) #include "erpc_threading.h" #endif #include "erpc_message_buffer.h" #include "erpc_transport.h" + #include "fsl_device_registers.h" #include "fsl_mu.h" @@ -122,7 +123,7 @@ class MUTransport : public Transport * * @return True if exist new message, else false. */ - virtual bool hasMessage() { return m_newMessage; } + virtual bool hasMessage(void) { return m_newMessage; } #if ERPC_TRANSPORT_MU_USE_MCMGR /*! @@ -184,7 +185,7 @@ class MUTransport : public Transport uint32_t m_txCntBytes; /*!< Count of currently received bytes of message */ uint32_t *volatile m_txBuffer; /*!< Pointer to buffer from which is copied data to MU registers during sending */ -#if ERPC_THREADS +#if !ERPC_THREADS_IS(NONE) Semaphore m_rxSemaphore; /*!< Semaphore used by RTOS to block task until the receiving is not complete */ Semaphore m_txSemaphore; /*!< Semaphore used by RTOS to block task until the sending is not complete */ diff --git a/erpc_c/transports/erpc_rpmsg_linux_transport.cpp b/erpc_c/transports/erpc_rpmsg_linux_transport.cpp index 72d00af48..c49810a4e 100644 --- a/erpc_c/transports/erpc_rpmsg_linux_transport.cpp +++ b/erpc_c/transports/erpc_rpmsg_linux_transport.cpp @@ -7,6 +7,7 @@ */ #include "erpc_rpmsg_linux_transport.h" + #include #include diff --git a/erpc_c/transports/erpc_rpmsg_linux_transport.h b/erpc_c/transports/erpc_rpmsg_linux_transport.h index ebc7c6a6b..74d6f0da7 100644 --- a/erpc_c/transports/erpc_rpmsg_linux_transport.h +++ b/erpc_c/transports/erpc_rpmsg_linux_transport.h @@ -7,7 +7,7 @@ */ /* Download "rpmsg_linux_endpoint.h/.cpp" from - * https://github.com/EmbeddedRPC/erpc-imx-demos/tree/master/middleware/rpmsg-cpp */ + * github.com/EmbeddedRPC/erpc-imx-demos/tree/master/middleware/rpmsg-cpp */ #include "erpc_rpmsg_linux_endpoint.h" #include "erpc_transport.h" @@ -19,7 +19,7 @@ namespace erpc { /*! * @brief RPMSG Linux transport to send/receive messages through RPMSG endpoints - * based on https://github.com/NXPmicro/rpmsg-sysfs/tree/0aa1817545a765c200b1b2f9b6680a420dcf9171 + * based on github.com/NXPmicro/rpmsg-sysfs/tree/0aa1817545a765c200b1b2f9b6680a420dcf9171 * implementation. * @ingroup rpmsg_linux_transport */ diff --git a/erpc_c/transports/erpc_rpmsg_lite_base_transport.h b/erpc_c/transports/erpc_rpmsg_lite_base_transport.h index 7a9ba2ed5..b0dc9ccb7 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_base_transport.h +++ b/erpc_c/transports/erpc_rpmsg_lite_base_transport.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__RPMSG_LITE_BASE_TRANSPORT_H_ #include "erpc_transport.h" + #include "rpmsg_lite.h" /*! diff --git a/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.cpp b/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.cpp index 2f2e1b758..21fe33666 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.cpp +++ b/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,8 +8,11 @@ */ #include "erpc_rpmsg_lite_rtos_transport.h" + #include "erpc_config_internal.h" + #include "rpmsg_ns.h" + #include using namespace erpc; @@ -17,7 +20,7 @@ using namespace erpc; //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// -uint8_t RPMsgBaseTransport::s_initialized = 0; +uint8_t RPMsgBaseTransport::s_initialized = 0U; struct rpmsg_lite_instance *RPMsgBaseTransport::s_rpmsg; //////////////////////////////////////////////////////////////////////////////// @@ -37,43 +40,44 @@ RPMsgRTOSTransport::RPMsgRTOSTransport(void) RPMsgRTOSTransport::~RPMsgRTOSTransport(void) { rpmsg_lite_deinit(s_rpmsg); - s_initialized = 0; + s_initialized = 0U; } -erpc_status_t RPMsgRTOSTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - unsigned long length, int rpmsg_link_id) +erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS); if (!s_rpmsg) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_queue = rpmsg_queue_create(s_rpmsg); if (!m_rpmsg_queue) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue); m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } -erpc_status_t RPMsgRTOSTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - int rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name) +erpc_status_t RPMsgRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t rpmsg_link_id, + void (*ready_cb)(void), char *nameservice_name) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS); if (!s_rpmsg) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } /* Signal the other core we are ready */ @@ -82,11 +86,11 @@ erpc_status_t RPMsgRTOSTransport::init(unsigned long src_addr, unsigned long dst ready_cb(); } - while (!rpmsg_lite_is_link_up(s_rpmsg)) + while (0 == rpmsg_lite_is_link_up(s_rpmsg)) { } - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_queue = rpmsg_queue_create(s_rpmsg); @@ -96,27 +100,28 @@ erpc_status_t RPMsgRTOSTransport::init(unsigned long src_addr, unsigned long dst } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue); - if (nameservice_name) + if (NULL != nameservice_name) { - if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, RL_NS_CREATE)) + if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, (uint32_t)RL_NS_CREATE)) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } } m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgRTOSTransport::receive(MessageBuffer *message) { char *buf = NULL; - int length = 0; - int ret_val = rpmsg_queue_recv_nocopy(s_rpmsg, m_rpmsg_queue, &m_dst_addr, &buf, &length, RL_BLOCK); + uint32_t length = 0; + int32_t ret_val = rpmsg_queue_recv_nocopy(s_rpmsg, m_rpmsg_queue, &m_dst_addr, &buf, &length, RL_BLOCK); assert(buf); message->set((uint8_t *)buf, length); message->setUsed(length); - return ret_val != RL_SUCCESS ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; + return ret_val != RL_SUCCESS ? (erpc_status_t)kErpcStatus_ReceiveFailed : (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgRTOSTransport::send(MessageBuffer *message) @@ -125,12 +130,12 @@ erpc_status_t RPMsgRTOSTransport::send(MessageBuffer *message) uint32_t length = message->getLength(); uint32_t used = message->getUsed(); message->set(NULL, 0); - int ret_val = rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, buf, used); + int32_t ret_val = rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, buf, used); if (ret_val == RL_SUCCESS) { - return kErpcStatus_Success; + return (erpc_status_t)kErpcStatus_Success; } message->set(buf, length); message->setUsed(used); - return kErpcStatus_SendFailed; + return (erpc_status_t)kErpcStatus_SendFailed; } diff --git a/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.h b/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.h index 6995d59e6..c23b90743 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.h +++ b/erpc_c/transports/erpc_rpmsg_lite_rtos_transport.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -12,6 +12,7 @@ #include "erpc_message_buffer.h" #include "erpc_rpmsg_lite_base_transport.h" + #include "rpmsg_lite.h" #include "rpmsg_queue.h" @@ -62,8 +63,8 @@ class RPMsgRTOSTransport : public RPMsgBaseTransport * @retval kErpcStatus_Success When rpmsg init function was executed successfully. * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, unsigned long length, - int rpmsg_link_id); + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id); /*! * @brief This function call RPMsg rtos init function - as RPMsg remote @@ -79,7 +80,7 @@ class RPMsgRTOSTransport : public RPMsgBaseTransport * @retval kErpcStatus_Success When rpmsg init function was executed successfully. * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, int rpmsg_link_id, + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name); /*! @@ -117,7 +118,7 @@ class RPMsgRTOSTransport : public RPMsgBaseTransport /* Remote device */ struct remote_device *m_rdev; /*!< Device which represent the second core. */ struct rpmsg_channel *m_app_rp_chnl; /*!< Represent connection between two device (two cores). */ - unsigned long m_dst_addr; /*!< Destination address used by rpmsg. */ + uint32_t m_dst_addr; /*!< Destination address used by rpmsg. */ rpmsg_queue_handle m_rpmsg_queue; /*!< Handle of RPMsg queue. */ struct rpmsg_lite_endpoint *m_rpmsg_ept; /*!< Pointer to RPMsg Lite Endpoint structure. */ }; diff --git a/erpc_c/transports/erpc_rpmsg_lite_transport.cpp b/erpc_c/transports/erpc_rpmsg_lite_transport.cpp index b255d6c5e..21a625019 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_transport.cpp +++ b/erpc_c/transports/erpc_rpmsg_lite_transport.cpp @@ -1,13 +1,15 @@ /* * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_rpmsg_lite_transport.h" + #include "erpc_config_internal.h" + #include "rpmsg_ns.h" using namespace erpc; @@ -15,7 +17,7 @@ using namespace erpc; //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// -uint8_t RPMsgBaseTransport::s_initialized = 0; +uint8_t RPMsgBaseTransport::s_initialized = 0U; struct rpmsg_lite_instance RPMsgTransport::s_rpmsg_ctxt; struct rpmsg_lite_instance *RPMsgBaseTransport::s_rpmsg = NULL; @@ -23,14 +25,14 @@ struct rpmsg_lite_instance *RPMsgBaseTransport::s_rpmsg = NULL; // Code //////////////////////////////////////////////////////////////////////////////// -int RPMsgTransport::rpmsg_read_cb(void *payload, int payload_len, unsigned long src, void *priv) +int32_t RPMsgTransport::rpmsg_read_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv) { RPMsgTransport *transport = (RPMsgTransport *)priv; if (payload_len <= ERPC_DEFAULT_BUFFER_SIZE) { MessageBuffer message((uint8_t *)payload, payload_len); message.setUsed(payload_len); - transport->m_messageQueue.add(message); + (void)transport->m_messageQueue.add(message); } return RL_HOLD; } @@ -45,26 +47,26 @@ RPMsgTransport::RPMsgTransport(void) RPMsgTransport::~RPMsgTransport(void) {} -erpc_status_t RPMsgTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - unsigned long length, int rpmsg_link_id) +erpc_status_t RPMsgTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS, &s_rpmsg_ctxt); - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_read_cb, this, &m_rpmsg_ept_context); m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } -erpc_status_t RPMsgTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - int rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name) +erpc_status_t RPMsgTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t rpmsg_link_id, + void (*ready_cb)(void), char *nameservice_name) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS, &s_rpmsg_ctxt); @@ -74,26 +76,26 @@ erpc_status_t RPMsgTransport::init(unsigned long src_addr, unsigned long dst_add ready_cb(); } - while (!rpmsg_lite_is_link_up(s_rpmsg)) + while (0 == rpmsg_lite_is_link_up(s_rpmsg)) { } - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_read_cb, this, &m_rpmsg_ept_context); - if (nameservice_name) + if (NULL != nameservice_name) { - if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, RL_NS_CREATE)) + if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, (uint32_t)RL_NS_CREATE)) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } } m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgTransport::receive(MessageBuffer *message) @@ -102,12 +104,13 @@ erpc_status_t RPMsgTransport::receive(MessageBuffer *message) { } - return kErpcStatus_Success; + return (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgTransport::send(MessageBuffer *message) { - int ret_val = rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, (char *)message->get(), message->getUsed()); + int32_t ret_val = + rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, (char *)message->get(), message->getUsed()); message->set(NULL, 0); - return ret_val != RL_SUCCESS ? kErpcStatus_SendFailed : kErpcStatus_Success; + return ret_val != RL_SUCCESS ? (erpc_status_t)kErpcStatus_SendFailed : (erpc_status_t)kErpcStatus_Success; } diff --git a/erpc_c/transports/erpc_rpmsg_lite_transport.h b/erpc_c/transports/erpc_rpmsg_lite_transport.h index 622bf1198..22b627076 100644 --- a/erpc_c/transports/erpc_rpmsg_lite_transport.h +++ b/erpc_c/transports/erpc_rpmsg_lite_transport.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -14,6 +14,7 @@ #include "erpc_message_buffer.h" #include "erpc_rpmsg_lite_base_transport.h" #include "erpc_static_queue.h" + #include "rpmsg_lite.h" /*! @@ -65,8 +66,8 @@ class RPMsgTransport : public RPMsgBaseTransport * @retval kErpcStatus_Success When rpmsg init function was executed successfully. * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, unsigned long length, - int rpmsg_link_id); + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id); /*! * @brief Initialization of RPMsgTransport layer - as RPMsg remote @@ -84,7 +85,7 @@ class RPMsgTransport : public RPMsgBaseTransport * @retval kErpcStatus_Success When rpmsg init function was executed successfully. * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, int rpmsg_link_id, + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name); /*! @@ -131,12 +132,12 @@ class RPMsgTransport : public RPMsgBaseTransport * * @return */ - static int rpmsg_read_cb(void *payload, int payload_len, unsigned long src, void *priv); + static int32_t rpmsg_read_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv); StaticQueue m_messageQueue; /*!< Received messages. Queue of messages with buffers filled in rpmsg callback. */ - unsigned long m_dst_addr; /*!< Destination address used by rpmsg. */ + uint32_t m_dst_addr; /*!< Destination address used by rpmsg. */ struct rpmsg_lite_ept_static_context m_rpmsg_ept_context; /*!< RPMsg Lite Endpoint static context. */ struct rpmsg_lite_endpoint *m_rpmsg_ept; /*!< Pointer to RPMsg Lite Endpoint structure. */ diff --git a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.cpp b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.cpp index 755cfff23..7d14fa151 100644 --- a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.cpp +++ b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2017-2020 NXP + * Copyright 2019 ACRIOS Systems s.r.o. * All rights reserved. * * @@ -8,9 +9,12 @@ */ #include "erpc_rpmsg_tty_rtos_transport.h" + #include "erpc_config_internal.h" #include "erpc_framed_transport.h" + #include "rpmsg_ns.h" + #include using namespace erpc; @@ -19,7 +23,7 @@ using namespace std; //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// -uint8_t RPMsgBaseTransport::s_initialized = 0; +uint8_t RPMsgBaseTransport::s_initialized = 0U; struct rpmsg_lite_instance *RPMsgBaseTransport::s_rpmsg; //////////////////////////////////////////////////////////////////////////////// @@ -37,8 +41,31 @@ RPMsgTTYRTOSTransport::RPMsgTTYRTOSTransport(void) RPMsgTTYRTOSTransport::~RPMsgTTYRTOSTransport(void) { - rpmsg_lite_deinit(s_rpmsg); - s_initialized = 0; + if (s_rpmsg != NULL) + { + if (m_rpmsg_ept != RL_NULL) + { + if (RL_SUCCESS != rpmsg_lite_destroy_ept(s_rpmsg, m_rpmsg_ept)) + { + return; + } + } + + if (m_rpmsg_queue != RL_NULL) + { + if (RL_SUCCESS != rpmsg_queue_destroy(s_rpmsg, m_rpmsg_queue)) + { + return; + } + } + + if (RL_SUCCESS != rpmsg_lite_deinit(s_rpmsg)) + { + return; + } + + s_initialized = 0U; + } } void RPMsgTTYRTOSTransport::setCrc16(Crc16 *crcImpl) @@ -47,40 +74,41 @@ void RPMsgTTYRTOSTransport::setCrc16(Crc16 *crcImpl) m_crcImpl = crcImpl; } -erpc_status_t RPMsgTTYRTOSTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - unsigned long length, int rpmsg_link_id) +erpc_status_t RPMsgTTYRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_master_init(base_address, length, rpmsg_link_id, RL_NO_FLAGS); if (!s_rpmsg) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_queue = rpmsg_queue_create(s_rpmsg); if (!m_rpmsg_queue) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue); m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } -erpc_status_t RPMsgTTYRTOSTransport::init(unsigned long src_addr, unsigned long dst_addr, void *base_address, - int rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name) +erpc_status_t RPMsgTTYRTOSTransport::init(uint32_t src_addr, uint32_t dst_addr, void *base_address, + uint32_t rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name) { - if (!s_initialized) + if (0U == s_initialized) { s_rpmsg = rpmsg_lite_remote_init(base_address, rpmsg_link_id, RL_NO_FLAGS); if (!s_rpmsg) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } /* Signal the other core we are ready */ @@ -89,11 +117,11 @@ erpc_status_t RPMsgTTYRTOSTransport::init(unsigned long src_addr, unsigned long ready_cb(); } - while (!rpmsg_lite_is_link_up(s_rpmsg)) + while (0 == rpmsg_lite_is_link_up(s_rpmsg)) { } - s_initialized = 1; + s_initialized = 1U; } m_rpmsg_queue = rpmsg_queue_create(s_rpmsg); @@ -103,16 +131,17 @@ erpc_status_t RPMsgTTYRTOSTransport::init(unsigned long src_addr, unsigned long } m_rpmsg_ept = rpmsg_lite_create_ept(s_rpmsg, src_addr, rpmsg_queue_rx_cb, m_rpmsg_queue); - if (nameservice_name) + if (NULL != nameservice_name) { - if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, RL_NS_CREATE)) + if (RL_SUCCESS != rpmsg_ns_announce(s_rpmsg, m_rpmsg_ept, nameservice_name, (uint32_t)RL_NS_CREATE)) { - return kErpcStatus_InitFailed; + return (erpc_status_t)kErpcStatus_InitFailed; } } m_dst_addr = dst_addr; - return m_rpmsg_ept == RL_NULL ? kErpcStatus_InitFailed : kErpcStatus_Success; + + return m_rpmsg_ept == RL_NULL ? (erpc_status_t)kErpcStatus_InitFailed : (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgTTYRTOSTransport::receive(MessageBuffer *message) @@ -120,24 +149,24 @@ erpc_status_t RPMsgTTYRTOSTransport::receive(MessageBuffer *message) assert(m_crcImpl && "Uninitialized Crc16 object."); FramedTransport::Header h; char *buf = NULL; - int length = 0; + uint32_t length = 0; - int ret_val = rpmsg_queue_recv_nocopy(s_rpmsg, m_rpmsg_queue, &m_dst_addr, &buf, &length, RL_BLOCK); + int32_t ret_val = rpmsg_queue_recv_nocopy(s_rpmsg, m_rpmsg_queue, &m_dst_addr, &buf, &length, RL_BLOCK); assert(buf); memcpy((uint8_t *)&h, buf, sizeof(h)); message->set(&((uint8_t *)buf)[sizeof(h)], length - sizeof(h)); - // Verify CRC. + /* Verify CRC. */ uint16_t computedCrc = m_crcImpl->computeCRC16(&((uint8_t *)buf)[sizeof(h)], h.m_messageSize); if (computedCrc != h.m_crc) { - return kErpcStatus_CrcCheckFailed; + return (erpc_status_t)kErpcStatus_CrcCheckFailed; } message->setUsed(h.m_messageSize); - return ret_val != RL_SUCCESS ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; + return ret_val != RL_SUCCESS ? (erpc_status_t)kErpcStatus_ReceiveFailed : (erpc_status_t)kErpcStatus_Success; } erpc_status_t RPMsgTTYRTOSTransport::send(MessageBuffer *message) @@ -154,12 +183,12 @@ erpc_status_t RPMsgTTYRTOSTransport::send(MessageBuffer *message) memcpy(buf - sizeof(h), (uint8_t *)&h, sizeof(h)); - int ret_val = rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, buf - sizeof(h), used + sizeof(h)); + int32_t ret_val = rpmsg_lite_send_nocopy(s_rpmsg, m_rpmsg_ept, m_dst_addr, buf - sizeof(h), used + sizeof(h)); if (ret_val == RL_SUCCESS) { - return kErpcStatus_Success; + return (erpc_status_t)kErpcStatus_Success; } message->set(buf, length); message->setUsed(used); - return kErpcStatus_SendFailed; + return (erpc_status_t)kErpcStatus_SendFailed; } diff --git a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.h b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.h index c7918b1ce..9960d6db0 100644 --- a/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.h +++ b/erpc_c/transports/erpc_rpmsg_tty_rtos_transport.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2017 NXP + * Copyright 2020 NXP * All rights reserved. * * @@ -13,6 +13,7 @@ #include "erpc_crc16.h" #include "erpc_message_buffer.h" #include "erpc_rpmsg_lite_base_transport.h" + #include "rpmsg_lite.h" #include "rpmsg_queue.h" @@ -35,7 +36,7 @@ namespace erpc { * @brief Transport that uses RPMsg zero copy RTOS API for interprocessor * messaging. * - * @ingroup rpmsg_lite_rtos_transport + * @ingroup rpmsg_tty_rtos_transport */ class RPMsgTTYRTOSTransport : public RPMsgBaseTransport { @@ -67,8 +68,8 @@ class RPMsgTTYRTOSTransport : public RPMsgBaseTransport * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed * successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, unsigned long length, - int rpmsg_link_id); + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t length, + uint32_t rpmsg_link_id); /*! * @brief This function call RPMsg rtos init function - as RPMsg remote @@ -88,7 +89,7 @@ class RPMsgTTYRTOSTransport : public RPMsgBaseTransport * @retval kErpcStatus_InitFailed When rpmsg init function wasn't executed * successfully. */ - virtual erpc_status_t init(unsigned long src_addr, unsigned long dst_addr, void *base_address, int rpmsg_link_id, + virtual erpc_status_t init(uint32_t src_addr, uint32_t dst_addr, void *base_address, uint32_t rpmsg_link_id, void (*ready_cb)(void), char *nameservice_name); /*! @@ -122,7 +123,7 @@ class RPMsgTTYRTOSTransport : public RPMsgBaseTransport virtual void setCrc16(Crc16 *crcImpl); protected: - unsigned long m_dst_addr; /*!< Destination address used by rpmsg. */ + uint32_t m_dst_addr; /*!< Destination address used by rpmsg. */ rpmsg_queue_handle m_rpmsg_queue; /*!< Handle of RPMsg queue. */ struct rpmsg_lite_endpoint *m_rpmsg_ept; /*!< Pointer to RPMsg Lite Endpoint structure. */ Crc16 *m_crcImpl; //!< CRC object. diff --git a/erpc_c/transports/erpc_serial_transport.cpp b/erpc_c/transports/erpc_serial_transport.cpp index 0f7a11c1a..f2326fa51 100644 --- a/erpc_c/transports/erpc_serial_transport.cpp +++ b/erpc_c/transports/erpc_serial_transport.cpp @@ -8,11 +8,20 @@ */ #include "erpc_serial_transport.h" + #include "erpc_message_buffer.h" #include "erpc_serial.h" + #include #include + +#ifdef _WIN32 +#include +#include +#include +#else #include +#endif using namespace erpc; @@ -39,10 +48,14 @@ erpc_status_t SerialTransport::init(uint8_t vtime, uint8_t vmin) { return kErpcStatus_InitFailed; } +#ifdef _WIN32 + // TODO +#else if (!isatty(m_serialHandle)) { return kErpcStatus_InitFailed; } +#endif if (-1 == serial_setup(m_serialHandle, m_baudRate)) { return kErpcStatus_InitFailed; @@ -51,10 +64,14 @@ erpc_status_t SerialTransport::init(uint8_t vtime, uint8_t vmin) { return kErpcStatus_InitFailed; } +#ifdef _WIN32 + // TODO +#else if (-1 == tcflush(m_serialHandle, TCIOFLUSH)) { return kErpcStatus_InitFailed; } +#endif return kErpcStatus_Success; } diff --git a/erpc_c/transports/erpc_serial_transport.h b/erpc_c/transports/erpc_serial_transport.h index 6176bf8ab..85eb34312 100644 --- a/erpc_c/transports/erpc_serial_transport.h +++ b/erpc_c/transports/erpc_serial_transport.h @@ -11,8 +11,14 @@ #define _EMBEDDED_RPC__SERIAL_TRANSPORT_H_ #include "erpc_framed_transport.h" + #include + +#ifdef _WIN32 +typedef long speed_t; +#else #include +#endif /*! * @addtogroup serial_transport diff --git a/erpc_c/transports/erpc_spi_master_transport.cpp b/erpc_c/transports/erpc_spi_master_transport.cpp index f85eee5db..ad05f3e4e 100644 --- a/erpc_c/transports/erpc_spi_master_transport.cpp +++ b/erpc_c/transports/erpc_spi_master_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,14 +8,29 @@ */ #include "erpc_spi_master_transport.h" + #include "board.h" #include "fsl_gpio.h" #include "fsl_port.h" #include "fsl_spi.h" + #include using namespace erpc; +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER1 0xAB +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER2 0xCD +#else +#ifndef ERPC_BOARD_SPI_INT_GPIO +#error "Please define the ERPC_BOARD_SPI_INT_GPIO used to notify when the SPI Slave is ready to transmit" +#endif +#endif + //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// @@ -26,6 +41,63 @@ static volatile bool s_isSlaveReady = false; // Code //////////////////////////////////////////////////////////////////////////////// +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +/* @brief Initialize the GPIO used to notify the SPI Master */ +static inline void SpiMasterTransport_NotifyTransferGpioInit() +{ + gpio_pin_config_t gpioConfig; + + gpioConfig.pinDirection = kGPIO_DigitalInput; + + PORT_SetPinInterruptConfig(ERPC_BOARD_SPI_INT_PORT, ERPC_BOARD_SPI_INT_PIN, kPORT_InterruptFallingEdge); + EnableIRQ(ERPC_BOARD_SPI_INT_PIN_IRQ); + + GPIO_PinInit(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN, &gpioConfig); + if (!GPIO_PinRead(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN)) + { + s_isSlaveReady = true; + } +} + +static inline void SpidevMasterTransport_WaitForSlaveReadyGpio() +{ + while (!s_isSlaveReady) + { + } +} +#else +static inline void SpidevMasterTransport_WaitForSlaveReadyMarker(SPI_Type *spiBaseAddr) +{ + uint8_t detected = 0; + uint8_t data; + spi_transfer_t masterXferSlaveReadyMarker; + + while (1) + { + masterXferSlaveReadyMarker.txData = NULL; + masterXferSlaveReadyMarker.rxData = &data; + masterXferSlaveReadyMarker.dataSize = 1; + + if (kStatus_Success == SPI_MasterTransferBlocking(spiBaseAddr, &masterXferSlaveReadyMarker)) + { + if (ERPC_BOARD_SPI_SLAVE_READY_MARKER1 == data) + { + detected = 1; + } + else if (detected && (ERPC_BOARD_SPI_SLAVE_READY_MARKER2 == data)) + { + break; + } + else + { + detected = 0; + // Thread::sleep(100); + } + } + } +} +#endif + SpiMasterTransport::SpiMasterTransport(SPI_Type *spiBaseAddr, uint32_t baudRate, uint32_t srcClock_Hz) : m_spiBaseAddr(spiBaseAddr) , m_baudRate(baudRate) @@ -41,22 +113,14 @@ SpiMasterTransport::~SpiMasterTransport(void) erpc_status_t SpiMasterTransport::init(void) { spi_master_config_t spiConfig; - gpio_pin_config_t gpioConfig; SPI_MasterGetDefaultConfig(&spiConfig); spiConfig.baudRate_Bps = m_baudRate; SPI_MasterInit(m_spiBaseAddr, &spiConfig, m_srcClock_Hz); - gpioConfig.pinDirection = kGPIO_DigitalInput; - - PORT_SetPinInterruptConfig(ERPC_BOARD_SPI_INT_PORT, ERPC_BOARD_SPI_INT_PIN, kPORT_InterruptFallingEdge); - EnableIRQ(ERPC_BOARD_SPI_INT_PIN_IRQ); - - GPIO_PinInit(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN, &gpioConfig); - if (!GPIO_PinRead(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN)) - { - s_isSlaveReady = true; - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiMasterTransport_NotifyTransferGpioInit(); +#endif return kErpcStatus_Success; } @@ -70,12 +134,16 @@ erpc_status_t SpiMasterTransport::underlyingReceive(uint8_t *data, uint32_t size masterXfer.rxData = data; masterXfer.dataSize = size; - while (!s_isSlaveReady) - { - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpidevMasterTransport_WaitForSlaveReadyGpio(); +#else + SpidevMasterTransport_WaitForSlaveReadyMarker(m_spiBaseAddr); +#endif status = SPI_MasterTransferBlocking(m_spiBaseAddr, &masterXfer); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO s_isSlaveReady = false; +#endif return status != kStatus_Success ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; } @@ -89,16 +157,19 @@ erpc_status_t SpiMasterTransport::underlyingSend(const uint8_t *data, uint32_t s masterXfer.rxData = NULL; masterXfer.dataSize = size; - while (!s_isSlaveReady) - { - } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpidevMasterTransport_WaitForSlaveReadyGpio(); +#endif status = SPI_MasterTransferBlocking(m_spiBaseAddr, &masterXfer); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO s_isSlaveReady = false; +#endif return status != kStatus_Success ? kErpcStatus_SendFailed : kErpcStatus_Success; } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO extern "C" { void ERPC_BOARD_SPI_INT_PIN_IRQ_HANDLER(void) { @@ -107,3 +178,4 @@ void ERPC_BOARD_SPI_INT_PIN_IRQ_HANDLER(void) s_isSlaveReady = true; } } +#endif diff --git a/erpc_c/transports/erpc_spi_master_transport.h b/erpc_c/transports/erpc_spi_master_transport.h index 18fb091aa..47a60d813 100644 --- a/erpc_c/transports/erpc_spi_master_transport.h +++ b/erpc_c/transports/erpc_spi_master_transport.h @@ -11,7 +11,9 @@ #define _EMBEDDED_RPC__SPI_MASTER_TRANSPORT_H_ #include "erpc_framed_transport.h" + #include "fsl_spi.h" + #include #include diff --git a/erpc_c/transports/erpc_spi_slave_transport.cpp b/erpc_c/transports/erpc_spi_slave_transport.cpp index a5e492a1b..90b57db25 100644 --- a/erpc_c/transports/erpc_spi_slave_transport.cpp +++ b/erpc_c/transports/erpc_spi_slave_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,13 +8,31 @@ */ #include "erpc_spi_slave_transport.h" + #include "board.h" #include "fsl_gpio.h" #include "fsl_spi.h" + #include +#include +using namespace std; using namespace erpc; +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN 2 +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER1 0xAB +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER2 0xCD +#else +#ifndef ERPC_BOARD_SPI_INT_GPIO +#error "Please define the ERPC_BOARD_SPI_INT_GPIO used to notify when the SPI Slave is ready to transmit" +#endif +#endif + //////////////////////////////////////////////////////////////////////////////// // Variables //////////////////////////////////////////////////////////////////////////////// @@ -26,9 +44,33 @@ static volatile bool s_isTransferCompleted = false; // Code //////////////////////////////////////////////////////////////////////////////// -void SPI_SlaveUserCallback(SPI_Type *base, spi_slave_handle_t *handle, erpc_status_t status, void *userData) +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +/* @brief Initialize the GPIO used to notify the SPI Master */ +static inline void SpiSlaveTransport_NotifyTransferGpioInit() +{ + gpio_pin_config_t gpioConfig; + + gpioConfig.pinDirection = kGPIO_DigitalOutput; + gpioConfig.outputLogic = 1U; + + GPIO_PinInit(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN, &gpioConfig); +} + +/* @brief Notify the SPI Master that the Slave is ready for a new transfer */ +static inline void SpiSlaveTransport_NotifyTransferGpioReady() +{ + GPIO_PortClear(ERPC_BOARD_SPI_INT_GPIO, 1U << ERPC_BOARD_SPI_INT_PIN); +} + +/* @brief Notify the SPI Master that the Slave has finished the transfer */ +static inline void SpiSlaveTransport_NotifyTransferGpioCompleted() { GPIO_PortSet(ERPC_BOARD_SPI_INT_GPIO, 1U << ERPC_BOARD_SPI_INT_PIN); +} +#endif + +static void SPI_SlaveUserCallback(SPI_Type *base, spi_slave_handle_t *handle, erpc_status_t status, void *userData) +{ s_isTransferCompleted = true; } @@ -44,25 +86,27 @@ SpiSlaveTransport::~SpiSlaveTransport(void) { if (m_isInited) { - GPIO_PortClear(ERPC_BOARD_SPI_INT_GPIO, 1U << ERPC_BOARD_SPI_INT_PIN); +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif + SPI_Deinit(m_spiBaseAddr); + m_isInited = false; } - SPI_Deinit(m_spiBaseAddr); } erpc_status_t SpiSlaveTransport::init(void) { spi_slave_config_t spiConfig; - gpio_pin_config_t gpioConfig; SPI_SlaveGetDefaultConfig(&spiConfig); SPI_SlaveInit(m_spiBaseAddr, &spiConfig); SPI_SlaveTransferCreateHandle(m_spiBaseAddr, &s_s_handle, SPI_SlaveUserCallback, NULL); - gpioConfig.pinDirection = kGPIO_DigitalOutput; - gpioConfig.outputLogic = 1U; +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioInit(); +#endif - GPIO_PinInit(ERPC_BOARD_SPI_INT_GPIO, ERPC_BOARD_SPI_INT_PIN, &gpioConfig); m_isInited = true; return kErpcStatus_Success; } @@ -79,9 +123,17 @@ erpc_status_t SpiSlaveTransport::underlyingReceive(uint8_t *data, uint32_t size) status = SPI_SlaveTransferNonBlocking(m_spiBaseAddr, &s_s_handle, &slaveXfer); - GPIO_PortClear(ERPC_BOARD_SPI_INT_GPIO, 1U << ERPC_BOARD_SPI_INT_PIN); - while (!s_isTransferCompleted) + if (kStatus_Success == status) { +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioReady(); +#endif + while (!s_isTransferCompleted) + { + } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif } return status != kStatus_Success ? kErpcStatus_ReceiveFailed : kErpcStatus_Success; @@ -91,18 +143,47 @@ erpc_status_t SpiSlaveTransport::underlyingSend(const uint8_t *data, uint32_t si { erpc_status_t status; spi_transfer_t slaveXfer; + s_isTransferCompleted = false; +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO slaveXfer.txData = (uint8_t *)data; slaveXfer.rxData = NULL; slaveXfer.dataSize = size; - s_isTransferCompleted = false; +#else + uint8_t *spiData = new (nothrow) uint8_t[size + ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN]; + if (spiData != NULL) + { + spiData[0] = ERPC_BOARD_SPI_SLAVE_READY_MARKER1; + spiData[1] = ERPC_BOARD_SPI_SLAVE_READY_MARKER2; + memcpy(&spiData[ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN], data, size); + } + else + { + return kErpcStatus_SendFailed; + } + + slaveXfer.txData = spiData; + slaveXfer.rxData = NULL; + slaveXfer.dataSize = size + ERPC_BOARD_SPI_SLAVE_READY_MARKER_LEN; +#endif status = SPI_SlaveTransferNonBlocking(m_spiBaseAddr, &s_s_handle, &slaveXfer); - GPIO_PortClear(ERPC_BOARD_SPI_INT_GPIO, 1U << ERPC_BOARD_SPI_INT_PIN); - while (!s_isTransferCompleted) + if (kStatus_Success == status) { +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioReady(); +#endif + while (!s_isTransferCompleted) + { + } +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpiSlaveTransport_NotifyTransferGpioCompleted(); +#endif } +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + delete[] spiData; +#endif return status != kStatus_Success ? kErpcStatus_SendFailed : kErpcStatus_Success; } diff --git a/erpc_c/transports/erpc_spi_slave_transport.h b/erpc_c/transports/erpc_spi_slave_transport.h index 6c7058fd9..39d21d87d 100644 --- a/erpc_c/transports/erpc_spi_slave_transport.h +++ b/erpc_c/transports/erpc_spi_slave_transport.h @@ -11,8 +11,10 @@ #define _EMBEDDED_RPC__SPI_SLAVE_TRANSPORT_H_ #include "erpc_framed_transport.h" + #include "fsl_gpio.h" #include "fsl_spi.h" + #include /*! diff --git a/erpc_c/transports/erpc_spidev_master_transport.cpp b/erpc_c/transports/erpc_spidev_master_transport.cpp new file mode 100644 index 000000000..e53f24023 --- /dev/null +++ b/erpc_c/transports/erpc_spidev_master_transport.cpp @@ -0,0 +1,187 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_spidev_master_transport.h" + +#include "erpc_message_buffer.h" +#include "erpc_spidev.h" +#include "erpc_sysgpio.h" + +#include + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Definitions +//////////////////////////////////////////////////////////////////////////////// + +#ifndef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER1 0xAB +#define ERPC_BOARD_SPI_SLAVE_READY_MARKER2 0xCD +#else +#ifndef ERPC_BOARD_SPI_INT_PIN +#error "Please define the BOARD_SPI_INT_PIN used to notify when the SPI Slave is ready to transmit" +#endif +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +static volatile int s_gpioHandle = 0; +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO +static inline void SpidevMasterTransport_WaitForSlaveReadyGpio() +{ + while (1) + { + /* + * The GPIO pin has been configured to generate interrupts on edge event + * The poll() will return whenever the interrupt was triggered + */ + if (gpio_poll(s_gpioHandle, -1)) + { + break; + } + } +} +#else +static inline void SpidevMasterTransport_WaitForSlaveReadyMarker(int spi_fd) +{ + uint8_t detected = 0; + uint8_t data; + while (1) + { + spidev_transfer(spi_fd, NULL, &data, 1); + if (ERPC_BOARD_SPI_SLAVE_READY_MARKER1 == data) + { + detected = 1; + } + else if (detected && ERPC_BOARD_SPI_SLAVE_READY_MARKER2 == data) + { + break; + } + else + { + detected = 0; + usleep(100); + } + } +} +#endif + +SpidevMasterTransport::SpidevMasterTransport(const char *spidev, uint32_t speed_Hz) +: m_spidevHandle(0) +, m_spidev(spidev) +, m_speed_Hz(speed_Hz) +{ +} + +SpidevMasterTransport::~SpidevMasterTransport(void) +{ + if (m_spidevHandle > 0) + { + spidev_close(m_spidevHandle); + } + +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + if (s_gpioHandle > 0) + { + gpio_close(s_gpioHandle); + } +#endif +} + +erpc_status_t SpidevMasterTransport::init(void) +{ + /* Initialize the SPI device */ + /* Open SPI device file descriptor */ + m_spidevHandle = spidev_open(m_spidev); + if (m_spidevHandle < ERPC_SPIDEV_STATUS_SUCCESS) + { + return kErpcStatus_InitFailed; + } + + /* Set SPI mode to SPI_MODE_0 (CPOL = 0, CPHA = 0) */ + if (ERPC_SPIDEV_STATUS_SUCCESS != spidev_set_mode(m_spidevHandle, 0)) + { + return kErpcStatus_InitFailed; + } + /* Set SPI default max speed */ + if (ERPC_SPIDEV_STATUS_SUCCESS != spidev_set_speed(m_spidevHandle, m_speed_Hz)) + { + return kErpcStatus_InitFailed; + } + /* Set SPI device word length */ + if (ERPC_SPIDEV_STATUS_SUCCESS != spidev_set_wordbits(m_spidevHandle, 8)) + { + return kErpcStatus_InitFailed; + } + +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + /* Initialize the GPIO SPI_INT_PIN */ + /* Export GPIO */ + if (ERPC_SYSGPIO_STATUS_SUCCESS != gpio_export(ERPC_BOARD_SPI_INT_PIN)) + { + return kErpcStatus_InitFailed; + } + /* Set GPIO direction to input */ + if (ERPC_SYSGPIO_STATUS_SUCCESS != gpio_direction(ERPC_BOARD_SPI_INT_PIN, 1)) + { + return kErpcStatus_InitFailed; + } + /* Set GPIO edge interrupt trigger */ + if (ERPC_SYSGPIO_STATUS_SUCCESS != gpio_set_edge(ERPC_BOARD_SPI_INT_PIN, (char *)"falling")) + { + return kErpcStatus_InitFailed; + } + /* Open GPIO file descriptor */ + s_gpioHandle = gpio_open(ERPC_BOARD_SPI_INT_PIN); + if (s_gpioHandle < ERPC_SYSGPIO_STATUS_SUCCESS) + { + return kErpcStatus_InitFailed; + } +#endif + + return kErpcStatus_Success; +} + +erpc_status_t SpidevMasterTransport::underlyingSend(const uint8_t *data, uint32_t size) +{ +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpidevMasterTransport_WaitForSlaveReadyGpio(); +#endif + + if (ERPC_SPIDEV_STATUS_SUCCESS != spidev_transfer(m_spidevHandle, (unsigned char *)data, NULL, size)) + { + return kErpcStatus_SendFailed; + } + return kErpcStatus_Success; +} + +erpc_status_t SpidevMasterTransport::underlyingReceive(uint8_t *data, uint32_t size) +{ +#ifdef ERPC_BOARD_SPI_SLAVE_READY_USE_GPIO + SpidevMasterTransport_WaitForSlaveReadyGpio(); +#else + SpidevMasterTransport_WaitForSlaveReadyMarker(m_spidevHandle); +#endif + + if (ERPC_SPIDEV_STATUS_SUCCESS != spidev_transfer(m_spidevHandle, NULL, data, size)) + { + return kErpcStatus_SendFailed; + } + + return kErpcStatus_Success; +} diff --git a/erpc_c/transports/erpc_spidev_master_transport.h b/erpc_c/transports/erpc_spidev_master_transport.h new file mode 100644 index 000000000..49cf5761a --- /dev/null +++ b/erpc_c/transports/erpc_spidev_master_transport.h @@ -0,0 +1,86 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _EMBEDDED_RPC__SPIDEV_MASTER_TRANSPORT_H_ +#define _EMBEDDED_RPC__SPIDEV_MASTER_TRANSPORT_H_ + +#include "erpc_framed_transport.h" + +/*! + * @addtogroup spidev_master_transport + * @{ + * @file + */ + +//////////////////////////////////////////////////////////////////////////////// +// Classes +//////////////////////////////////////////////////////////////////////////////// + +namespace erpc { +/*! + * @brief Very basic transport to send/receive messages via SPIdev. + * + * @ingroup spidev_master_transport + */ +class SpidevMasterTransport : public FramedTransport +{ +public: + /*! + * @brief Constructor. + * + * @param[in] spidev SPI device name. + * @param[in] speed_Hz SPI clock speed in Hz. + */ + SpidevMasterTransport(const char *spidev, uint32_t speed_Hz); + + /*! + * @brief Destructor. + */ + virtual ~SpidevMasterTransport(void); + + /*! + * @brief Initialize SPI peripheral. + * + * @return Status of init function. + */ + erpc_status_t init(void); + +protected: + int m_spidevHandle; /*!< SPI handle id. */ + const char *m_spidev; /*!< SPI device name. */ + uint32_t m_speed_Hz; /*!< SPI clock speed in Hz. */ + +private: + /*! + * @brief Receive data from SPI peripheral. + * + * @param[inout] data Preallocated buffer for receiving data. + * @param[in] size Size of data to read. + * + * @retval kErpcStatus_ReceiveFailed SPI failed to receive data. + * @retval kErpcStatus_Success Successfully received all data. + */ + virtual erpc_status_t underlyingReceive(uint8_t *data, uint32_t size); + + /*! + * @brief Write data to SPI peripheral. + * + * @param[in] data Buffer to send. + * @param[in] size Size of data to send. + * + * @retval kErpcStatus_SendFailed SPI failed to send data. + * @retval kErpcStatus_Success Successfully sent all data. + */ + virtual erpc_status_t underlyingSend(const uint8_t *data, uint32_t size); +}; + +} // namespace erpc + +/*! @} */ + +#endif // _EMBEDDED_RPC__SPIDEV_MASTER_TRANSPORT_H_ diff --git a/erpc_c/transports/erpc_tcp_transport.cpp b/erpc_c/transports/erpc_tcp_transport.cpp index cb6b1a438..aca968aec 100644 --- a/erpc_c/transports/erpc_tcp_transport.cpp +++ b/erpc_c/transports/erpc_tcp_transport.cpp @@ -7,10 +7,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_tcp_transport.h" + #include +#if ERPC_HAS_POSIX #include +#endif #include #include +#include #include #include #include @@ -81,12 +85,12 @@ erpc_status_t TCPTransport::connectClient(void) { if (m_socket != -1) { - TCP_DEBUG_PRINT("socket already connected\n"); + TCP_DEBUG_PRINT("%s", "socket already connected\n"); return kErpcStatus_Success; } // Fill in hints structure for getaddrinfo. - struct addrinfo hints = { 0 }; + struct addrinfo hints = {}; hints.ai_flags = AI_NUMERICSERV; hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -141,12 +145,15 @@ erpc_status_t TCPTransport::connectClient(void) return kErpcStatus_ConnectionFailure; } + int set = 1; + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *)&set, sizeof(int)); + // On some systems (BSD) we can disable SIGPIPE on the socket. For others (Linux), we have to // ignore SIGPIPE. #if defined(SO_NOSIGPIPE) // Disable SIGPIPE for this socket. This will cause write() to return an EPIPE error if the // other side has disappeared instead of our process receiving a SIGPIPE. - int set = 1; + set = 1; if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)) < 0) { ::close(sock); @@ -162,9 +169,9 @@ erpc_status_t TCPTransport::connectClient(void) return kErpcStatus_Success; } -erpc_status_t TCPTransport::close(void) +erpc_status_t TCPTransport::close(bool stopServer) { - if (m_isServer) + if (m_isServer && stopServer) { m_runServer = false; } @@ -197,7 +204,8 @@ erpc_status_t TCPTransport::underlyingReceive(uint8_t *data, uint32_t size) // Length will be zero if the connection is closed. if (length == 0) { - close(); + // close socket, not server + close(false); return kErpcStatus_ConnectionClosed; } else if (length < 0) @@ -218,7 +226,8 @@ erpc_status_t TCPTransport::underlyingSend(const uint8_t *data, uint32_t size) { if (m_socket <= 0) { - return kErpcStatus_Success; + // we should not pretend to have a succesful Send or we create a deadlock + return kErpcStatus_ConnectionFailure; } // Loop until all data is sent. @@ -234,8 +243,8 @@ erpc_status_t TCPTransport::underlyingSend(const uint8_t *data, uint32_t size) { if (errno == EPIPE) { - // Server closed. - close(); + // close socket, not server + close(false); return kErpcStatus_ConnectionClosed; } return kErpcStatus_SendFailed; @@ -247,7 +256,7 @@ erpc_status_t TCPTransport::underlyingSend(const uint8_t *data, uint32_t size) void TCPTransport::serverThread(void) { - TCP_DEBUG_PRINT("in server thread\n"); + TCP_DEBUG_PRINT("%s", "in server thread\n"); // Create socket. int serverSocket = socket(AF_INET, SOCK_STREAM, 0); @@ -292,17 +301,21 @@ void TCPTransport::serverThread(void) return; } - TCP_DEBUG_PRINT("Listening for connections\n"); + TCP_DEBUG_PRINT("%s", "Listening for connections\n"); while (m_runServer) { struct sockaddr incomingAddress; socklen_t incomingAddressLength = sizeof(struct sockaddr); + // we should use select() otherwise we can't end the server properly int incomingSocket = accept(serverSocket, &incomingAddress, &incomingAddressLength); if (incomingSocket > 0) { // Successfully accepted a connection. m_socket = incomingSocket; + // should be inherited from accept() socket but it's not always ... + int yes = 1; + setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, (void *)&yes, sizeof(yes)); } else { diff --git a/erpc_c/transports/erpc_tcp_transport.h b/erpc_c/transports/erpc_tcp_transport.h index e1bb9db65..a4779b99b 100644 --- a/erpc_c/transports/erpc_tcp_transport.h +++ b/erpc_c/transports/erpc_tcp_transport.h @@ -76,9 +76,10 @@ class TCPTransport : public FramedTransport /*! * @brief This function disconnects client or stop server host. * + * @param[in] stopServer Specify is server shall be closed as well (stop listen()) * @retval #kErpcStatus_Success Always return this. */ - virtual erpc_status_t close(void); + virtual erpc_status_t close(bool stopServer = true); protected: bool m_isServer; /*!< If true then server is using transport, else client. */ diff --git a/erpc_c/transports/erpc_uart_cmsis_transport.cpp b/erpc_c/transports/erpc_uart_cmsis_transport.cpp index 30022e4f8..debfc16bc 100644 --- a/erpc_c/transports/erpc_uart_cmsis_transport.cpp +++ b/erpc_c/transports/erpc_uart_cmsis_transport.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,6 +8,7 @@ */ #include "erpc_uart_cmsis_transport.h" + #include using namespace erpc; @@ -18,6 +19,7 @@ using namespace erpc; static volatile bool s_isTransferReceiveCompleted = false; static volatile bool s_isTransferSendCompleted = false; +static UartTransport *s_uart_instance = NULL; //////////////////////////////////////////////////////////////////////////////// // Code @@ -25,7 +27,12 @@ static volatile bool s_isTransferSendCompleted = false; UartTransport::UartTransport(ARM_DRIVER_USART *uartDrv) : m_uartDrv(uartDrv) +#if !ERPC_THREADS_IS(NONE) +, m_rxSemaphore() +, m_txSemaphore() +#endif { + s_uart_instance = this; } UartTransport::~UartTransport(void) @@ -33,17 +40,37 @@ UartTransport::~UartTransport(void) (*m_uartDrv).Uninitialize(); } +void UartTransport::tx_cb(void) +{ +#if !ERPC_THREADS_IS(NONE) + m_txSemaphore.putFromISR(); +#else + s_isTransferSendCompleted = true; +#endif +} + +void UartTransport::rx_cb(void) +{ +#if !ERPC_THREADS_IS(NONE) + m_rxSemaphore.putFromISR(); +#else + s_isTransferReceiveCompleted = true; +#endif +} + /* Transfer callback */ -void TransferCallback(uint32_t event) +static void TransferCallback(uint32_t event) { + UartTransport *transport = s_uart_instance; + if (event == ARM_USART_EVENT_SEND_COMPLETE) { - s_isTransferSendCompleted = true; + transport->tx_cb(); } if (event == ARM_USART_EVENT_RECEIVE_COMPLETE) { - s_isTransferReceiveCompleted = true; + transport->rx_cb(); } } @@ -77,9 +104,14 @@ erpc_status_t UartTransport::underlyingReceive(uint8_t *data, uint32_t size) int32_t status = (*m_uartDrv).Receive(data, size); if (status == ARM_DRIVER_OK) { +/* wait until the receiving is finished */ +#if !ERPC_THREADS_IS(NONE) + m_rxSemaphore.get(); +#else while (!s_isTransferReceiveCompleted) { } +#endif return kErpcStatus_Success; } @@ -93,9 +125,14 @@ erpc_status_t UartTransport::underlyingSend(const uint8_t *data, uint32_t size) int32_t status = (*m_uartDrv).Send(data, size); if (status == ARM_DRIVER_OK) { +/* wait until the sending is finished */ +#if !ERPC_THREADS_IS(NONE) + m_txSemaphore.get(); +#else while (!s_isTransferSendCompleted) { } +#endif return kErpcStatus_Success; } diff --git a/erpc_c/transports/erpc_uart_cmsis_transport.h b/erpc_c/transports/erpc_uart_cmsis_transport.h index f680b14c3..efcecf5f7 100644 --- a/erpc_c/transports/erpc_uart_cmsis_transport.h +++ b/erpc_c/transports/erpc_uart_cmsis_transport.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -10,8 +10,14 @@ #ifndef _EMBEDDED_RPC__UART_TRANSPORT_H_ #define _EMBEDDED_RPC__UART_TRANSPORT_H_ +#include "erpc_config_internal.h" +#if !ERPC_THREADS_IS(NONE) +#include "erpc_threading.h" +#endif #include "erpc_framed_transport.h" + #include "Driver_USART.h" + #include /*! @@ -54,9 +60,26 @@ class UartTransport : public FramedTransport */ virtual erpc_status_t init(void); + /*! + * @brief Function called from ARM_USART_SignalEvent when ARM_USART_EVENT_RECEIVE_COMPLETE event is asserted + * + * Unblocks the receive function. + */ + void rx_cb(void); + + /*! + * @brief Function called from ARM_USART_SignalEvent when ARM_USART_EVENT_SEND_COMPLETE event is asserted + * + * Unblocks the send function. + */ + void tx_cb(void); + protected: ARM_DRIVER_USART *m_uartDrv; /*!< Access structure of the USART Driver */ - +#if !ERPC_THREADS_IS(NONE) + Semaphore m_rxSemaphore; /*!< Semaphore used by RTOS to block task until the receiving is not complete */ + Semaphore m_txSemaphore; /*!< Semaphore used by RTOS to block task until the sending is not complete */ +#endif private: /*! * @brief Receive data from UART peripheral. diff --git a/erpc_c/transports/erpc_usb_cdc_transport.cpp b/erpc_c/transports/erpc_usb_cdc_transport.cpp new file mode 100644 index 000000000..9e4afb267 --- /dev/null +++ b/erpc_c/transports/erpc_usb_cdc_transport.cpp @@ -0,0 +1,182 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "erpc_usb_cdc_transport.h" + +#include + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Variables +//////////////////////////////////////////////////////////////////////////////// + +static volatile bool s_isTransferReceiveCompleted = false; +static volatile bool s_isTransferSendCompleted = false; +static UsbCdcTransport *s_usbcdc_instance = NULL; + +SDK_ALIGN(static uint8_t s_serialWriteHandleBuffer[SERIAL_MANAGER_WRITE_HANDLE_SIZE], 4); +static serial_write_handle_t s_serialWriteHandle = &s_serialWriteHandleBuffer[0]; /*!< serial manager write handle */ + +SDK_ALIGN(static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE], 4); +static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0]; /*!< serial manager read handle */ +//////////////////////////////////////////////////////////////////////////////// +// Code +//////////////////////////////////////////////////////////////////////////////// + +static void ERPC_SerialManagerTxCallback(void *callbackParam, serial_manager_callback_message_t *message, + serial_manager_status_t status) +{ + UsbCdcTransport *transport = s_usbcdc_instance; + if ((NULL == callbackParam) || (NULL == message)) + { + return; + } + + if (kStatus_SerialManager_Success == status) + { + transport->tx_cb(); + } + else + { + /* Handle other status if needed */ + } +} + +static void ERPC_SerialManagerRxCallback(void *callbackParam, serial_manager_callback_message_t *message, + serial_manager_status_t status) +{ + UsbCdcTransport *transport = s_usbcdc_instance; + if ((NULL == callbackParam) || (NULL == message)) + { + return; + } + + if (kStatus_SerialManager_Success == status) + { + transport->rx_cb(); + } + else + { + /* Handle other status if needed */ + } +} + +void UsbCdcTransport::tx_cb(void) +{ +#if !ERPC_THREADS_IS(NONE) + m_txSemaphore.putFromISR(); +#else + s_isTransferSendCompleted = true; +#endif +} + +void UsbCdcTransport::rx_cb(void) +{ +#if !ERPC_THREADS_IS(NONE) + m_rxSemaphore.putFromISR(); +#else + s_isTransferReceiveCompleted = true; +#endif +} + +UsbCdcTransport::UsbCdcTransport(serial_handle_t serialHandle, serial_manager_config_t *serialConfig, + serial_port_usb_cdc_config_t *usbCdcConfig, uint8_t *usbRingBuffer, + uint32_t usbRingBufferLength) +: m_serialHandle(serialHandle) +, m_serialConfig(serialConfig) +, m_usbCdcConfig(usbCdcConfig) +, m_usbRingBuffer(usbRingBuffer) +, m_usbRingBufferLength(usbRingBufferLength) +#if !ERPC_THREADS_IS(NONE) +, m_rxSemaphore() +, m_txSemaphore() +#endif +{ + s_usbcdc_instance = this; +} + +UsbCdcTransport::~UsbCdcTransport(void) +{ + /* Cleanup */ + SerialManager_CloseWriteHandle(s_serialWriteHandle); + SerialManager_CloseReadHandle(s_serialReadHandle); + SerialManager_Deinit(m_serialHandle); +} + +erpc_status_t UsbCdcTransport::init(void) +{ + /* Init Serial Manager for USB CDC */ + m_serialConfig->type = kSerialPort_UsbCdc; + m_serialConfig->ringBuffer = m_usbRingBuffer; + m_serialConfig->ringBufferSize = m_usbRingBufferLength; + m_serialConfig->portConfig = m_usbCdcConfig; + + if (kStatus_SerialManager_Success == SerialManager_Init(m_serialHandle, m_serialConfig)) + { + if (kStatus_SerialManager_Success == SerialManager_OpenWriteHandle(m_serialHandle, s_serialWriteHandle)) + { + if (kStatus_SerialManager_Success == SerialManager_OpenReadHandle(m_serialHandle, s_serialReadHandle)) + { + if (kStatus_SerialManager_Success == SerialManager_InstallTxCallback(s_serialWriteHandle, + ERPC_SerialManagerTxCallback, + s_serialWriteHandle)) + { + if (kStatus_SerialManager_Success == SerialManager_InstallRxCallback(s_serialReadHandle, + ERPC_SerialManagerRxCallback, + s_serialReadHandle)) + { + return kErpcStatus_Success; + } + } + } + } + } + + return kErpcStatus_InitFailed; +} + +erpc_status_t UsbCdcTransport::underlyingReceive(uint8_t *data, uint32_t size) +{ + s_isTransferReceiveCompleted = false; + + if (kStatus_SerialManager_Success == SerialManager_ReadNonBlocking(s_serialReadHandle, data, size)) + { +/* wait until the receiving is finished */ +#if !ERPC_THREADS_IS(NONE) + m_rxSemaphore.get(); +#else + while (!s_isTransferReceiveCompleted) + { + } +#endif + return kErpcStatus_Success; + } + + return kErpcStatus_ReceiveFailed; +} + +erpc_status_t UsbCdcTransport::underlyingSend(const uint8_t *data, uint32_t size) +{ + s_isTransferSendCompleted = false; + + if (kStatus_SerialManager_Success == SerialManager_WriteNonBlocking(s_serialWriteHandle, (uint8_t *)data, size)) + { +/* wait until the sending is finished */ +#if !ERPC_THREADS_IS(NONE) + m_txSemaphore.get(); +#else + while (!s_isTransferSendCompleted) + { + } +#endif + return kErpcStatus_Success; + } + + return kErpcStatus_SendFailed; +} diff --git a/erpc_c/transports/erpc_usb_cdc_transport.h b/erpc_c/transports/erpc_usb_cdc_transport.h new file mode 100644 index 000000000..0d6879307 --- /dev/null +++ b/erpc_c/transports/erpc_usb_cdc_transport.h @@ -0,0 +1,124 @@ +/* + * Copyright 2020 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ +#define _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ + +#include "erpc_config_internal.h" +#if !ERPC_THREADS_IS(NONE) +#include "erpc_threading.h" +#endif + +#include "erpc_framed_transport.h" + +#include "fsl_component_serial_manager.h" + +#include + +/*! + * @addtogroup USB_CDC_transport + * @{ + * @file + */ + +//////////////////////////////////////////////////////////////////////////////// +// Classes +//////////////////////////////////////////////////////////////////////////////// + +namespace erpc { +/*! + * @brief Very basic transport to send/receive messages via virtual USB CDC port. + * + * @ingroup USB_CDC_transport + */ +class UsbCdcTransport : public FramedTransport +{ +public: + /*! + * @brief Constructor. + * + * @param[in] serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the + * caller, see serial manager header file. + * @param[in] serialConfig Pointer to user-defined configuration structure allocated by the caller, see serial + * manager header file. + * @param[in] usbCdcConfig Pointer to serial port usb config structure allocated by the caller, see serial manager + * header file. + * @param[in] usbRingBuffer Pointer to point serial manager ring buffer allocated by the caller, see serial manager + * header file. + * @param[in] usbRingBufferLength Serial manager ring buffer size. + */ + UsbCdcTransport(serial_handle_t serialHandle, serial_manager_config_t *serialConfig, + serial_port_usb_cdc_config_t *usbCdcConfig, uint8_t *usbRingBuffer, uint32_t usbRingBufferLength); + + /*! + * @brief Destructor. + */ + virtual ~UsbCdcTransport(void); + + /*! + * @brief Initialize USB CDC peripheral configuration structure with values specified in UsbCdcTransport + * constructor. + * + * @retval kErpcStatus_InitFailed When USB CDC init function failed. + * @retval kErpcStatus_Success When USB CDC init function was executed successfully. + */ + virtual erpc_status_t init(void); + + /*! + * @brief Function called from Serial Manager Rx Callback to unblock the receive function + * + * Unblocks the receive function. + */ + void rx_cb(void); + + /*! + * @brief Function called from Serial Manager Tx Callback to unblock the send function + * + * Unblocks the send function. + */ + void tx_cb(void); + +protected: +#if !ERPC_THREADS_IS(NONE) + Semaphore m_rxSemaphore; /*!< Semaphore used by RTOS to block task until the receiving is not complete */ + Semaphore m_txSemaphore; /*!< Semaphore used by RTOS to block task until the sending is not complete */ +#endif +private: + serial_handle_t m_serialHandle; + serial_manager_config_t *m_serialConfig; + serial_port_usb_cdc_config_t *m_usbCdcConfig; + uint8_t *m_usbRingBuffer; + uint32_t m_usbRingBufferLength; + + /*! + * @brief Receive data from USB CDC peripheral. + * + * @param[inout] data Preallocated buffer for receiving data. + * @param[in] size Size of data to read. + * + * @retval kErpcStatus_ReceiveFailed USB CDC failed to receive data. + * @retval kErpcStatus_Success Successfully received all data. + */ + virtual erpc_status_t underlyingReceive(uint8_t *data, uint32_t size); + + /*! + * @brief Write data to USB CDC peripheral. + * + * @param[in] data Buffer to send. + * @param[in] size Size of data to send. + * + * @retval kErpcStatus_Success Always returns success status. + */ + virtual erpc_status_t underlyingSend(const uint8_t *data, uint32_t size); +}; + +} // namespace erpc + +/*! @} */ + +#endif /* _EMBEDDED_RPC__USB_CDC_TRANSPORT_H_ */ diff --git a/erpc_c/transports/transports.dox b/erpc_c/transports/transports.dox index 9aea8a751..67e20c961 100644 --- a/erpc_c/transports/transports.dox +++ b/erpc_c/transports/transports.dox @@ -27,6 +27,12 @@ @brief Kinetis SDK SPI slave driver transport. */ +/*! +@defgroup spidev_master_transport SPIdev Linux Master +@ingroup transports +@brief SPIdev Linux transport. +*/ + /*! @defgroup itbp_transport Inter-thread @ingroup transports @@ -56,6 +62,12 @@ @brief RPMsg-Lite zero copy transport. */ +/*! +@defgroup rpmsg_tty_rtos_transport RPMsg TTY RTOS +@ingroup transports +@brief RPMsg TTY RTOS transport. +*/ + /*! @defgroup tcp_transport TCP/IP @ingroup transports @@ -73,3 +85,9 @@ @ingroup transports @brief RPMsg endpoints linux transport. */ + +/*! +@defgroup USB_CDC_transport USB CDC +@ingroup transports +@brief USB CDC transport. +*/ diff --git a/erpc_python/README.rst b/erpc_python/README.rst deleted file mode 100644 index 822acf464..000000000 --- a/erpc_python/README.rst +++ /dev/null @@ -1,24 +0,0 @@ -| eRPC Python Infrastructure -| ========================== -| -| This folder contains the Python implementation of the eRPC infrastructure. -| -| The eRPC project is stored on Github_. -.. _Github: https://github.com/EmbeddedRPC/erpc -| -| The Python implementation of eRPC is fully compatible with the C/C++ implementation at the -| protocol level. Also, the classes mirror those in the C++ infrastructure. -| -| Installation: -| -| To install the eRPC Python infrastructure, run the setup.py script like this: -| -| pip install erpc -| -| -| Once installed, you can access the infrastructure via a standard import statement. -| -| import erpc -| xport = erpc.transport.SerialTransport("/dev/ttyS1", 115200) -| client = erpc.client.ClientManager(xport, erpc.basic_codec.BasicCodec) - diff --git a/erpc_python/README_Pypi.md b/erpc_python/README_Pypi.md new file mode 100644 index 000000000..7b48e33b7 --- /dev/null +++ b/erpc_python/README_Pypi.md @@ -0,0 +1,23 @@ +eRPC Python Infrastructure +========================== + +This folder contains the Python implementation of the eRPC infrastructure. + +The eRPC project is stored on Github: https://github.com/EmbeddedRPC/erpc + +The Python implementation of eRPC is fully compatible with the C/C++ implementation at the +protocol level. Also, the classes mirror those in the C++ infrastructure. + +Installation: + + To install the eRPC Python infrastructure, run the setup.py script like this: + + pip install erpc + + + Once installed, you can access the infrastructure via a standard import statement. + + import erpc + xport = erpc.transport.SerialTransport("/dev/ttyS1", 115200) + client = erpc.client.ClientManager(xport, erpc.basic_codec.BasicCodec) + diff --git a/erpc_python/erpc/erpc_version.py b/erpc_python/erpc/erpc_version.py index 5d09d9924..11675c637 100644 --- a/erpc_python/erpc/erpc_version.py +++ b/erpc_python/erpc/erpc_version.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -# Copyright 2017 NXP +# Copyright 2017-2020 NXP # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause #Should be same as in erpc_version.h -ERPC_VERSION = "1.7.2" +ERPC_VERSION = "1.8.0" diff --git a/erpc_python/erpc/server.py b/erpc_python/erpc/server.py index ab14a9582..9c991e193 100644 --- a/erpc_python/erpc/server.py +++ b/erpc_python/erpc/server.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # Copyright 2016 NXP +# Copyright 2020 ACRIOS Systems s.r.o. # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -20,8 +21,8 @@ def service_id(self): def handle_invocation(self, methodId, sequence, codec): try: self._methods[methodId](sequence, codec) - except KeyError: - raise RequestError("invalid method ID (%d)" % (methodId)) + except Exception as e: + raise RequestError("invalid method ID (%d) or method implementation: %s" % (methodId, str(e))) class Server(object): def __init__(self, transport=None, codecClass=None): diff --git a/erpc_python/setup.cfg b/erpc_python/setup.cfg index c34b498b2..adf5ed72a 100644 --- a/erpc_python/setup.cfg +++ b/erpc_python/setup.cfg @@ -1,5 +1,7 @@ [bdist_wheel] -# This flag says that the code is written to work on both Python 2 and Python -# 3. If at all possible, it is good practice to do this. If you cannot, you -# will need to generate wheels for each Python version that you support. -universal=1 \ No newline at end of file +universal = 1 + +[egg_info] +tag_build = +tag_date = 0 + diff --git a/erpc_python/setup.py b/erpc_python/setup.py index 565c1f4e6..98e860211 100644 --- a/erpc_python/setup.py +++ b/erpc_python/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Copyright (c) 2016 Freescale Semiconductor, Inc. -# Copyright 2016 NXP +# Copyright 2016-2019 NXP # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -13,7 +13,7 @@ here = path.abspath(path.dirname(__file__)) -with open(path.join(here, 'README.rst'), encoding='utf-8') as f: +with open(path.join(here, 'README_Pypi.md'), encoding='utf-8') as f: long_description = f.read() #steps: https://packaging.python.org/distributing/ @@ -26,6 +26,7 @@ version=erpc_version.ERPC_VERSION, description="eRPC Python infrastructure", long_description=long_description, + long_description_content_type="text/markdown", author="NXP", url='https://github.com/embeddedrpc/erpc', license="BSD 3-Clause", @@ -41,7 +42,7 @@ "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", ], - keywords='rpc rpc-framework embedded multicore multiprocessor amp', + keywords='rpc rpc-framework embedded multicore multiprocessor amp rpmsg_lite', use_2to3=True, packages=['erpc'], ) diff --git a/erpcgen/src/AstNode.cpp b/erpcgen/src/AstNode.cpp index c278b1317..eff76d2a4 100644 --- a/erpcgen/src/AstNode.cpp +++ b/erpcgen/src/AstNode.cpp @@ -8,8 +8,10 @@ */ #include "AstNode.h" + #include "ErpcLexer.h" #include "format_string.h" + #include #include @@ -218,8 +220,7 @@ string AstNode::getDescription() const case TOK_ARRAY: case TOK_UNION_CASE: break; - default: - { + default: { output += " " + valToString + " "; if (valToString.size() == 1) { diff --git a/erpcgen/src/AstNode.h b/erpcgen/src/AstNode.h index 9d285acca..25a062721 100644 --- a/erpcgen/src/AstNode.h +++ b/erpcgen/src/AstNode.h @@ -12,6 +12,7 @@ #include "Token.h" #include "smart_ptr.h" + #include #include #include diff --git a/erpcgen/src/AstWalker.cpp b/erpcgen/src/AstWalker.cpp index 9f51c1a36..d2af18126 100644 --- a/erpcgen/src/AstWalker.cpp +++ b/erpcgen/src/AstWalker.cpp @@ -8,6 +8,7 @@ */ #include "AstWalker.h" + #include "ErpcLexer.h" #include "Logging.h" diff --git a/erpcgen/src/AstWalker.h b/erpcgen/src/AstWalker.h index ad054b249..172c14172 100644 --- a/erpcgen/src/AstWalker.h +++ b/erpcgen/src/AstWalker.h @@ -117,24 +117,92 @@ class AstWalker * @brief Top-down handlers types, which can be called. */ //@{ - virtual void handleRoot(AstNode *node, top_down){}; - virtual AstNode *handleProgram(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleConst(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleChildren(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleType(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleEnum(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleEnumMember(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleStruct(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleStructMember(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleUnion(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleUnionCase(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleInterface(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleFunction(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleParam(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleExpr(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleBinaryOp(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleUnaryOp(AstNode *node, top_down) { return nullptr; } - virtual AstNode *handleAnnotation(AstNode *node, top_down) { return nullptr; } + virtual void handleRoot(AstNode *node, top_down) { (void)node; }; + virtual AstNode *handleProgram(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleConst(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleChildren(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleType(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleEnum(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleEnumMember(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleStruct(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleStructMember(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnion(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnionCase(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleInterface(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleFunction(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleParam(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleExpr(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleBinaryOp(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnaryOp(AstNode *node, top_down) + { + (void)node; + return nullptr; + } + virtual AstNode *handleAnnotation(AstNode *node, top_down) + { + (void)node; + return nullptr; + } //@} /* @@ -143,24 +211,92 @@ class AstWalker * @brief Bottom-up handlers types, which can be called. */ //@{ - virtual void handleRoot(AstNode *node, bottom_up){}; - virtual AstNode *handleProgram(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleConst(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleChildren(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleType(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleEnum(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleEnumMember(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleStruct(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleStructMember(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleUnion(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleUnionCase(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleInterface(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleFunction(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleParam(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleExpr(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleBinaryOp(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleUnaryOp(AstNode *node, bottom_up) { return nullptr; } - virtual AstNode *handleAnnotation(AstNode *node, bottom_up) { return nullptr; } + virtual void handleRoot(AstNode *node, bottom_up) { (void)node; }; + virtual AstNode *handleProgram(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleConst(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleChildren(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleType(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleEnum(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleEnumMember(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleStruct(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleStructMember(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnion(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnionCase(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleInterface(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleFunction(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleParam(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleExpr(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleBinaryOp(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleUnaryOp(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } + virtual AstNode *handleAnnotation(AstNode *node, bottom_up) + { + (void)node; + return nullptr; + } //@} }; diff --git a/erpcgen/src/CGenerator.cpp b/erpcgen/src/CGenerator.cpp index ca454b092..a71caf864 100644 --- a/erpcgen/src/CGenerator.cpp +++ b/erpcgen/src/CGenerator.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * @@ -8,10 +8,12 @@ */ #include "CGenerator.h" + #include "Logging.h" #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" + #include #include #include @@ -163,22 +165,19 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da switch (dataType->getDataType()) { - case DataType::kAliasType: - { + case DataType::kAliasType: { AliasType *aliasType = dynamic_cast(dataType); assert(aliasType); aliasType->setElementType(findChildDataType(dataTypes, aliasType->getElementType())); break; } - case DataType::kArrayType: - { + case DataType::kArrayType: { ArrayType *arrayType = dynamic_cast(dataType); assert(arrayType); arrayType->setElementType(findChildDataType(dataTypes, arrayType->getElementType())); break; } - case DataType::kBuiltinType: - { + case DataType::kBuiltinType: { if (dataType->isBinary()) { // check if binary data type was replaced with structure wrapper @@ -209,8 +208,7 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da dataTypes.insert(dataType); break; } - case DataType::kFunctionType: - { + case DataType::kFunctionType: { FunctionType *funcType = dynamic_cast(dataType); assert(funcType); @@ -233,8 +231,7 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da } break; } - case DataType::kListType: - { + case DataType::kListType: { // The only child node of a list node is the element type. ListType *listType = dynamic_cast(dataType); DataType *trueContainerDataType = listType->getTrueContainerDataType(); @@ -326,8 +323,7 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da break; } } - case DataType::kStructType: - { + case DataType::kStructType: { StructType *structType = dynamic_cast(dataType); assert(structType); @@ -346,8 +342,7 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da } break; } - case DataType::kUnionType: - { + case DataType::kUnionType: { // Keil need extra pragma option when unions are used. m_templateData["usedUnionType"] = true; UnionType *currentUnion = dynamic_cast(dataType); @@ -361,8 +356,7 @@ DataType *CGenerator::findChildDataType(set &dataTypes, DataType *da } break; } - default: - { + default: { break; } } @@ -629,7 +623,7 @@ data_map CGenerator::getEnumTemplateData(EnumType *enumType) data_list CGenerator::getEnumMembersTemplateData(EnumType *enumType) { - int j = 0; + unsigned int j = 0; data_list enumMembersList; for (auto member : enumType->getMembers()) { @@ -720,12 +714,12 @@ void CGenerator::makeAliasesTemplateData() else { /* skip structure, unions and functions type definitions */ - for (int aliasTypesIt = i; aliasTypesIt < aliasTypeVector.size(); ++aliasTypesIt) + for (unsigned int aliasTypesIt = i; aliasTypesIt < aliasTypeVector.size(); ++aliasTypesIt) { if (callbackParamType == aliasTypeVector[aliasTypesIt]) { // Add aliases in IDL declaration order. - int nextIt = aliasTypesIt + 1; + unsigned int nextIt = aliasTypesIt + 1; while (nextIt < aliasTypeVector.size()) { AliasType *nextAlias = dynamic_cast(aliasTypeVector[nextIt]); @@ -811,8 +805,7 @@ void CGenerator::makeAliasesTemplateData() aliasInfo["unnamedName"] = getOutputName(aliasType); switch (elementDataType->getDataType()) { - case DataType::kStructType: - { + case DataType::kStructType: { StructType *structType = dynamic_cast(elementDataType); assert(structType); aliasInfo["unnamed"] = getStructDefinitionTemplateData( @@ -820,8 +813,7 @@ void CGenerator::makeAliasesTemplateData() aliasInfo["unnamedType"] = "struct"; break; } - case DataType::kEnumType: - { + case DataType::kEnumType: { EnumType *enumType = dynamic_cast(elementDataType); assert(enumType); aliasInfo["unnamed"] = getEnumTemplateData(enumType); @@ -870,8 +862,7 @@ void CGenerator::makeSymbolsDeclarationTemplateData() switch ((*it)->getSymbolType()) { - case DataType::kStructTypeSymbol: - { + case DataType::kStructTypeSymbol: { StructType *structType = dynamic_cast(*it); assert(structType); @@ -882,8 +873,7 @@ void CGenerator::makeSymbolsDeclarationTemplateData() break; } - case DataType::kUnionTypeSymbol: - { + case DataType::kUnionTypeSymbol: { UnionType *unionType = dynamic_cast(*it); assert(unionType); @@ -936,8 +926,7 @@ data_map CGenerator::makeGroupSymbolsTemplateData(Group *group) { switch (symbol->getSymbolType()) { - case DataType::kStructTypeSymbol: - { + case DataType::kStructTypeSymbol: { StructType *structType = dynamic_cast(symbol); assert(structType); @@ -973,8 +962,7 @@ data_map CGenerator::makeGroupSymbolsTemplateData(Group *group) } break; } - case DataType::kUnionTypeSymbol: - { + case DataType::kUnionTypeSymbol: { UnionType *unionType = dynamic_cast(symbol); assert(unionType); @@ -1267,6 +1255,7 @@ data_map CGenerator::getUnionDeclarationTemplateData(UnionType *unionType) data_map CGenerator::getUnionDefinitionTemplateData(Group *group, UnionType *unionType, data_map &unionInfo, bool &needUnionsServerFree) { + (void)group; bool needTempVariable = false; unionInfo["coderCall"] = getEncodeDecodeCall("data->", nullptr, unionType, nullptr, true, nullptr, needTempVariable, false); @@ -1573,9 +1562,9 @@ data_map CGenerator::getFunctionBaseTemplateData(Group *group, FunctionBase *fn) Symbol *symbol = fn->getParameters().getScope().getSymbol(maxLengthName, false); if (symbol) { - StructMember *structMember = dynamic_cast(symbol); - assert(structMember); - if (structMember->getDirection() != kInDirection) + StructMember *symbolStructMember = dynamic_cast(symbol); + assert(symbolStructMember); + if (symbolStructMember->getDirection() != kInDirection) { throw semantic_error( format_string("line %d, ref %d: The parameter named by a max_length annotation must be " @@ -1756,8 +1745,7 @@ void CGenerator::setSymbolDataToSide(const Symbol *symbolType, const set<_param_ { case Symbol::kStructTypeSymbol: case Symbol::kUnionTypeSymbol: - case Symbol::kFunctionTypeSymbol: - { + case Symbol::kFunctionTypeSymbol: { bool in = directions.count(kInDirection); bool out = directions.count(kOutDirection); bool inOut = directions.count(kInoutDirection); @@ -1782,32 +1770,27 @@ void CGenerator::setSymbolDataToSide(const Symbol *symbolType, const set<_param_ break; } - case Symbol::kStructMemberSymbol: - { + case Symbol::kStructMemberSymbol: { const StructMember *structMember = dynamic_cast(symbolType); assert(structMember); switch (structMember->getDirection()) { case kOutDirection: - case kInoutDirection: - { + case kInoutDirection: { direction = kInOut; break; } - case kInDirection: - { + case kInDirection: { direction = kIn; break; } - default: - { + default: { throw internal_error("Unsupported direction type of structure member."); } } break; } - default: - { + default: { throw internal_error(format_string("Symbol: %s is not structure or function parameter.", symbolType->getDescription().c_str())); } @@ -1815,18 +1798,15 @@ void CGenerator::setSymbolDataToSide(const Symbol *symbolType, const set<_param_ switch (direction) { - case kIn: - { + case kIn: { toServer.push_back(dataMap); break; } - case kOut: - { + case kOut: { toClient.push_back(dataMap); break; } - case kInOut: - { + case kInOut: { toServer.push_back(dataMap); toClient.push_back(dataMap); break; @@ -1842,6 +1822,7 @@ void CGenerator::setSymbolDataToSide(const Symbol *symbolType, const set<_param_ data_map CGenerator::getTypeInfo(DataType *t, bool isFunction) { + (void)isFunction; data_map info; info["isNotVoid"] = make_data(t->getDataType() != DataType::kVoidType); return info; @@ -1863,7 +1844,7 @@ string CGenerator::getErrorReturnValue(FunctionBase *fn) } else if (dataType->isString()) { - return "(char *) " + returnVal->toString(); + return (dataType->isUString() ? "(unsigned char *)" : "(char*)") + returnVal->toString(); } else if (dataType->isScalar()) { @@ -1886,28 +1867,22 @@ string CGenerator::getErrorReturnValue(FunctionBase *fn) assert(builtinType); switch (builtinType->getBuiltinType()) { - case BuiltinType::kBoolType: - { + case BuiltinType::kBoolType: { return "false"; } - case BuiltinType::kUInt8Type: - { + case BuiltinType::kUInt8Type: { return "0xFFU"; } - case BuiltinType::kUInt16Type: - { + case BuiltinType::kUInt16Type: { return "0xFFFFU"; } - case BuiltinType::kUInt32Type: - { + case BuiltinType::kUInt32Type: { return "0xFFFFFFFFU"; } - case BuiltinType::kUInt64Type: - { + case BuiltinType::kUInt64Type: { return "0xFFFFFFFFFFFFFFFFU"; } - default: - { + default: { return "-1"; } } @@ -1937,7 +1912,7 @@ string CGenerator::getFunctionServerCall(Function *fn, FunctionType *functionTyp if (params.size()) { - int n = 0; + unsigned int n = 0; for (auto it : params) { bool isLast = (n == params.size() - 1); @@ -2013,7 +1988,7 @@ string CGenerator::getFunctionPrototype(Group *group, FunctionBase *fn, std::str if (params.size()) { - int n = 0; + unsigned int n = 0; for (auto it : params) { bool isLast = (n == params.size() - 1); @@ -2127,7 +2102,7 @@ string CGenerator::generateIncludeGuardName(const string &filename) size_t found = filename.find_last_of("/\\"); if (found != string::npos) { - string fileNoPath = filename.substr(found + 1); + fileNoPath = filename.substr(found + 1); } // Create include guard macro name. guard = "_"; @@ -2146,8 +2121,7 @@ string CGenerator::getTypenameName(DataType *t, const string &name) string returnName; switch (t->getDataType()) { - case DataType::kArrayType: - { + case DataType::kArrayType: { // Array type requires the array element count to come after the variable/member name. returnName = name; ArrayType *a = dynamic_cast(t); @@ -2157,8 +2131,7 @@ string CGenerator::getTypenameName(DataType *t, const string &name) returnName = getTypenameName(a->getElementType(), returnName); break; } - case DataType::kBuiltinType: - { + case DataType::kBuiltinType: { assert(nullptr != dynamic_cast(t)); returnName = getBuiltinTypename(dynamic_cast(t)); if (!(t->isString() && name != "" && name[0] == '*')) @@ -2168,16 +2141,14 @@ string CGenerator::getTypenameName(DataType *t, const string &name) returnName += name; break; } - case DataType::kListType: - { + case DataType::kListType: { const ListType *a = dynamic_cast(t); assert(a); returnName = "* " + name; returnName = getTypenameName(a->getElementType(), returnName); break; } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *unionType = dynamic_cast(t); assert(unionType); if (unionType->isNonEncapsulatedUnion()) @@ -2193,8 +2164,7 @@ string CGenerator::getTypenameName(DataType *t, const string &name) } break; } - case DataType::kVoidType: - { + case DataType::kVoidType: { returnName = "void"; returnName += returnSpaceWhenNotEmpty(name) + name; break; @@ -2202,8 +2172,7 @@ string CGenerator::getTypenameName(DataType *t, const string &name) case DataType::kAliasType: case DataType::kEnumType: case DataType::kFunctionType: - case DataType::kStructType: - { + case DataType::kStructType: { returnName = getOutputName(t); returnName += returnSpaceWhenNotEmpty(name) + name; break; @@ -2243,6 +2212,8 @@ string CGenerator::getBuiltinTypename(const BuiltinType *t) return "double"; case BuiltinType::kStringType: return "char *"; + case BuiltinType::kUStringType: + return "unsigned char*"; case BuiltinType::kBinaryType: return "uint8_t *"; default: @@ -2294,6 +2265,7 @@ void CGenerator::getEncodeDecodeBuiltin(Group *group, BuiltinType *t, data_map & templateData["freeingCall"] = m_templateData["freeData"]; // needDealloc(templateData, t, structType, nullptr); templateData["builtinType"] = "kStringType"; + templateData["builtinTypeName"] = t->isUString() ? "unsigned char*" : "char*"; } else { @@ -2415,15 +2387,13 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT switch (t->getDataType()) { - case DataType::kAliasType: - { + case DataType::kAliasType: { AliasType *aliasType = dynamic_cast(t); assert(aliasType); return getEncodeDecodeCall(name, group, aliasType->getElementType(), structType, inDataContainer, structMember, needTempVariable, isFunctionParam); } - case DataType::kArrayType: - { + case DataType::kArrayType: { static uint8_t arrayCounter; ArrayType *arrayType = dynamic_cast(t); assert(arrayType); @@ -2456,13 +2426,11 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT --arrayCounter; break; } - case DataType::kBuiltinType: - { + case DataType::kBuiltinType: { getEncodeDecodeBuiltin(group, (BuiltinType *)t, templateData, structType, structMember, isFunctionParam); break; } - case DataType::kEnumType: - { + case DataType::kEnumType: { needTempVariable = true; templateData["decode"] = m_templateData["decodeEnumType"]; templateData["encode"] = m_templateData["encodeEnumType"]; @@ -2477,8 +2445,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT } break; } - case DataType::kFunctionType: - { + case DataType::kFunctionType: { FunctionType *funType = dynamic_cast(t); assert(funType); const FunctionType::c_function_list_t &callbacks = funType->getCallbackFuns(); @@ -2503,8 +2470,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT templateData["decode"] = m_templateData["decodeFunctionType"]; break; } - case DataType::kListType: - { + case DataType::kListType: { ListType *listType = dynamic_cast(t); assert(listType); DataType *elementType = listType->getElementType(); @@ -2648,8 +2614,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT structMember, needTempVariable, isFunctionParam); break; } - case DataType::kStructType: - { + case DataType::kStructType: { // needDealloc(templateData, t, structType, structMember); string typeName = getOutputName(t); if (typeName != "") @@ -2669,8 +2634,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT } break; } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *unionType = dynamic_cast(t); assert(unionType); @@ -2784,8 +2748,7 @@ data_map CGenerator::getEncodeDecodeCall(const string &name, Group *group, DataT } break; } - default: - { + default: { throw internal_error("unknown member type"); } } @@ -2920,32 +2883,27 @@ bool CGenerator::isNeedCallFree(DataType *dataType) DataType *trueDataType = dataType->getTrueDataType(); switch (trueDataType->getDataType()) { - case DataType::kArrayType: - { + case DataType::kArrayType: { ArrayType *arrayType = dynamic_cast(trueDataType); assert(arrayType); return isNeedCallFree(arrayType->getElementType()); } - case DataType::kBuiltinType: - { + case DataType::kBuiltinType: { BuiltinType *builtinType = dynamic_cast(trueDataType); assert(builtinType); return builtinType->isString() || builtinType->isBinary(); } - case DataType::kListType: - { + case DataType::kListType: { return true; } - case DataType::kStructType: - { + case DataType::kStructType: { StructType *structType = dynamic_cast(trueDataType); assert(structType); set loopDetection; return structType->containListMember() || structType->containStringMember() || containsByrefParamToFree(structType, loopDetection); } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *unionType = dynamic_cast(trueDataType); assert(unionType); for (auto unionCase : unionType->getCases()) @@ -2982,18 +2940,12 @@ void CGenerator::setCallingFreeFunctions(Symbol *symbol, data_map &info, bool re { if (!returnType) { - switch (trueDataType->getDataType()) + if (trueDataType->isStruct() || trueDataType->isUnion() || + (trueDataType->isFunction() && ((structMember->getDirection() == kOutDirection)))) { - case DataType::kStructType: - case DataType::kUnionType: - { - string name = getOutputName(structMember, false); - firstFreeingCall1["firstFreeingCall"] = m_templateData["freeData"]; - firstFreeingCall1["freeName"] = name; - break; - } - default: - break; + string name = getOutputName(structMember, false); + firstFreeingCall1["firstFreeingCall"] = m_templateData["freeData"]; + firstFreeingCall1["freeName"] = name; } } else @@ -3058,7 +3010,7 @@ data_map CGenerator::allocateCall(const string &name, Symbol *symbol) else { typeValue = "char"; - typePointerValue = "char *"; + typePointerValue = dataType->isUString() ? "unsigned char*" : "char *"; } alloc["name"] = name.c_str(); @@ -3086,14 +3038,12 @@ bool CGenerator::containsString(DataType *dataType) DataType *trueDataType = dataType->getTrueContainerDataType(); switch (trueDataType->getDataType()) { - case DataType::kStructType: - { + case DataType::kStructType: { StructType *s = dynamic_cast(trueDataType); assert(s); return s->containStringMember(); } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *u = dynamic_cast(trueDataType); assert(u); for (UnionCase *unionCase : u->getUniqueCases()) @@ -3112,8 +3062,7 @@ bool CGenerator::containsString(DataType *dataType) } return false; } - default: - { + default: { if (trueDataType->isString()) { return true; @@ -3132,14 +3081,12 @@ bool CGenerator::containsList(DataType *dataType) DataType *trueDataType = dataType->getTrueContainerDataType(); switch (trueDataType->getDataType()) { - case DataType::kStructType: - { + case DataType::kStructType: { StructType *s = dynamic_cast(trueDataType); assert(s); return s->containListMember(); } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *u = dynamic_cast(trueDataType); assert(u); for (UnionCase *unionCase : u->getUniqueCases()) @@ -3158,8 +3105,7 @@ bool CGenerator::containsList(DataType *dataType) } return false; } - default: - { + default: { return false; } } diff --git a/erpcgen/src/CGenerator.h b/erpcgen/src/CGenerator.h index c6c329f20..36c7e02a8 100644 --- a/erpcgen/src/CGenerator.h +++ b/erpcgen/src/CGenerator.h @@ -13,6 +13,7 @@ #include "Generator.h" #include "cpptempl.h" #include "types/Group.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/ErpcLexer.cpp b/erpcgen/src/ErpcLexer.cpp index 5ff096513..fd26dac1a 100644 --- a/erpcgen/src/ErpcLexer.cpp +++ b/erpcgen/src/ErpcLexer.cpp @@ -7,11 +7,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include "ErpcLexer.h" + #include "erpc_crc16.h" #include "erpc_version.h" + #include "Generator.h" #include "HexValues.h" #include "SearchPath.h" + #include #include #include @@ -76,16 +79,14 @@ int ErpcLexer::processStringEscapes(const char *in, char *out) { switch (*in) { - case '\\': - { + case '\\': { // start of an escape sequence char c = *++in; switch (c) { case 0: // end of the string, bail break; - case 'x': - { + case 'x': { // start of a hex char escape sequence // read high and low nibbles, checking for end of string diff --git a/erpcgen/src/ErpcLexer.h b/erpcgen/src/ErpcLexer.h index 2fa004cd0..c896217a1 100644 --- a/erpcgen/src/ErpcLexer.h +++ b/erpcgen/src/ErpcLexer.h @@ -16,6 +16,7 @@ #undef yyFlexLexer #include "AstNode.h" #include "ParseErrors.h" + #include #include #include @@ -161,8 +162,8 @@ class ErpcLexer : public yyFlexLexer protected: Value *m_value; /*!< Value for the current token. */ token_loc_t m_location; /*!< Location for the current token. */ - CurrentFileInfo *m_currentFileInfo; /*!< Pointer to current file info. */ uint32_t m_indents; /*!< How much indents can be removed from newlines in doxygen comments. */ + CurrentFileInfo *m_currentFileInfo; /*!< Pointer to current file info. */ uint16_t m_idlCrc16; /*!< Crc16 of IDL files. */ /*! diff --git a/erpcgen/src/Generator.cpp b/erpcgen/src/Generator.cpp index f088ad77d..8a278858b 100644 --- a/erpcgen/src/Generator.cpp +++ b/erpcgen/src/Generator.cpp @@ -8,11 +8,14 @@ */ #include "Generator.h" + #include "erpc_version.h" + #include "Logging.h" #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" + #include #include #include @@ -26,9 +29,9 @@ using namespace std; //////////////////////////////////////////////////////////////////////////////// Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType) -: m_def(def) +: m_idlCrc16(def->getIdlCrc16()) +, m_def(def) , m_globals(&(def->getGlobals())) -, m_idlCrc16(def->getIdlCrc16()) , m_generatorType(generatorType) { m_templateData["erpcVersion"] = ERPC_VERSION; @@ -134,14 +137,12 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType) // set codec information switch (m_def->getCodecType()) { - case InterfaceDefinition::kBasicCodec: - { + case InterfaceDefinition::kBasicCodec: { m_templateData["codecClass"] = "BasicCodec"; m_templateData["codecHeader"] = "erpc_basic_codec.h"; break; } - default: - { + default: { m_templateData["codecClass"] = "Codec"; m_templateData["codecHeader"] = "erpc_codec.h"; break; @@ -298,8 +299,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat switch (dataType->getDataType()) { - case DataType::kAliasType: - { + case DataType::kAliasType: { AliasType *aliasType = dynamic_cast(dataType); if (aliasType != nullptr) { @@ -307,8 +307,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat } break; } - case DataType::kArrayType: - { + case DataType::kArrayType: { ArrayType *arrayType = dynamic_cast(dataType); if (arrayType != nullptr) { @@ -316,8 +315,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat } break; } - case DataType::kListType: - { + case DataType::kListType: { ListType *listType = dynamic_cast(dataType); if (listType != nullptr) { @@ -325,8 +323,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat } break; } - case DataType::kStructType: - { + case DataType::kStructType: { StructType *structType = dynamic_cast(dataType); if (structType != nullptr) { @@ -337,8 +334,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat } break; } - case DataType::kUnionType: - { + case DataType::kUnionType: { // Keil need extra pragma option when unions are used. m_templateData["usedUnionType"] = true; UnionType *unionType = dynamic_cast(dataType); @@ -351,8 +347,7 @@ DataType *Generator::findChildDataType(set &dataTypes, DataType *dat } break; } - default: - { + default: { break; } } @@ -430,7 +425,7 @@ data_list Generator::makeGroupInterfacesTemplateData(Group *group) data_list functions = getFunctionsTemplateData(group, iface); ifaceInfo["functions"] = functions; ifaceInfo["isNonExternalInterface"] = false; - for (int i = 0; i < functions.size(); ++i) + for (unsigned int i = 0; i < functions.size(); ++i) { assert(dynamic_cast(functions[i].get().get())); string isNonExternalFunction = diff --git a/erpcgen/src/Generator.h b/erpcgen/src/Generator.h index 52c5835f6..0da93eeda 100644 --- a/erpcgen/src/Generator.h +++ b/erpcgen/src/Generator.h @@ -28,6 +28,7 @@ #include "types/StructType.h" #include "types/UnionType.h" #include "types/VoidType.h" + #include #include @@ -175,7 +176,7 @@ class Generator * * @param[in] structMember Structure member, Function parameter or Union member. */ - virtual void setBinaryList(StructMember *structMember){}; + virtual void setBinaryList(StructMember *structMember) { (void)structMember; }; /*! * @brief This function sets group symbols template data. diff --git a/erpcgen/src/HexValues.cpp b/erpcgen/src/HexValues.cpp index 950d27f54..da6ab78e1 100644 --- a/erpcgen/src/HexValues.cpp +++ b/erpcgen/src/HexValues.cpp @@ -8,6 +8,7 @@ */ #include "HexValues.h" + #include bool isHexDigit(char c) diff --git a/erpcgen/src/InterfaceDefinition.cpp b/erpcgen/src/InterfaceDefinition.cpp index 88b641f03..6ecde745e 100644 --- a/erpcgen/src/InterfaceDefinition.cpp +++ b/erpcgen/src/InterfaceDefinition.cpp @@ -8,6 +8,7 @@ */ #include "InterfaceDefinition.h" + #include "AstNode.h" #include "AstWalker.h" #include "ErpcLexer.h" @@ -29,10 +30,10 @@ using namespace std; InterfaceDefinition::InterfaceDefinition() : m_ast(nullptr) , m_globals() +, m_program(nullptr) , m_programName("") , m_outputFilename("") , m_codec(kNotSpecified) -, m_program(nullptr) { init(); } @@ -83,6 +84,7 @@ void InterfaceDefinition::createBuiltinTypes() m_globals.addSymbol(new BuiltinType("float", BuiltinType::_builtin_type::kFloatType)); m_globals.addSymbol(new BuiltinType("double", BuiltinType::_builtin_type::kDoubleType)); m_globals.addSymbol(new BuiltinType("string", BuiltinType::_builtin_type::kStringType)); + m_globals.addSymbol(new BuiltinType("ustring", BuiltinType::_builtin_type::kUStringType)); m_globals.addSymbol(new BuiltinType("binary", BuiltinType::_builtin_type::kBinaryType)); } diff --git a/erpcgen/src/InterfaceDefinition.h b/erpcgen/src/InterfaceDefinition.h index 5c147d40c..60a34a777 100644 --- a/erpcgen/src/InterfaceDefinition.h +++ b/erpcgen/src/InterfaceDefinition.h @@ -13,6 +13,7 @@ #include "AstNode.h" #include "types/Program.h" #include "types/SymbolScope.h" + #include #include diff --git a/erpcgen/src/Logging.cpp b/erpcgen/src/Logging.cpp index 1ad5bd0c6..8cd18cc2e 100644 --- a/erpcgen/src/Logging.cpp +++ b/erpcgen/src/Logging.cpp @@ -8,6 +8,7 @@ */ #include "Logging.h" + #include #include #include diff --git a/erpcgen/src/ParseErrors.h b/erpcgen/src/ParseErrors.h index 8dd2a66a7..a1372b9f3 100644 --- a/erpcgen/src/ParseErrors.h +++ b/erpcgen/src/ParseErrors.h @@ -13,6 +13,7 @@ #include "Logging.h" #include "Token.h" #include "os_config.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/PythonGenerator.cpp b/erpcgen/src/PythonGenerator.cpp index 755195c76..0fe7c4202 100644 --- a/erpcgen/src/PythonGenerator.cpp +++ b/erpcgen/src/PythonGenerator.cpp @@ -8,10 +8,12 @@ */ #include "PythonGenerator.h" + #include "Logging.h" #include "ParseErrors.h" #include "annotations.h" #include "format_string.h" + #include #include #include @@ -65,7 +67,7 @@ void PythonGenerator::generateInitFile(string fileName) { fileName += "/__init__.py"; generateOutputFile(fileName, "py_init", m_templateData, kPyInit); -}; +} void PythonGenerator::generateCommonFile(string fileName) { @@ -136,7 +138,7 @@ void PythonGenerator::generate() makeIncludesTemplateData(); - makeAliasesTemplateData(); + // makeAliasesTemplateData(); makeConstTemplateData(); @@ -167,6 +169,7 @@ void PythonGenerator::setTemplateComments(Symbol *symbol, data_map &symbolInfo) data_map PythonGenerator::getFunctionTemplateData(Group *group, Function *fn) { + (void)group; data_map info; string proto = getFunctionPrototype(fn); @@ -407,6 +410,7 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) data_list structs; data_list unions; + data_list aliases; Log::info("Group symbols:\n"); @@ -417,8 +421,7 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) switch (symbol->getSymbolType()) { - case DataType::kStructTypeSymbol: - { + case DataType::kStructTypeSymbol: { StructType *structType = dynamic_cast(symbol); if (structType == nullptr) { @@ -442,8 +445,7 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) } break; } - case DataType::kUnionTypeSymbol: - { + case DataType::kUnionTypeSymbol: { UnionType *unionType = dynamic_cast(symbol); if (unionType == nullptr) { @@ -453,6 +455,11 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) Log::info("%s\n", unionType->getDescription().c_str()); string name = filterName(getOutputName(unionType)); + if (name.find('$') != string::npos) + { + Log::debug("%s is inside struct!\n", name.c_str()); + break; + } // check if template for this structure has not already been generated if (names.find(name) == names.end()) @@ -468,6 +475,29 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) } break; } + case DataType::kAliasTypeSymbol: { + AliasType *aliasType = dynamic_cast(symbol); + if (aliasType == nullptr) + break; + + DataType *elementDataType = aliasType->getElementType(); + DataType *trueDataType = elementDataType->getTrueDataType(); + // Only generate aliases for enums, unions and structs in Python. + if (!(trueDataType->isEnum() || trueDataType->isUnion() || trueDataType->isStruct())) + break; + + string realType = getOutputName(aliasType); + Log::debug("%s\n", realType.c_str()); + + info["name"] = filterName(realType); + info["elementType"] = getTypeInfo(elementDataType); + info["trueType"] = getTypeInfo(trueDataType); + + setTemplateComments(aliasType, info); + + aliases.push_back(info); + break; + } default: break; } @@ -475,6 +505,7 @@ data_map PythonGenerator::makeGroupSymbolsTemplateData(Group *group) symbolsTemplate["structs"] = structs; symbolsTemplate["unions"] = unions; + symbolsTemplate["aliases"] = aliases; return symbolsTemplate; } @@ -566,13 +597,11 @@ data_map PythonGenerator::getTypeInfo(DataType *t) info["isNonEncapsulatedUnion"] = false; switch (t->getDataType()) { - case DataType::kAliasType: - { + case DataType::kAliasType: { info = getTypeInfo(t->getTrueDataType()); break; } - case DataType::kArrayType: - { + case DataType::kArrayType: { // Array type requires the array element count to come after the variable/member name. ArrayType *a = dynamic_cast(t); assert(a); @@ -581,19 +610,16 @@ data_map PythonGenerator::getTypeInfo(DataType *t) info["elementType"] = getTypeInfo(a->getElementType()); break; } - case DataType::kBuiltinType: - { + case DataType::kBuiltinType: { assert(dynamic_cast(t)); info["type"] = getBuiltinTypename(dynamic_cast(t)); break; } - case DataType::kEnumType: - { + case DataType::kEnumType: { info["type"] = "enum"; break; } - case DataType::kFunctionType: - { + case DataType::kFunctionType: { info["type"] = "function"; FunctionType *funType = dynamic_cast(t); assert(funType); @@ -615,21 +641,18 @@ data_map PythonGenerator::getTypeInfo(DataType *t) } break; } - case DataType::kListType: - { + case DataType::kListType: { const ListType *a = dynamic_cast(t); assert(a); info["type"] = "list"; info["elementType"] = getTypeInfo(a->getElementType()); break; } - case DataType::kStructType: - { + case DataType::kStructType: { info["type"] = "struct"; break; } - case DataType::kUnionType: - { + case DataType::kUnionType: { UnionType *unionType = dynamic_cast(t); assert(unionType); info["type"] = "union"; @@ -697,8 +720,7 @@ data_map PythonGenerator::getTypeInfo(DataType *t) info["cases"] = unionCases; break; } - case DataType::kVoidType: - { + case DataType::kVoidType: { info["type"] = "void"; break; } @@ -759,6 +781,7 @@ string PythonGenerator::filterName(const string &name) string PythonGenerator::convertComment(const string &comment, comment_type commentType) { + (void)commentType; // Longer patterns are ordered earlier than similar shorter patterns. static const char *const kCommentBegins[] = { "//!<", "//!", "///<", "///", "/*!<", "/*!", "/**<", "/**", 0 }; static const char *const kCommentEnds[] = { "*/", 0 }; @@ -875,11 +898,11 @@ string PythonGenerator::stripWhitespace(const string &s) uint32_t n; // Strip leading whitespace. - for (n = 0, i = 0; i < result.size(); ++i, ++n) + for (n = 0, i = 0; i < (int)result.size(); ++i, ++n) { char c = result[i]; - if ((i < result.size() - 1 && c == ' ' && !checkWhitspaceChar(result[i + 1])) || !checkWhitspaceChar(c)) + if ((i < (int)result.size() - 1 && c == ' ' && !checkWhitspaceChar(result[i + 1])) || !checkWhitspaceChar(c)) { break; } @@ -890,7 +913,7 @@ string PythonGenerator::stripWhitespace(const string &s) } // Strip trailing whitespace. - for (n = 0, i = result.size() - 1; i > 0; --i, ++n) + for (n = 0, i = (int)result.size() - 1; i > 0; --i, ++n) { char c = result[i]; if (!checkWhitspaceChar(c)) diff --git a/erpcgen/src/PythonGenerator.h b/erpcgen/src/PythonGenerator.h index 6dc1d50c7..2cf51bfb9 100644 --- a/erpcgen/src/PythonGenerator.h +++ b/erpcgen/src/PythonGenerator.h @@ -12,6 +12,7 @@ #include "Generator.h" #include "cpptempl.h" + #include #include diff --git a/erpcgen/src/SearchPath.cpp b/erpcgen/src/SearchPath.cpp index b60894f5f..c03565e03 100644 --- a/erpcgen/src/SearchPath.cpp +++ b/erpcgen/src/SearchPath.cpp @@ -8,6 +8,7 @@ */ #include "SearchPath.h" + #include #if __WIN32__ @@ -64,6 +65,7 @@ void PathSearcher::setTempPath(const std::string &path) //! \retval false No match could be made. \a result has been left unmodified. bool PathSearcher::search(const std::string &base, target_type_t targetType, bool searchCwd, std::string &result) { + (void)targetType; FILE *tempFile; bool absolute = isAbsolute(base); diff --git a/erpcgen/src/SymbolScanner.cpp b/erpcgen/src/SymbolScanner.cpp index ccf56b3d6..9ff18b484 100644 --- a/erpcgen/src/SymbolScanner.cpp +++ b/erpcgen/src/SymbolScanner.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * Copyright (c) 2020 Texas Instruments Incorporated * All rights reserved. * * @@ -8,6 +9,7 @@ */ #include "SymbolScanner.h" + #include "ErpcLexer.h" #include "Logging.h" #include "annotations.h" @@ -18,6 +20,7 @@ #include "types/FunctionType.h" #include "types/ListType.h" #include "types/VoidType.h" + #include #include @@ -29,6 +32,7 @@ using namespace std; //////////////////////////////////////////////////////////////////////////////// void SymbolScanner::handleRoot(AstNode *node, bottom_up) { + (void)node; if (m_forwardDeclarations.size() != 0) { string forwardTypes; @@ -772,7 +776,7 @@ AstNode *SymbolScanner::handleUnion(AstNode *node, top_down) string unionVariableName = node->getParent()->getChild(0)->getToken().getStringValue(); /* Create a new node in the AST for the union's name, and assign it */ - node->appendChild(new AstNode(Token(TOK_IDENT, new StringValue(unionVariableName + "_$union")))); + node->appendChild(new AstNode(Token(TOK_IDENT, new StringValue(unionVariableName + "_union")))); /* union token. */ tok = &node->getChild(3)->getToken(); @@ -858,6 +862,7 @@ AstNode *SymbolScanner::handleUnion(AstNode *node, bottom_up) AstNode *SymbolScanner::handleUnionCase(AstNode *node, top_down) { + (void)node; return nullptr; } @@ -1135,7 +1140,7 @@ AstNode *SymbolScanner::handleFunction(AstNode *node, bottom_up) const StructType::member_vector_t &callbackParams = callbackFunctionType->getParameters().getMembers(); if (callbackFunctionType->getParameters().getMembers().size() > paramsSize) { - for (int i = paramsSize; i < callbackParams.size(); ++i) + for (unsigned int i = paramsSize; i < callbackParams.size(); ++i) { if (callbackParams[i]->getName().compare("") == 0) { @@ -1302,6 +1307,7 @@ void SymbolScanner::setParameterDirection(StructMember *param, AstNode *directio AstNode *SymbolScanner::handleExpr(AstNode *node, bottom_up) { + (void)node; /* Log::debug("expr: %s\n", node->getDescription().c_str()); */ return nullptr; } @@ -1350,8 +1356,7 @@ DataType *SymbolScanner::lookupDataType(const AstNode *typeNode) case TOK_LIST: return createListType(typeNode); - case TOK_UNION: - { + case TOK_UNION: { assert(nullptr != m_currentStruct); return lookupDataTypeByName(typeNode->getChild(3)->getToken(), &(m_currentStruct->getScope()), false); break; @@ -1480,7 +1485,7 @@ void SymbolScanner::addAnnotations(AstNode *childNode, Symbol *symbol) string nameOfType; if (childNode->getParent()->getChild(0)) { - string nameOfType = childNode->getParent()->getChild(0)->getToken().getStringValue(); + nameOfType = childNode->getParent()->getChild(0)->getToken().getStringValue(); Log::log("Handling annotations for %s\n", nameOfType.c_str()); } else diff --git a/erpcgen/src/Token.cpp b/erpcgen/src/Token.cpp index 9d36e92d5..f6b09672a 100644 --- a/erpcgen/src/Token.cpp +++ b/erpcgen/src/Token.cpp @@ -8,6 +8,7 @@ */ #include "Token.h" + #include "ErpcLexer.h" #include "ParseErrors.h" diff --git a/erpcgen/src/UniqueIdChecker.cpp b/erpcgen/src/UniqueIdChecker.cpp index 3f39fdebe..c8be73388 100644 --- a/erpcgen/src/UniqueIdChecker.cpp +++ b/erpcgen/src/UniqueIdChecker.cpp @@ -8,6 +8,7 @@ */ #include "UniqueIdChecker.h" + #include "Annotation.h" #include "Logging.h" #include "ParseErrors.h" @@ -60,7 +61,7 @@ void UniqueIdChecker::initUsedInterfaceIds(SymbolScope::symbol_vector_t ifaces) { if (0 < ifaces.size()) { - for (int i = 0; i < ifaces.size(); ++i) + for (unsigned int i = 0; i < ifaces.size(); ++i) { Interface *iface = dynamic_cast(ifaces[i]); assert(iface); @@ -75,7 +76,7 @@ void UniqueIdChecker::initUsedFunctionIds(Interface *iface) Interface::function_vector_t functions = iface->getFunctions(); if (0 < functions.size()) { - for (int i = 0; i < functions.size(); ++i) + for (unsigned int i = 0; i < functions.size(); ++i) { m_usedFunctionIds.push_back(make_pair(functions[i]->getUniqueId(), functions[i]->getName())); } @@ -98,7 +99,7 @@ void UniqueIdChecker::setInterfaceId(Interface *iface, Annotation *interfaceId) format_string("@id value for interface %s must be greater than zero", iface->getName().c_str())); } iface->setUniqueId(newIdValue); - for (int i = 0; i < m_usedInterfaceIds.size(); ++i) + for (unsigned int i = 0; i < m_usedInterfaceIds.size(); ++i) { if (0 == m_usedInterfaceIds[i].second.compare(iface->getName())) { @@ -132,7 +133,7 @@ void UniqueIdChecker::setFunctionId(Function *fn, Annotation *idAnnotation) printf("%d: \n",i, usedFunctionIds[i].first, usedFunctionIds[i].second.c_str()); } */ - for (int i = 0; i < m_usedFunctionIds.size(); ++i) + for (unsigned int i = 0; i < m_usedFunctionIds.size(); ++i) { // printf("usedFunctionIds at i: %s\t", usedFunctionIds[i].second.c_str()); // printf("fn name: %s\n", fn->getName().c_str()); diff --git a/erpcgen/src/UniqueIdChecker.h b/erpcgen/src/UniqueIdChecker.h index 518f96a78..c4e6b131d 100644 --- a/erpcgen/src/UniqueIdChecker.h +++ b/erpcgen/src/UniqueIdChecker.h @@ -9,16 +9,16 @@ #ifndef _EMBEDDED_RPC__UNIQUEIDCHECKER_H_ #define _EMBEDDED_RPC__UNIQUEIDCHECKER_H_ +#include "Interface.h" +#include "InterfaceDefinition.h" +#include "SymbolScope.h" + #include #include #include #include #include -#include "Interface.h" -#include "InterfaceDefinition.h" -#include "SymbolScope.h" - //////////////////////////////////////////////////////////////////////////////// // Classes //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/Value.h b/erpcgen/src/Value.h index ac13a971a..2774061a1 100644 --- a/erpcgen/src/Value.h +++ b/erpcgen/src/Value.h @@ -10,10 +10,16 @@ #define _Value_h_ #include "format_string.h" + #include #include -typedef enum { kIntegerValue, kStringValue, kFloatValue } value_type_t; /*!< Value types */ +typedef enum +{ + kIntegerValue, + kStringValue, + kFloatValue +} value_type_t; /*!< Value types */ /*! * @brief Abstract base class for values of arbitrary types. @@ -82,7 +88,13 @@ class IntegerValue : public Value { public: //! Supported sizes of integers. - typedef enum { kSigned, kSignedLong, kUnsigned, kUnsignedLong } int_type_t; //!< The integer type. + typedef enum + { + kSigned, + kSignedLong, + kUnsigned, + kUnsignedLong + } int_type_t; //!< The integer type. /*! * @brief Constructor. diff --git a/erpcgen/src/cpptemplate/Makefile b/erpcgen/src/cpptemplate/Makefile index 2bd8f0bf9..0c8efb39e 100644 --- a/erpcgen/src/cpptemplate/Makefile +++ b/erpcgen/src/cpptemplate/Makefile @@ -33,6 +33,7 @@ LIBRARIES = -lc -lstdc++ -lm -lboost_unit_test_framework-mt -L$(BOOST_ROOT)/lib INCLUDES = -I$(BOOST_ROOT)/include CXXFLAGS = -std=gnu++11 -Werror -g3 -O0 -MMD -MP $(INCLUDES) +CXXFLAGS += -Wall -Wextra -Wshadow -pedantic-errors .PHONY: all all: cpptempl_test diff --git a/erpcgen/src/cpptemplate/cpptempl.cpp b/erpcgen/src/cpptemplate/cpptempl.cpp index 0830a3195..5cbb00917 100644 --- a/erpcgen/src/cpptemplate/cpptempl.cpp +++ b/erpcgen/src/cpptemplate/cpptempl.cpp @@ -521,6 +521,7 @@ bool DataBool::empty() } void DataBool::dump(int indent) { + (void)indent; std::cout << "(bool)" << getvalue() << std::endl; } int DataBool::getint() const @@ -540,6 +541,7 @@ bool DataInt::empty() } void DataInt::dump(int indent) { + (void)indent; std::cout << "(int)" << m_value << std::endl; } int DataInt::getint() const @@ -561,6 +563,7 @@ int DataValue::getint() const } void DataValue::dump(int indent) { + (void)indent; std::string text = boost::algorithm::replace_all_copy(getvalue(), "\n", "\\n"); std::cout << "\"" << text << "\"" << std::endl; } @@ -624,6 +627,7 @@ bool DataTemplate::empty() void DataTemplate::dump(int indent) { + (void)indent; std::cout << "(template)\n"; } @@ -794,7 +798,7 @@ const KeywordDef k_keywords[] = { { TRUE_TOKEN, "true" }, { FALSE_TOKEN, "fa { ELSE_TOKEN, "else" }, { DEF_TOKEN, "def" }, { SET_TOKEN, "set" }, { ENDFOR_TOKEN, "endfor" }, { ENDIF_TOKEN, "endif" }, { ENDDEF_TOKEN, "enddef" }, { AND_TOKEN, "and" }, { OR_TOKEN, "or" }, { NOT_TOKEN, "not" }, - { INVALID_TOKEN } }; + { INVALID_TOKEN, NULL } }; TokenType get_keyword_token(const std::string &s) { @@ -1578,7 +1582,7 @@ void NodeVar::gettext(std::ostream &stream, data_map &data) stream << str; } - catch (TemplateException e) + catch (TemplateException &e) { e.set_line_if_missing(get_line()); throw e; @@ -1686,7 +1690,7 @@ void NodeFor::gettext(std::ostream &stream, data_map &data) // ignore exception - the for loop key variable doesn't exist, so just // don't execute the for loop at all } - catch (TemplateException e) + catch (TemplateException &e) { e.set_line_if_missing(get_line()); throw e; @@ -1760,7 +1764,7 @@ bool NodeIf::is_true(data_map &data) return !d->empty(); } - catch (TemplateException e) + catch (TemplateException &e) { e.set_line_if_missing(get_line()); throw e; @@ -1806,6 +1810,7 @@ NodeType NodeDef::gettype() void NodeDef::gettext(std::ostream &stream, data_map &data) { + (void)stream; // Follow the key path. data_ptr &target = data.parse_path(m_name, true); @@ -1825,6 +1830,7 @@ NodeType NodeSet::gettype() void NodeSet::gettext(std::ostream &stream, data_map &data) { + (void)stream; TokenIterator tok(m_expr); tok.match(SET_TOKEN, "expected 'set'"); std::string path = tok.match(KEY_PATH_TOKEN, "expected key path")->get_value(); @@ -1929,7 +1935,7 @@ node_vector &TemplateParser::parse() return m_top_nodes; } - catch (TemplateException e) + catch (TemplateException &e) { e.set_line_if_missing(m_current_line); throw e; diff --git a/erpcgen/src/cpptemplate/unit_testing.h b/erpcgen/src/cpptemplate/unit_testing.h index bcd6d9bed..47a9dd28b 100644 --- a/erpcgen/src/cpptemplate/unit_testing.h +++ b/erpcgen/src/cpptemplate/unit_testing.h @@ -29,6 +29,7 @@ #else #include "windows.h" #include "winnls.h" // unicode-multibyte conversion + #include #endif diff --git a/erpcgen/src/erpcgen.cpp b/erpcgen/src/erpcgen.cpp index 326d4ee86..4aa68ef38 100644 --- a/erpcgen/src/erpcgen.cpp +++ b/erpcgen/src/erpcgen.cpp @@ -8,6 +8,7 @@ */ #include "erpc_version.h" + #include "CGenerator.h" #include "ErpcLexer.h" #include "InterfaceDefinition.h" @@ -17,6 +18,7 @@ #include "UniqueIdChecker.h" #include "options.h" #include "types/Program.h" + #include #include #include @@ -40,7 +42,7 @@ const char k_toolName[] = "erpcgen"; const char k_version[] = ERPC_VERSION; /*! Copyright string. */ -const char k_copyright[] = "Copyright 2016-2018 NXP. All rights reserved."; +const char k_copyright[] = "Copyright 2016-2020 NXP. All rights reserved."; static const char *k_optionsDefinition[] = { "?|help", "V|version", @@ -191,8 +193,7 @@ class erpcgenTool PathSearcher::getGlobalSearcher().addSearchPath(optarg); break; - case 'g': - { + case 'g': { string lang = optarg; if (lang == "c") { @@ -210,8 +211,7 @@ class erpcgenTool break; } - case 'c': - { + case 'c': { string codec = optarg; if (codec.compare("basic") == 0) { @@ -381,6 +381,7 @@ class erpcgenTool */ int main(int argc, char *argv[], char *envp[]) { + (void)envp; try { return erpcgen::erpcgenTool(argc, argv).run(); diff --git a/erpcgen/src/erpcgen_lexer.l b/erpcgen/src/erpcgen_lexer.l index f7166b85c..b3aff1243 100644 --- a/erpcgen/src/erpcgen_lexer.l +++ b/erpcgen/src/erpcgen_lexer.l @@ -210,7 +210,7 @@ void { return TOK_VOID; } } } - if (yyleng > m_indents) // remove indent spaces + if (yyleng > (int)m_indents) // remove indent spaces { yytext += m_indents; yyleng -= m_indents; diff --git a/erpcgen/src/erpcgen_parser.y b/erpcgen/src/erpcgen_parser.y index bbf4bba95..9362db249 100644 --- a/erpcgen/src/erpcgen_parser.y +++ b/erpcgen/src/erpcgen_parser.y @@ -1244,6 +1244,7 @@ static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ErpcLexer * lexer) static void yyerror(YYLTYPE * yylloc, ErpcLexer * lexer, AstNode ** resultAST, const char * error) { + (void)resultAST; throw syntax_error(format_string("file %s:%d:%d: %s\n", lexer->getFileName().c_str(), yylloc->m_firstLine, yylloc->m_firstChar, error)); } diff --git a/erpcgen/src/format_string.cpp b/erpcgen/src/format_string.cpp index a5fb078e9..694c39079 100644 --- a/erpcgen/src/format_string.cpp +++ b/erpcgen/src/format_string.cpp @@ -8,7 +8,9 @@ */ #include "format_string.h" + #include "smart_ptr.h" + #include #include #include diff --git a/erpcgen/src/options.cpp b/erpcgen/src/options.cpp index 485dc2dd7..be73c3896 100644 --- a/erpcgen/src/options.cpp +++ b/erpcgen/src/options.cpp @@ -40,12 +40,12 @@ // - Added PARSE_POS control flag and POSITIONAL return value. // ^^************************************************************************** +#include "options.h" + #include #include #include -#include "options.h" - using namespace std; // static const char indent[] = "@(#)Options 1.05" ; @@ -159,10 +159,10 @@ void OptArgvIter::rewind(void) static const char WHITESPACE[] = " \t\n\r\v\f"; const char *OptStrTokIter::default_delims = WHITESPACE; -OptStrTokIter::OptStrTokIter(const char *tokens, const char *delimiters) +OptStrTokIter::OptStrTokIter(const char *tokens, const char *arg_delimiters) : len(unsigned(strlen(tokens))) , str(tokens) -, seps(delimiters) +, seps(arg_delimiters) , cur(NULLSTR) , tokstr(NULLSTR) { @@ -203,7 +203,7 @@ void OptStrTokIter::rewind(void) cur = ::strtok(tokstr, seps); } - // ************************************************************* OptIstreamIter +// ************************************************************* OptIstreamIter #ifdef vms enum @@ -633,7 +633,7 @@ unsigned OptionSpec::Format(char *buf, unsigned optctrls) const #endif /* USE_STDIO */ } - // ******************************************************************* Options +// ******************************************************************* Options #if (defined(MSWIN) || defined(OS2) || defined(MSDOS)) #define DIR_SEP_CHAR '\\' @@ -641,13 +641,13 @@ unsigned OptionSpec::Format(char *buf, unsigned optctrls) const #define DIR_SEP_CHAR '/' #endif -Options::Options(const char *name, const char *const optv[]) +Options::Options(const char *arg_name, const char *const optv[]) : explicit_end(0) , optctrls(DEFAULT) , optvec(optv) , nextchar(NULLSTR) , listopt(NULLSTR) -, cmdname(name) +, cmdname(arg_name) { const char *basename = ::strrchr(cmdname, DIR_SEP_CHAR); if (basename) diff --git a/erpcgen/src/templates/c_client_source.template b/erpcgen/src/templates/c_client_source.template index 050cedd1b..63ccc2fef 100644 --- a/erpcgen/src/templates/c_client_source.template +++ b/erpcgen/src/templates/c_client_source.template @@ -47,6 +47,14 @@ extern ClientManager *g_client; {% if fn.returnValue.type.isNotVoid %} {$fn.returnValue.resultVariable}{% if fn.returnValue.isNullReturnType %} = NULL{%endif%}; +#if ERPC_PRE_POST_ACTION + pre_post_action_cb preCB = g_client->getPreCB(); + if (preCB) + { + preCB(); + } +#endif + {% endif -- isNotVoid %} // Get a new request. {% if !fn.isReturnValue %} @@ -132,6 +140,15 @@ extern ClientManager *g_client; g_client->callErrorHandler(err, {$functionIDName}); {% endif -- generateErrorChecks %} {% if generateErrorChecks && fn.returnValue.type.isNotVoid %} + +#if ERPC_PRE_POST_ACTION + pre_post_action_cb postCB = g_client->getPostCB(); + if (postCB) + { + postCB(); + } +#endif + {% if empty(fn.returnValue.errorReturnValue) == false && fn.returnValue.isNullReturnType == false %} if (err) @@ -164,8 +181,6 @@ static {$callbackType.prototype} { {% if fn.isCallback %} {% if fn.returnValue.type.isNotVoid %}return {% endif %}{$fn.callbackFName}(k{$iface.name}_service_id, k{$iface.name}_{$fn.name}_id{% for param in fn.parameters %}, {$param.name}{% endfor %}); -{% if fn.returnValue.type.isNotVoid %}return; -{% endif %} {% else -- fn.isCallback >%} {$ clientShimCode(fn, "k"& iface.name & "_service_id", "k" & iface.name & "_" & fn.name & "_id") >} {% endif -- fn.isCallback >%} diff --git a/erpcgen/src/templates/c_coders.template b/erpcgen/src/templates/c_coders.template index 6ffcad07c..5f43a9613 100644 --- a/erpcgen/src/templates/c_coders.template +++ b/erpcgen/src/templates/c_coders.template @@ -4,7 +4,7 @@ uint32_t {$info.stringLocalName}_len; char * {$info.stringLocalName}_local; codec->readString(&{$info.stringLocalName}_len, &{$info.stringLocalName}_local); {% if ((source == "client" && info.withoutAlloc == false) or source == "server") %} -{$info.name} = (char *) erpc_malloc(({$info.stringAllocSize} + 1) * sizeof(char)); +{$info.name} = ({$info.builtinTypeName}) erpc_malloc(({$info.stringAllocSize} + 1) * sizeof(char)); {% if generateAllocErrorChecks == true %} if ({$info.name} == NULL) { @@ -232,7 +232,7 @@ codec->readData({$info.name}, {$info.sizeTemp} * sizeof({$info.builtinTypeName}) {# Encode sending data #} {% def encodeBuiltinType(info) ----------------- %} {% if info.builtinType == "kStringType" %} -codec->writeString(strlen({$info.name}), {$info.name}); +codec->writeString(strlen((const char*){$info.name}), (const char*){$info.name}); {% else %} {% if source == "client" && info.pointerScalarTypes %} codec->write(*{$info.name}); diff --git a/erpcgen/src/templates/c_common_header.template b/erpcgen/src/templates/c_common_header.template index 0e93542af..77b0c9a67 100644 --- a/erpcgen/src/templates/c_common_header.template +++ b/erpcgen/src/templates/c_common_header.template @@ -8,7 +8,7 @@ #define {$commonGuardMacro} {% if usedUnionType %} -#if defined(__CC_ARM) +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) #pragma anon_unions #endif {% endif -- usedUnionType %} @@ -129,7 +129,7 @@ extern "C" { {$> fn.mlComment} {$fn.prototype};{$fn.ilComment}{$loop.addNewLineIfNotLast} {% endfor -- functions %} -//@} {$iface.ilComment} +//@}{$iface.ilComment} {% endfor -- iface %} #if defined(__cplusplus) diff --git a/erpcgen/src/templates/c_server_header.template b/erpcgen/src/templates/c_server_header.template index 71098a496..52e2aba24 100644 --- a/erpcgen/src/templates/c_server_header.template +++ b/erpcgen/src/templates/c_server_header.template @@ -50,6 +50,12 @@ typedef void * erpc_service_t; {% for iface in group.interfaces %} erpc_service_t create_{$iface.serviceClassName}(void); +{% if dynamicServices == true %} +void destroy_{$iface.serviceClassName}(erpc_service_t *service); +{% else --dynamicServices == true %} +void destroy_{$iface.serviceClassName}(void); +{% endif --dynamicServices == true %} + {% endfor -- iface %} #ifdef __cplusplus } diff --git a/erpcgen/src/templates/c_server_source.template b/erpcgen/src/templates/c_server_source.template index 68d842c30..a7b427ce3 100644 --- a/erpcgen/src/templates/c_server_source.template +++ b/erpcgen/src/templates/c_server_source.template @@ -240,11 +240,24 @@ erpc_service_t create_{$iface.serviceClassName}() { return new (nothrow) {$iface.serviceClassName}(); } + +void destroy_{$iface.serviceClassName}(erpc_service_t *service) +{ + if (*service) + { + delete service; + } +} {% else --dynamicServices == true %} erpc_service_t create_{$iface.serviceClassName}() { s_{$iface.serviceClassName}.construct(); return s_{$iface.serviceClassName}.get(); } + +void destroy_{$iface.serviceClassName}() +{ + s_{$iface.serviceClassName}.destroy(); +} {% endif --dynamicServices == true %} {% endfor -- iface %} diff --git a/erpcgen/src/templates/py_client.template b/erpcgen/src/templates/py_client.template index a9bdfd5ee..1c9824419 100644 --- a/erpcgen/src/templates/py_client.template +++ b/erpcgen/src/templates/py_client.template @@ -61,7 +61,11 @@ class {$iface.name}Client(interface.I{$iface.name}): {% if p.type.type == 'union' %} {$p.name}._write(codec, {$p.discriminator}) {% else%} +{% if p.direction == "inout" %} + {$encodeValue(p.type, p.name & ".value", "codec", " ", 0)} +{% else %} {$encodeValue(p.type, p.name, "codec", " ", 0)} +{% endif -- p.direction %} {% endif -- isUnion %} {% endif -- isNullable %} {% endfor -- inParams %} diff --git a/erpcgen/src/templates/py_coders.template b/erpcgen/src/templates/py_coders.template index 60b5760fe..b123284f3 100644 --- a/erpcgen/src/templates/py_coders.template +++ b/erpcgen/src/templates/py_coders.template @@ -11,7 +11,7 @@ {% else %} {% set self = "self." %} {% endif %} -codec.start_write_union({$self}discriminator) +codec.start_write_union({$self}{$info.discriminatorName}) {# unions are always within structs, so we have self available #} {% set isFirst = true %} {% set hasNonVoidCase = false %} @@ -80,7 +80,7 @@ codec.start_write_union({$self}discriminator) {#--------------- function ---------------#} {% elif info.type == "function" %} {% if info.tableName != "" %} -{$codec}.write_int32({$ info.tableName}.index({$name})){%>%} +{$codec}.write_int8({$ info.tableName}.index({$name})){%>%} {% else %} # When are defined less than 2 callback functions, eRPC don't need serialize any code. {% endif%} @@ -102,7 +102,7 @@ codec.start_write_union({$self}discriminator) {% else %} {% set self = "self." %} {% endif %} -{$self}discriminator = codec.start_read_union() +{$self}{$info.discriminatorName} = codec.start_read_union() {% if self == "self." %} {$indent}{$name} = {$name}_union() {% endif %} @@ -171,7 +171,7 @@ _n{$depth} = {$codec}.start_read_list() {#--------------- function ---------------#} {% elif info.type == "function" %} {% if info.tableName != "" %} -{$name} = {$ info.tableName}[{$codec}.read_int32()] +{$name} = {$ info.tableName}[{$codec}.read_int8()] {% else %} # When are defined less than 2 callback functions, eRPC don't need serialize any code. {$indent}{$name} = {$info.callbackName} diff --git a/erpcgen/src/templates/py_common.template b/erpcgen/src/templates/py_common.template index e4fcc8289..6a4479084 100644 --- a/erpcgen/src/templates/py_common.template +++ b/erpcgen/src/templates/py_common.template @@ -58,9 +58,13 @@ class {$s.name}(object): {% endfor -- union cases %} {% endfor -- members %} - def __init__(self{% for m in s.members if not m.lengthForMember %}, {$m.name}=None{% endfor %}): + def __init__(self{% for m in s.members if ((not m.lengthForMember) && m.type.type != 'union') %}, {$m.name}=None{% endfor %}): {% for m in s.members if not m.lengthForMember %} +{% if (m.type.type == 'union' && m.type.isNonEncapsulatedUnion == false) %} + self.{$m.name} = self.{$m.name}_union # {$prettyTypeName(m.name, m.type)} +{% else %} self.{$m.name} = {$m.name} # {$prettyTypeName(m.name, m.type)} +{% endif -- union type %} {% endfor -- members %} {# create read-only properties for @length counts #} @@ -101,11 +105,11 @@ class {$s.name}(object): if {$self_m_name} is None: raise ValueError("{$m.name} is None") {% if (m.type.type == 'union' && m.type.isNonEncapsulatedUnion == true) %} - {$m.name}._write(codec, self.{$m.discriminator}) + self.{$m.name}._write(codec, self.{$m.discriminator}) {% else -- isNonEncapsulatedUnion %} {$encodeValue(m.type, self_m_name, "codec", " ", 0)} {% endif -- isNonEncapsulatedUnion %} -{% endif -- isNullable %} +{% endif -- isNullable %} {% endfor -- members %} def __str__(self): @@ -146,10 +150,10 @@ class {$u.name}(object): {% endfor -- group.symbolsMap.unions %} {% endif -- not empty(group.symbolsMap.unions) %} +{% if not empty(group.symbolsMap.aliases) %} -{% if aliases %} # Type aliases -{% for a in aliases %} +{% for a in group.symbolsMap.aliases %} {$a.name} = {$a.elementType.name} -{% endfor -- aliases %} -{% endif -- aliases %} +{% endfor -- group.symbolsMap.aliases %} +{% endif -- not empty(group.symbolsMap.aliases) %} \ No newline at end of file diff --git a/erpcgen/src/types/AliasType.h b/erpcgen/src/types/AliasType.h index 4584af798..b6f864313 100644 --- a/erpcgen/src/types/AliasType.h +++ b/erpcgen/src/types/AliasType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__ALIASTYPE_H_ #include "DataType.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/Annotation.h b/erpcgen/src/types/Annotation.h index 37aaa748d..944a17cd9 100644 --- a/erpcgen/src/types/Annotation.h +++ b/erpcgen/src/types/Annotation.h @@ -13,6 +13,7 @@ #include "AstNode.h" #include "Token.h" #include "Value.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/ArrayType.h b/erpcgen/src/types/ArrayType.h index a488eb390..9ea550fed 100644 --- a/erpcgen/src/types/ArrayType.h +++ b/erpcgen/src/types/ArrayType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__ARRAYTYPE_H_ #include "DataType.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/BuiltinType.h b/erpcgen/src/types/BuiltinType.h index 93c475f20..4984247be 100644 --- a/erpcgen/src/types/BuiltinType.h +++ b/erpcgen/src/types/BuiltinType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__BUILTINTYPE_H_ #include "DataType.h" + #include //////////////////////////////////////////////////////////////////////////////// @@ -42,6 +43,7 @@ class BuiltinType : public DataType kFloatType, kDoubleType, kStringType, + kUStringType, kBinaryType }; @@ -108,10 +110,18 @@ class BuiltinType : public DataType /*! * @brief This function return true/false value for identify string type. * - * @retval true When builtin type is string. - * @retval false When builtin type isn't string. + * @retval true When builtin type is string or ustring. + * @retval false When builtin type isn't string or ustring. + */ + virtual bool isString() const { return m_builtinType == kStringType || m_builtinType == kUStringType; } + + /*! + * @brief This function return true/false value for identify ustring type. + * + * @retval true When builtin type is ustring. + * @retval false When builtin type isn't ustring. */ - virtual bool isString() const { return m_builtinType == kStringType; } + virtual bool isUString() const { return m_builtinType == kUStringType; } /*! * @brief This function return true/false value for identify binary type. diff --git a/erpcgen/src/types/ConstType.h b/erpcgen/src/types/ConstType.h index 600dd53b7..4d7b3c98f 100644 --- a/erpcgen/src/types/ConstType.h +++ b/erpcgen/src/types/ConstType.h @@ -12,6 +12,7 @@ #include "DataType.h" #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/DataType.h b/erpcgen/src/types/DataType.h index 11bb4fa68..52f20afd7 100644 --- a/erpcgen/src/types/DataType.h +++ b/erpcgen/src/types/DataType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__DATATYPE_H_ #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// @@ -194,6 +195,13 @@ class DataType : public Symbol */ virtual bool isString() const { return false; } + /*! + * @brief This function return "false" value as default for identify ustring type. + * + * @retval false Always return false. + */ + virtual bool isUString() const { return false; } + /*! * @brief This function return "false" value as default for identify struct type. * diff --git a/erpcgen/src/types/EnumMember.h b/erpcgen/src/types/EnumMember.h index e2bfa9061..9d64d8713 100644 --- a/erpcgen/src/types/EnumMember.h +++ b/erpcgen/src/types/EnumMember.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__ENUMMEBER_H_ #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/EnumType.h b/erpcgen/src/types/EnumType.h index b81330435..5ef65e133 100644 --- a/erpcgen/src/types/EnumType.h +++ b/erpcgen/src/types/EnumType.h @@ -12,6 +12,7 @@ #include "DataType.h" #include "EnumMember.h" + #include #include diff --git a/erpcgen/src/types/Function.h b/erpcgen/src/types/Function.h index 60b0c3dee..fd96f2aa5 100644 --- a/erpcgen/src/types/Function.h +++ b/erpcgen/src/types/Function.h @@ -13,6 +13,7 @@ #include "DataType.h" #include "StructType.h" #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// @@ -82,7 +83,7 @@ class FunctionBase * * @param[in] isOneway Set, if function return type is oneway. */ - void setIsOneway(bool isOneway) { m_isOneway = isOneway; } + void setIsOneway(bool argIsOneway) { m_isOneway = argIsOneway; } /*! * @brief This function returns description about the interface function. @@ -125,8 +126,8 @@ class Function : public FunctionBase, public Symbol * @param[in] m_interface Parent interface. */ Function(const Token &tok, Interface *interface) - : Symbol(kFunctionSymbol, tok) - , FunctionBase() + : FunctionBase() + , Symbol(kFunctionSymbol, tok) , m_uniqueId(++s_idCounter) , m_interface(interface) , m_functionType(nullptr) @@ -143,8 +144,8 @@ class Function : public FunctionBase, public Symbol * @param[in] uniqueId Given unique function id. */ Function(const Token &tok, Interface *interface, uint32_t uniqueId) - : Symbol(kFunctionSymbol, tok) - , FunctionBase() + : FunctionBase() + , Symbol(kFunctionSymbol, tok) , m_uniqueId(uniqueId) , m_interface(interface) , m_functionType(nullptr) diff --git a/erpcgen/src/types/FunctionType.h b/erpcgen/src/types/FunctionType.h index a9ad304cf..d464d02db 100644 --- a/erpcgen/src/types/FunctionType.h +++ b/erpcgen/src/types/FunctionType.h @@ -14,6 +14,7 @@ #include "Function.h" #include "StructType.h" #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/Group.h b/erpcgen/src/types/Group.h index ff5772a14..146c9cb1f 100644 --- a/erpcgen/src/types/Group.h +++ b/erpcgen/src/types/Group.h @@ -11,6 +11,7 @@ #include "Interface.h" #include "cpptempl.h" + #include #include #include diff --git a/erpcgen/src/types/Interface.h b/erpcgen/src/types/Interface.h index 66771924e..7193c040e 100644 --- a/erpcgen/src/types/Interface.h +++ b/erpcgen/src/types/Interface.h @@ -13,6 +13,7 @@ #include "Function.h" #include "Symbol.h" #include "SymbolScope.h" + #include #include diff --git a/erpcgen/src/types/ListType.h b/erpcgen/src/types/ListType.h index 37cdff746..25504a447 100644 --- a/erpcgen/src/types/ListType.h +++ b/erpcgen/src/types/ListType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__LISTTYPE_H_ #include "DataType.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/Program.h b/erpcgen/src/types/Program.h index 6ea1ac1fb..65676d6ea 100644 --- a/erpcgen/src/types/Program.h +++ b/erpcgen/src/types/Program.h @@ -12,6 +12,7 @@ #include "DataType.h" #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/StructMember.h b/erpcgen/src/types/StructMember.h index a890138b5..b224b3f03 100644 --- a/erpcgen/src/types/StructMember.h +++ b/erpcgen/src/types/StructMember.h @@ -12,6 +12,7 @@ #include "DataType.h" #include "Symbol.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/StructType.h b/erpcgen/src/types/StructType.h index 7c7a3add4..f0aef1d43 100644 --- a/erpcgen/src/types/StructType.h +++ b/erpcgen/src/types/StructType.h @@ -13,6 +13,7 @@ #include "DataType.h" #include "StructMember.h" #include "SymbolScope.h" + #include #include diff --git a/erpcgen/src/types/Symbol.h b/erpcgen/src/types/Symbol.h index edfc9557a..43b870552 100644 --- a/erpcgen/src/types/Symbol.h +++ b/erpcgen/src/types/Symbol.h @@ -13,6 +13,7 @@ #include "Annotation.h" #include "AstNode.h" #include "Token.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/SymbolScope.h b/erpcgen/src/types/SymbolScope.h index 7469b581f..41d654af7 100644 --- a/erpcgen/src/types/SymbolScope.h +++ b/erpcgen/src/types/SymbolScope.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__SYMBOLSCOPE_H_ #include "Symbol.h" + #include #include #include diff --git a/erpcgen/src/types/Type.cpp b/erpcgen/src/types/Type.cpp index c04a2cf90..bc92c2cfe 100644 --- a/erpcgen/src/types/Type.cpp +++ b/erpcgen/src/types/Type.cpp @@ -28,6 +28,7 @@ #include "UnionType.h" #include "annotations.h" #include "cpptempl.h" + #include using namespace erpcgen; @@ -94,7 +95,7 @@ Annotation *Symbol::findAnnotation(string name, Annotation::program_lang_t lang) vector Symbol::getAnnotations(string name, Annotation::program_lang_t lang) { vector anList; - for (int i = 0; i < m_annotations.size(); ++i) + for (unsigned int i = 0; i < m_annotations.size(); ++i) { if (m_annotations[i].getName() == name && (m_annotations[i].getLang() == lang || m_annotations[i].getLang() == Annotation::kAll)) @@ -239,7 +240,7 @@ void SymbolScope::replaceSymbol(Symbol *oldSym, Symbol *newSym) int32_t SymbolScope::getSymbolPos(Symbol *sym) { - for (int i = 0; i < m_symbolVector.size(); i++) + for (unsigned int i = 0; i < m_symbolVector.size(); i++) { if (m_symbolVector[i] == sym) { @@ -323,7 +324,7 @@ void StructType::addMember(StructMember *newMember) string StructType::getDescription() const { string members; - int n = 0; + unsigned int n = 0; for (auto it : m_members) { members += format_string("%d:", n); @@ -363,7 +364,7 @@ void EnumType::addMember(EnumMember *newMember) string EnumType::getDescription() const { string members; - int n = 0; + unsigned int n = 0; for (auto it : m_members) { members += format_string("%d:", n); @@ -437,7 +438,7 @@ const set<_param_direction> Group::getSymbolDirections(Symbol *symbol) const string Group::getDescription() const { string ifaces; - int n = 0; + unsigned int n = 0; for (auto it : m_interfaces) { ifaces += format_string("%d:", n); @@ -475,14 +476,12 @@ DataType *DataType::getTrueContainerDataType() DataType *trueDataType = this->getTrueDataType(); switch (trueDataType->getDataType()) { - case DataType::kListType: - { + case DataType::kListType: { ListType *l = dynamic_cast(trueDataType); assert(l); return l->getElementType()->getTrueContainerDataType(); } - case DataType::kArrayType: - { + case DataType::kArrayType: { ArrayType *a = dynamic_cast(trueDataType); assert(a); return a->getElementType()->getTrueContainerDataType(); @@ -517,7 +516,7 @@ void Interface::addFunction(Function *func) string Interface::getDescription() const { string fns; - int n = 0; + unsigned int n = 0; for (auto it : m_functions) { fns += format_string("%d:", n); @@ -592,21 +591,21 @@ string UnionType::getDescription() const UnionType::case_vector_t UnionType::getUniqueCases() { UnionType::case_vector_t uniqueCases; - bool addCase = true; + bool uniqueAddCase = true; for (auto unionCase : getCases()) { for (auto uniqueCase : uniqueCases) { if (casesAreTheSame(unionCase, uniqueCase)) { - addCase = false; + uniqueAddCase = false; } } - if (addCase) + if (uniqueAddCase) { uniqueCases.push_back(unionCase); } - addCase = true; + uniqueAddCase = true; } return uniqueCases; } @@ -619,7 +618,7 @@ bool UnionType::casesAreTheSame(UnionCase *a, UnionCase *b) { return false; } - for (int i = 0; i < aNames.size(); ++i) + for (unsigned int i = 0; i < aNames.size(); ++i) { if (aNames[i] != bNames[i]) { diff --git a/erpcgen/src/types/UnionType.h b/erpcgen/src/types/UnionType.h index 2e7a51775..6af6c5cae 100644 --- a/erpcgen/src/types/UnionType.h +++ b/erpcgen/src/types/UnionType.h @@ -13,6 +13,7 @@ #include "DataType.h" #include "StructType.h" #include "UnionCase.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/src/types/VoidType.h b/erpcgen/src/types/VoidType.h index a980729f5..016ab53d1 100644 --- a/erpcgen/src/types/VoidType.h +++ b/erpcgen/src/types/VoidType.h @@ -11,6 +11,7 @@ #define _EMBEDDED_RPC__VOIDTYPE_H_ #include "DataType.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/erpcgen/test/readme.md b/erpcgen/test/readme.md index baf8e6efb..66e151cfe 100644 --- a/erpcgen/test/readme.md +++ b/erpcgen/test/readme.md @@ -4,9 +4,8 @@ erpcgen test system This file documents the parser and output test system for erpcgen. This test system is built on py.test using its extensive plugin hooks. To run the tests, just run -py.test in either the `erpc/erpgen/` or `erpc/erpcgen/test/` directory. -Because of py.test are trying run all tests in all subfolders, is safer to run py.test with parameter -source directory (from erpcgen directory run: "pytest test"). This prevent on windows to execute +py.test in `erpc/erpcgen/test/` directory. It's safer to run py.test with parameter source +directory (from erpcgen directory run: "pytest test"). This prevent on windows to execute boost test in boost folder. @@ -15,7 +14,7 @@ Setup Python 2.7.x is required. It will also work with Python 3.5+. -py.test and pyYAML are required to run the tests. These can be installed via pip. +py.test(**Version 5.0.0-**) and pyYAML are required to run the tests. These can be installed via pip. pip install pytest pyyaml diff --git a/erpcgen/test/test_forward_declaration_c.yml b/erpcgen/test/test_forward_declaration_c.yml index 2eb92822d..c39f0594a 100644 --- a/erpcgen/test/test_forward_declaration_c.yml +++ b/erpcgen/test/test_forward_declaration_c.yml @@ -1,6 +1,10 @@ --- name: struct before function desc: forward declaration of structure before function which is using type. +params: + dir: + - "in" + - "out" idl: struct forwardStruct; @@ -13,7 +17,7 @@ idl: interface foo { - myFun(in forwardCallback_t pCallback1_t) -> void + myFun({dir} forwardCallback_t pCallback1_t) -> void forwardCallback_t forwardCallback; } @@ -26,6 +30,12 @@ test.h: - "{" - forwardCallback_t pCallback; - "};" +test_server.cpp: + - if: dir == 'in' + then: + - not: erpc_free(pCallback1_t); + else: + - erpc_free(pCallback1_t); --- name: struct before struct diff --git a/erpcgen/test/test_length_py.yml b/erpcgen/test/test_length_py.yml index 85db39ec0..1ac4a1b06 100644 --- a/erpcgen/test/test_length_py.yml +++ b/erpcgen/test/test_length_py.yml @@ -48,7 +48,7 @@ test/interface.py: - def bar(self, l) test/client.py: - def bar(self, l) - - start_write_list(len(l)) + - start_write_list(len(l.value)) - perform_request - start_read_list - not: codec.read_int32() @@ -78,9 +78,14 @@ idl: | lang: py test/client.py: - def bar(self, v) + - if: dir in ('in', ) + then: + - write_{type}(v) + - if: dir in ('inout', ) + then: + - write_{type}(v.value) - if: dir in ('in', 'inout') then: - - write_{type}(v) - not: write_int32(len(v)) - perform_request - if: dir in ('inout',) diff --git a/erpcgen/test/test_name_py.yml b/erpcgen/test/test_name_py.yml index ad57ec695..6fd3de6d3 100644 --- a/erpcgen/test/test_name_py.yml +++ b/erpcgen/test/test_name_py.yml @@ -41,7 +41,6 @@ test/common.py: - if self.d is None - codec.write_int32(self.d) - self.d - - type = StructName test/client.py: - def function(self, m) diff --git a/erpcgen/test/test_nullable_c.yml b/erpcgen/test/test_nullable_c.yml index 63967ef36..f73990a90 100644 --- a/erpcgen/test/test_nullable_c.yml +++ b/erpcgen/test/test_nullable_c.yml @@ -16,10 +16,10 @@ test_client.cpp: - codec->writeNullFlag(true) - if: dir in ('in', 'inout') then: - - codec->writeString(strlen(a), a); + - codec->writeString(strlen((const char*)a), (const char*)a); - if: dir == 'out' then: - - not: codec->writeString(strlen(a), a); + - not: codec->writeString(strlen((const char*)a), (const char*)a); - if: dir in ('out', 'inout') then: - if (a != NULL) @@ -41,7 +41,51 @@ test_server.cpp: - if: dir in ('out', 'inout') then: - if (a != NULL) - - codec->writeString(strlen(a), a); + - codec->writeString(strlen((const char*)a), (const char*)a); +--- +name: param ustring +desc: +params: + dir: + - "in" + - "out" + - "inout" +idl: | + interface foo { + bar({dir} ustring a @nullable @max_length(8)) -> void + } +test_client.cpp: + - re: void bar\(\w*\s*unsigned\s*char\s*\* a\) + - if (a == NULL) + - codec->writeNullFlag(true) + - if: dir in ('in', 'inout') + then: + - codec->writeString(strlen((const char*)a), (const char*)a); + - if: dir == 'out' + then: + - not: codec->writeString(strlen((const char*)a), (const char*)a); + - if: dir in ('out', 'inout') + then: + - if (a != NULL) + - codec->readString(&a_len, &a_local); +test_server.cpp: + - ::bar_shim + - unsigned char* a = NULL; + - bool isNull; + - codec->readNullFlag(&isNull) + - if (!isNull) + - if: dir in ('in', 'inout') + then: + - codec->readString(&a_len, &a_local) + - if: dir == 'out' + then: + - not: codec->readString(&a_len, &a_local) + - else + - a = NULL; + - if: dir in ('out', 'inout') + then: + - if (a != NULL) + - codec->writeString(strlen((const char*)a), (const char*)a); --- name: in param struct desc: @@ -167,7 +211,7 @@ test_client.cpp: - codec->writeNullFlag(true); - else - codec->writeNullFlag(false); - - codec->writeString(strlen(data->a), data->a); + - codec->writeString(strlen((const char*)data->a), (const char*)data->a); - if: dir in ('out', 'inout') then: - void read_erpc_pair_struct @@ -196,7 +240,7 @@ test_server.cpp: - codec->writeNullFlag(true); - else - codec->writeNullFlag(false); - - codec->writeString(strlen(data->a), data->a); + - codec->writeString(strlen((const char*)data->a), (const char*)data->a); --- name: return struct diff --git a/erpcgen/test/test_union_py.yml b/erpcgen/test/test_union_py.yml index a2cf6b137..9c210920f 100644 --- a/erpcgen/test/test_union_py.yml +++ b/erpcgen/test/test_union_py.yml @@ -168,7 +168,7 @@ lang: py test/common.py: - not: class unionVariable_union(object) - "class structType(object):" - - def __init__(self, discriminator=None, unionVariable=None) + - def __init__(self, discriminator=None) - self.discriminator = discriminator # fruitType - self.unionVariable = unionVariable # unionType - self.unionVariable, self.discriminator = common.unionType()._read(codec) diff --git a/erpcsniffer/src/Sniffer.cpp b/erpcsniffer/src/Sniffer.cpp index 9bc1f7e19..02936a29c 100644 --- a/erpcsniffer/src/Sniffer.cpp +++ b/erpcsniffer/src/Sniffer.cpp @@ -7,9 +7,12 @@ */ #include "Sniffer.h" + #include "erpc_c/infra/erpc_message_buffer.h" + #include "Logging.h" #include "annotations.h" + #include #include #include @@ -75,8 +78,8 @@ erpc_status_t Sniffer::run() 0 : chrono::duration_cast(currentTime - previousTime).count()); uint32_t timeDifferenceSize = timeDifference.size(); - uint32_t countSpaces = floor((timeDifferenceSize - 1) / 3); - for (uint32_t i = 1; i <= countSpaces; ++i) + uint32_t diffCountSpaces = floor((timeDifferenceSize - 1) / 3); + for (uint32_t i = 1; i <= diffCountSpaces; ++i) { timeDifference = timeDifference.insert(timeDifferenceSize - i * 3, " "); } @@ -187,8 +190,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) erpc_status_t err; switch (dataType->getDataType()) { - case DataType::_data_type::kAliasType: - { + case DataType::_data_type::kAliasType: { AliasType *aliasType = dynamic_cast(dataType); assert(aliasType); string parseDataInfo; @@ -202,8 +204,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) addSpaces(parsedDataInfo, 2); break; } - case DataType::_data_type::kArrayType: - { + case DataType::_data_type::kArrayType: { ArrayType *arrayType = dynamic_cast(dataType); assert(arrayType); uint32_t arraySize = arrayType->getElementCount(); @@ -226,15 +227,13 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) } break; } - case DataType::_data_type::kBuiltinType: - { + case DataType::_data_type::kBuiltinType: { parsedDataInfo = " value: "; BuiltinType *builtinType = dynamic_cast(dataType); assert(builtinType); switch (builtinType->getBuiltinType()) { - case BuiltinType::_builtin_type::kBoolType: - { + case BuiltinType::_builtin_type::kBoolType: { bool value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -244,8 +243,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "bool" + parsedDataInfo + ((value) ? "true" : "false"); break; } - case BuiltinType::_builtin_type::kInt8Type: - { + case BuiltinType::_builtin_type::kInt8Type: { int8_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -255,8 +253,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "int8_t" + parsedDataInfo + format_string("%d", value); break; } - case BuiltinType::_builtin_type::kInt16Type: - { + case BuiltinType::_builtin_type::kInt16Type: { int16_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -266,8 +263,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "int16_t" + parsedDataInfo + format_string("%d", value); break; } - case BuiltinType::_builtin_type::kInt32Type: - { + case BuiltinType::_builtin_type::kInt32Type: { int32_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -277,8 +273,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "int32_t" + parsedDataInfo + format_string("%d", value); break; } - case BuiltinType::_builtin_type::kInt64Type: - { + case BuiltinType::_builtin_type::kInt64Type: { int64_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -288,8 +283,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "int64_t" + parsedDataInfo + format_string("%ld", value); break; } - case BuiltinType::_builtin_type::kUInt8Type: - { + case BuiltinType::_builtin_type::kUInt8Type: { uint8_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -299,8 +293,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "uint8_t" + parsedDataInfo + format_string("%u", value); break; } - case BuiltinType::_builtin_type::kUInt16Type: - { + case BuiltinType::_builtin_type::kUInt16Type: { uint16_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -310,8 +303,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "uint16_t" + parsedDataInfo + format_string("%u", value); break; } - case BuiltinType::_builtin_type::kUInt32Type: - { + case BuiltinType::_builtin_type::kUInt32Type: { uint32_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -321,8 +313,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "uint32_t" + parsedDataInfo + format_string("%u", value); break; } - case BuiltinType::_builtin_type::kUInt64Type: - { + case BuiltinType::_builtin_type::kUInt64Type: { uint64_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -332,8 +323,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "uint64_t" + parsedDataInfo + format_string("%lu", value); break; } - case BuiltinType::_builtin_type::kFloatType: - { + case BuiltinType::_builtin_type::kFloatType: { float value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -343,8 +333,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "float" + parsedDataInfo + format_string("%f", value); break; } - case BuiltinType::_builtin_type::kDoubleType: - { + case BuiltinType::_builtin_type::kDoubleType: { double value; m_codec->read(&value); if ((err = m_codec->getStatus())) @@ -354,8 +343,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "double" + parsedDataInfo + format_string("%f", value); break; } - case BuiltinType::_builtin_type::kStringType: - { + case BuiltinType::_builtin_type::kStringType: { char *value; uint32_t length; m_codec->readString(&length, &value); @@ -366,8 +354,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = "string" + parsedDataInfo + format_string("%.*s", length, value); break; } - case BuiltinType::_builtin_type::kBinaryType: - { + case BuiltinType::_builtin_type::kBinaryType: { uint8_t *value; uint32_t length; m_codec->readBinary(&length, &value); @@ -376,25 +363,23 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) return err; } string binaryValue; - for (int i = 0; i < length; ++i) + for (unsigned int i = 0; i < length; ++i) { binaryValue += format_string("%d|", value[i]); } parsedDataInfo = "binary" + parsedDataInfo + binaryValue; break; } - default: - { + default: { throw runtime_error("Unrecognized builtin type.\n"); } } break; } - case DataType::_data_type::kEnumType: - { + case DataType::_data_type::kEnumType: { EnumType *e = dynamic_cast(dataType); assert(e); - int32_t value; + uint32_t value; m_codec->read(&value); if ((err = m_codec->getStatus())) { @@ -416,8 +401,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) parsedDataInfo = format_string("%s value: %s", e->getName().c_str(), enumMemberName.c_str()); break; } - case DataType::_data_type::kFunctionType: - { + case DataType::_data_type::kFunctionType: { FunctionType *f = dynamic_cast(dataType); assert(f); int32_t value; @@ -437,8 +421,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) } break; } - case DataType::_data_type::kListType: - { + case DataType::_data_type::kListType: { ListType *listType = dynamic_cast(dataType); assert(listType); uint32_t listSize; @@ -447,7 +430,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) { return err; } - for (int i = 0; i < listSize; i++) + for (unsigned int i = 0; i < listSize; i++) { string parseDataInfo; err = parseDataType(listType->getElementType(), parseDataInfo); @@ -468,13 +451,12 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) } break; } - case DataType::_data_type::kStructType: - { + case DataType::_data_type::kStructType: { StructType *structType = dynamic_cast(dataType); assert(structType); parsedDataInfo = "struct " + structType->getName() + ":\n"; StructType::member_vector_t members = structType->getMembers(); - for (int i = 0; i < members.size(); ++i) + for (unsigned int i = 0; i < members.size(); ++i) { string parseDataInfo; err = parseMemberType(structType, members[i], parseDataInfo); @@ -494,8 +476,7 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) addSpaces(parsedDataInfo, 2); break; } - case DataType::_data_type::kUnionType: - { + case DataType::_data_type::kUnionType: { UnionType *unionType = dynamic_cast(dataType); assert(unionType); int32_t discriminator; @@ -545,13 +526,11 @@ erpc_status_t Sniffer::parseDataType(DataType *dataType, string &parsedDataInfo) addSpaces(parsedDataInfo, 2); break; } - case DataType::_data_type::kVoidType: - { + case DataType::_data_type::kVoidType: { parsedDataInfo = "void"; break; } - default: - { + default: { throw runtime_error("Unrecognized data type.\n"); } } @@ -670,14 +649,12 @@ string Sniffer::getDataTypeName(DataType *dataType) { switch (dataType->getDataType()) { - case DataType::kListType: - { + case DataType::kListType: { ListType *listType = dynamic_cast(dataType); assert(listType); return "list<" + getDataTypeName(listType->getElementType()) + ">"; } - case DataType::kArrayType: - { + case DataType::kArrayType: { string returnVal; while (dataType->isArray()) { @@ -688,8 +665,7 @@ string Sniffer::getDataTypeName(DataType *dataType) } return getDataTypeName(dataType) + returnVal; } - case DataType::kVoidType: - { + case DataType::kVoidType: { return "void"; } default: diff --git a/erpcsniffer/src/Sniffer.h b/erpcsniffer/src/Sniffer.h index 155cf5fe7..bf19d423e 100644 --- a/erpcsniffer/src/Sniffer.h +++ b/erpcsniffer/src/Sniffer.h @@ -11,7 +11,9 @@ #include "erpc_c/infra/erpc_basic_codec.h" #include "erpc_c/infra/erpc_transport.h" + #include "CGenerator.h" + #include //////////////////////////////////////////////////////////////////////////////// // Classes diff --git a/erpcsniffer/src/erpcsniffer.cpp b/erpcsniffer/src/erpcsniffer.cpp index a88345b34..348fd15fb 100644 --- a/erpcsniffer/src/erpcsniffer.cpp +++ b/erpcsniffer/src/erpcsniffer.cpp @@ -11,6 +11,7 @@ #include "erpc_transport.h" #include "erpc_transport_setup.h" #include "erpc_version.h" + #include "ErpcLexer.h" #include "InterfaceDefinition.h" #include "Logging.h" @@ -19,6 +20,7 @@ #include "UniqueIdChecker.h" #include "annotations.h" #include "options.h" + #include #include #include @@ -183,26 +185,22 @@ class erpcsnifferTool { switch (optchar) { - case '?': - { + case '?': { printUsage(options); return 0; } - case 'V': - { + case 'V': { printf("%s %s\n%s\n", k_toolName, k_version, k_copyright); return 0; } - case 'o': - { + case 'o': { m_outputFilePath = optarg; break; } - case 'v': - { + case 'v': { if (m_verboseType != kExtraDebug) { m_verboseType = (verbose_type_t)(((int)m_verboseType) + 1); @@ -210,14 +208,12 @@ class erpcsnifferTool break; } - case 'I': - { + case 'I': { PathSearcher::getGlobalSearcher().addSearchPath(optarg); break; } - case 't': - { + case 't': { string transport = optarg; if (transport == "tcp") { @@ -235,32 +231,27 @@ class erpcsnifferTool break; } - case 'q': - { + case 'q': { m_quantity = strtoul(optarg, NULL, 10); break; } - case 'b': - { + case 'b': { m_baudrate = strtoul(optarg, NULL, 10); break; } - case 'p': - { + case 'p': { m_port = optarg; break; } - case 'h': - { + case 'h': { m_host = optarg; break; } - default: - { + default: { Log::error("error: unrecognized option\n\n"); printUsage(options); return 0; @@ -345,8 +336,7 @@ class erpcsnifferTool Transport *_transport; switch (m_transport) { - case kTcpTransport: - { + case kTcpTransport: { uint16_t portNumber = strtoul(m_port, NULL, 10); TCPTransport *tcpTransport = new TCPTransport(m_host, portNumber, true); if (erpc_status_t err = tcpTransport->open()) @@ -357,16 +347,14 @@ class erpcsnifferTool break; } - case kSerialTransport: - { + case kSerialTransport: { erpc_transport_t transport = erpc_transport_serial_init(m_port, m_baudrate); _transport = reinterpret_cast(transport); assert(_transport); break; } - default: - { + default: { break; } } @@ -445,6 +433,7 @@ class erpcsnifferTool */ int main(int argc, char *argv[], char *envp[]) { + (void)envp; try { return erpcsniffer::erpcsnifferTool(argc, argv).run(); diff --git a/examples/matrix_multiply_tcp_python/matrix_multiply.py b/examples/matrix_multiply_tcp_python/matrix_multiply.py index af4e4890c..107a4a922 100644 --- a/examples/matrix_multiply_tcp_python/matrix_multiply.py +++ b/examples/matrix_multiply_tcp_python/matrix_multiply.py @@ -140,6 +140,9 @@ def runClient(transport): argParser.add_argument('-s', '--server', action='store_true', help='Run server') argParser.add_argument('-t', '--host', default='localhost', help='Host IP address (default value is localhost)') argParser.add_argument('-p', '--port', default='40', help='Port (default value is 40)') + argParser.add_argument('-S', '--serial', default=None, help='Serial device (default value is None)') + argParser.add_argument('-B', '--baud', default='115200', help='Baud (default value is 115200)') + args = argParser.parse_args() # check if either server or client has been selected @@ -149,8 +152,12 @@ def runClient(transport): print('eRPC Matrix Multiply TCP example') - # initialize TCP transport layer - transport = erpc.transport.TCPTransport(args.host, int(args.port), args.server) + if args.serial: + # initialize Serial transport layer + transport = erpc.transport.SerialTransport(args.serial, int(args.baud)) + else: + # initialize TCP transport layer + transport = erpc.transport.TCPTransport(args.host, int(args.port), args.server) if args.client: print('Client connecting to a host on %s:%s' % (args.host, args.port)) diff --git a/examples/matrix_multiply_tcp_python/service/__init__.py b/examples/matrix_multiply_tcp_python/service/__init__.py index 4de10adea..ad482727f 100644 --- a/examples/matrix_multiply_tcp_python/service/__init__.py +++ b/examples/matrix_multiply_tcp_python/service/__init__.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # diff --git a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/__init__.py b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/__init__.py index 18eb5d0fe..8188e5c91 100644 --- a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/__init__.py +++ b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/__init__.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # @@ -15,8 +15,8 @@ version = erpc_version.ERPC_VERSION except ImportError: version = "unknown" -if version != "1.7.2": - raise ValueError("The generated shim code version (1.7.2) is different to the rest of eRPC code (%s). \ +if version != "1.8.0": + raise ValueError("The generated shim code version (1.8.0) is different to the rest of eRPC code (%s). \ Install newer version by running \"python setup.py install\" in folder erpc/erpc_python/." % repr(version)) from . import common diff --git a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/client.py b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/client.py index 41fdc87d3..ef2798bf0 100644 --- a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/client.py +++ b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/client.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # diff --git a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/common.py b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/common.py index cf21b35be..0947097fb 100644 --- a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/common.py +++ b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/common.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # @@ -18,4 +18,3 @@ #matrix size is changed in the erpc file matrix_size = 5 - diff --git a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/interface.py b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/interface.py index e35618083..42830a7db 100644 --- a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/interface.py +++ b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/interface.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # diff --git a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/server.py b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/server.py index f2750aa5d..b9ee6ba65 100644 --- a/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/server.py +++ b/examples/matrix_multiply_tcp_python/service/erpc_matrix_multiply/server.py @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -# Generated by erpcgen 1.7.2 on Fri Mar 15 10:14:52 2019. +# Generated by erpcgen 1.8.0 on Thu Oct 8 16:38:36 2020. # # AUTOGENERATED - DO NOT EDIT # diff --git a/mk/flags.mk b/mk/flags.mk index 8c87d0021..1326271f7 100644 --- a/mk/flags.mk +++ b/mk/flags.mk @@ -29,6 +29,7 @@ else endif CXXFLAGS += -std=gnu++11 -D LINUX -Wunused-variable -Wno-deprecated-register -Wno-narrowing -Werror $(MARCH) +#CXXFLAGS += -Wall -Wextra -Wshadow -pedantic-errors CFLAGS += -std=gnu11 -D LINUX -D _GNU_SOURCE -Werror $(MARCH) YYFLAGS += -Wno-other # --debug --verbose LLFLAGS += diff --git a/run_clang_format.py b/run_clang_format.py index 16b17bde7..db9c3c339 100644 --- a/run_clang_format.py +++ b/run_clang_format.py @@ -53,5 +53,5 @@ print("Ignored: ", file) else: print("Formatting: ", file) - subprocess.call(["clang-format-5.0", "-i", file]) + subprocess.call(["clang-format-10.0", "-i", file]) print('*****************************************************************************\n') diff --git a/test/common/gtest/gtest.cpp b/test/common/gtest/gtest.cpp index 50b127ff8..3ac4413e6 100644 --- a/test/common/gtest/gtest.cpp +++ b/test/common/gtest/gtest.cpp @@ -1863,7 +1863,10 @@ void AssertHelper::operator=(const Message& message) const { } // Mutex for linked pointers. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); +#pragma GCC diagnostic pop // Application pathname gotten in InitGoogleTest. std::string g_executable_path; @@ -5210,13 +5213,13 @@ class DefaultStoredResultEventListener : public StoredResultEventListener{ const BaseTestPartResult* DefaultStoredResultEventListener::TransformTestPartResult(const TestPartResult& test_part_result) { return new TestPartResult(test_part_result.type(),test_part_result.file_name(), test_part_result.line_number(), test_part_result.message()); -}; +} #if !GTEST_OS_BARE_METAL void DefaultStoredResultEventListener::OutputXmlTestPartResult(::std::ostream* stream, const BaseTestPartResult* base_test_part_result) { XmlUnitTestResultPrinter::OutputXmlTestPartResult(stream, base_test_part_result); -}; +} #endif // End DefaultStoredResultEventListener @@ -5237,7 +5240,7 @@ class BaseStoredResultEventListener : public StoredResultEventListener{ const BaseTestPartResult* BaseStoredResultEventListener::TransformTestPartResult(const TestPartResult& test_part_result) { return new BaseTestPartResult(test_part_result.type()); -}; +} #if !GTEST_OS_BARE_METAL void BaseStoredResultEventListener::OutputXmlTestPartResult(::std::ostream* stream, @@ -5245,7 +5248,7 @@ void BaseStoredResultEventListener::OutputXmlTestPartResult(::std::ostream* stre *stream << " type() == BaseTestPartResult::kFatalFailure) ? "fatal_failure" : "non_fatal_failure") << "\">\n"; -}; +} #endif // End BaseStoredResultEventListener diff --git a/test/common/gtest/gtest.h b/test/common/gtest/gtest.h index eb28fadcd..e07c3371c 100644 --- a/test/common/gtest/gtest.h +++ b/test/common/gtest/gtest.h @@ -2091,7 +2091,7 @@ using ::std::tuple_size; #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. -#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) +#if ((defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)) && (!defined(__ARMCC_VERSION))) # define GTEST_HAS_CXXABI_H_ 1 #else # define GTEST_HAS_CXXABI_H_ 0 @@ -17757,7 +17757,7 @@ class BaseTestPartResult{ // C'tor. BaseTestPartResult does NOT have a default constructor. // Always use this constructor (with parameters) to create a // BaseTestPartResult object. - BaseTestPartResult(Type type){type_ = type;} + BaseTestPartResult(Type arg_type){type_ = arg_type;} // D'tor. BaseTestPartResult have a virtual destructor because it could // be used for inheritance. diff --git a/test/common/retarget_cpp_streamed_io.c b/test/common/retarget_cpp_streamed_io.c index 9048d55c2..6cb1e31c7 100644 --- a/test/common/retarget_cpp_streamed_io.c +++ b/test/common/retarget_cpp_streamed_io.c @@ -26,7 +26,8 @@ #if defined(__CC_ARM) || defined(__ARMCC_VERSION) -#include "fsl_log.h" +//#include "fsl_log.h" +#include "fsl_debug_console.h" //#pragma import(__use_no_semihosting_swi) #include @@ -37,7 +38,6 @@ char *_sys_command_string(char *cmd, int len) { return (cmd); } - /* * These names are special strings which will be recognized by * _sys_open and will cause it to return the standard I/O handles, instead @@ -72,12 +72,14 @@ int _sys_close(FILEHANDLE fh) */ int _sys_write(FILEHANDLE fh, const unsigned char *buf, unsigned len, int mode) { - int i; - for (i = 0; i < len; i++) - { - // UART_write(buf[i]); - LOG_Push((uint8_t *)(&buf[i]), 1); - } + // int i; + // for (i = 0; i < len; i++) + //{ + // // UART_write(buf[i]); + // LOG_Push((uint8_t *)(&buf[i]), 1); + //} + + DbgConsole_SendData((uint8_t *)buf, len); return 0; } @@ -101,7 +103,8 @@ int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode) { // buf[pos]=UART_read(); - LOG_ReadCharacter((uint8_t *)&buf[pos]); + // LOG_ReadCharacter((uint8_t *)&buf[pos]); + DbgConsole_ReadCharacter((uint8_t *)&buf[pos]); // Advance position in buffer pos++; @@ -125,7 +128,10 @@ int _sys_read(FILEHANDLE fh, unsigned char *buf, unsigned len, int mode) } // else UART_write(buf[pos-1]); // Echo normal char to terminal else - LOG_Push((uint8_t *)(&buf[pos - 1]), 1); // Echo normal char to terminal + // LOG_Push((uint8_t *)(&buf[pos - 1]), 1); // Echo normal char to + // terminal + DbgConsole_SendData((uint8_t *)(&buf[pos - 1]), + 1); // Echo normal char to terminal } while (buf[pos - 1] != '\r'); @@ -144,9 +150,9 @@ void _ttywrch(int ch) char ench = ch; // UART_write(ench); - LOG_Push((uint8_t *)(&ench), 1); + // LOG_Push((uint8_t *)(&ench), 1); + DbgConsole_SendData((uint8_t *)(&ench), 1); } - /* * Return non-zero if the argument file is connected to a terminal. */ diff --git a/test/common/unit_test.h b/test/common/unit_test.h index dde7cf3fe..ace9e57fd 100644 --- a/test/common/unit_test.h +++ b/test/common/unit_test.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -17,6 +17,10 @@ void add_services(erpc::SimpleServer *server); +void remove_services(erpc::SimpleServer *server); + void add_common_service(erpc::SimpleServer *server); +void remove_common_service(erpc::SimpleServer *server); + #endif // _EMBEDDED_RPC__UNIT_TEST_H_ diff --git a/test/common/unit_test_arbitrator_app0.cpp b/test/common/unit_test_arbitrator_app0.cpp index a1217f866..a3b92f5a0 100644 --- a/test/common/unit_test_arbitrator_app0.cpp +++ b/test/common/unit_test_arbitrator_app0.cpp @@ -1,26 +1,23 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include "unit_test.h" - #include "erpc_arbitrated_client_setup.h" #include "erpc_mbf_setup.h" #include "erpc_server_setup.h" #include "erpc_transport_setup.h" #include "FreeRTOS.h" +#include "gtest.h" #include "semphr.h" #include "task.h" - -#include "gtest.h" - #include "test_firstInterface.h" #include "test_secondInterface_server.h" +#include "unit_test.h" #ifdef __cplusplus extern "C" { @@ -29,7 +26,12 @@ extern "C" { #include "board.h" #include "fsl_debug_console.h" #include "mcmgr.h" +#if defined(RPMSG) #include "rpmsg_lite.h" +#endif +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +int main(int argc, char **argv); +#endif #ifdef __cplusplus } #endif @@ -49,6 +51,7 @@ TaskHandle_t g_clientTask; volatile int waitQuit = 0; volatile uint16_t eRPCReadyEventData = 0; extern const uint32_t erpc_generated_crc; +erpc_service_t service = NULL; //////////////////////////////////////////////////////////////////////////////// // Code @@ -131,12 +134,21 @@ void runInit(void *arg) MCMGR_RegisterEvent(kMCMGR_RemoteApplicationEvent, eRPCReadyEventHandler, NULL); // Boot source for Core 1 - MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, (uint32_t)rpmsg_lite_base, kMCMGR_Start_Synchronous); +#if defined(RPMSG) + MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, (uint32_t)rpmsg_lite_base, + kMCMGR_Start_Synchronous); +#elif defined(MU) + MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, (uint32_t)0, kMCMGR_Start_Asynchronous); +#endif - // RPMsg-Lite transport layer initialization erpc_transport_t transportClient; erpc_transport_t transportServer; +#if defined(RPMSG) + // RPMsg-Lite transport layer initialization transportClient = erpc_transport_rpmsg_lite_rtos_master_init(100, 101, ERPC_TRANSPORT_RPMSG_LITE_LINK_ID); +#elif defined(MU) + transportClient = erpc_transport_mu_init(MU_BASE); +#endif if (transportClient == NULL) { // error in initialization of transport layer @@ -154,7 +166,11 @@ void runInit(void *arg) // MessageBufferFactory initialization erpc_mbf_t message_buffer_factory; +#if defined(RPMSG) message_buffer_factory = erpc_mbf_rpmsg_init(transportClient); +#elif defined(MU) + message_buffer_factory = erpc_mbf_dynamic_init(); +#endif // eRPC client side initialization transportServer = erpc_arbitrated_client_init(transportClient, message_buffer_factory); @@ -169,7 +185,8 @@ void runInit(void *arg) erpc_arbitrated_client_set_server_thread_id((void *)g_serverTask); // adding the service to the server - erpc_add_service_to_server(create_SecondInterface_service()); + service = create_SecondInterface_service(); + erpc_add_service_to_server(service); // unblock server and client task xTaskNotifyGive(g_serverTask); @@ -188,6 +205,12 @@ void runInit(void *arg) vTaskSuspend(NULL); } +/************************************************************************************ + * Following snippet reused from https://github.com/google/googletest/blob/master/googletest/docs/advanced.md + * Copyright 2008, Google Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ + class MinimalistPrinter : public ::testing::EmptyTestEventListener { // Called before a test starts. @@ -199,8 +222,8 @@ class MinimalistPrinter : public ::testing::EmptyTestEventListener // Called after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const ::testing::TestPartResult &test_part_result) { - PRINTF("%s in %s:%d\r\n%s\r\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), - test_part_result.line_number(), test_part_result.summary()); + PRINTF("%s in %s:%d\r\n%s\r\n", test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), test_part_result.line_number(), test_part_result.summary()); } // Called after a test ends. @@ -215,10 +238,10 @@ class MinimalistPrinter : public ::testing::EmptyTestEventListener test_case.failed_test_count()); } }; +/* + * end of reused snippet + ***********************************************************************************/ -#ifdef __cplusplus -extern "C" { -#endif int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); @@ -235,10 +258,10 @@ int main(int argc, char **argv) // Calculate size of the image uint32_t core1_image_size; core1_image_size = get_core1_image_size(); - PRINTF("Copy CORE1 image to address: 0x%x, size: %d\r\n", CORE1_BOOT_ADDRESS, core1_image_size); + PRINTF("Copy CORE1 image to address: 0x%x, size: %d\r\n", (void *)(char *)CORE1_BOOT_ADDRESS, core1_image_size); // Copy application from FLASH to RAM - memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size); + memcpy((void *)(char *)CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size); #endif g_waitQuitMutex = xSemaphoreCreateMutex(); @@ -252,12 +275,13 @@ int main(int argc, char **argv) { } } -#ifdef __cplusplus -} -#endif void quitSecondInterfaceServer() { + /* removing the service from the server */ + erpc_remove_service_from_server(service); + destroy_SecondInterface_service(); + // Stop server part erpc_server_stop(); increaseWaitQuit(); diff --git a/test/common/unit_test_arbitrator_app1.cpp b/test/common/unit_test_arbitrator_app1.cpp index add7eb75f..ca1bf46a1 100644 --- a/test/common/unit_test_arbitrator_app1.cpp +++ b/test/common/unit_test_arbitrator_app1.cpp @@ -1,24 +1,22 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include "unit_test.h" - #include "erpc_arbitrated_client_setup.h" #include "erpc_mbf_setup.h" #include "erpc_server_setup.h" #include "erpc_transport_setup.h" -#include "test_firstInterface_server.h" -#include "test_secondInterface.h" - #include "FreeRTOS.h" #include "semphr.h" #include "task.h" +#include "test_firstInterface_server.h" +#include "test_secondInterface.h" +#include "unit_test.h" #ifdef __cplusplus extern "C" { @@ -26,7 +24,12 @@ extern "C" { #include "app_core1.h" #include "board.h" #include "mcmgr.h" +#if defined(RPMSG) #include "rpmsg_lite.h" +#endif +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +int main(int argc, char **argv); +#endif #ifdef __cplusplus } #endif @@ -47,6 +50,7 @@ uint32_t startupData; mcmgr_status_t status; volatile int stopTest = 0; extern const uint32_t erpc_generated_crc; +erpc_service_t service = NULL; //////////////////////////////////////////////////////////////////////////////// // Code @@ -143,14 +147,21 @@ void runInit(void *arg) status = MCMGR_GetStartupData(&startupData); } while (status != kStatus_MCMGR_Success); - // RPMsg-Lite transport layer initialization erpc_transport_t transportClient; erpc_transport_t transportServer; + erpc_mbf_t message_buffer_factory; + +#if defined(RPMSG) + // RPMsg-Lite transport layer initialization transportClient = erpc_transport_rpmsg_lite_rtos_remote_init(101, 100, (void *)startupData, 0, SignalReady, NULL); // MessageBufferFactory initialization - erpc_mbf_t message_buffer_factory; message_buffer_factory = erpc_mbf_rpmsg_init(transportClient); +#elif defined(MU) + // MU transport layer initialization + transportClient = erpc_transport_mu_init(MU_BASE); + message_buffer_factory = erpc_mbf_dynamic_init(); +#endif // eRPC client side initialization transportServer = erpc_arbitrated_client_init(transportClient, message_buffer_factory); @@ -165,7 +176,12 @@ void runInit(void *arg) erpc_arbitrated_client_set_server_thread_id((void *)g_serverTask); // adding the service to the server - erpc_add_service_to_server(create_FirstInterface_service()); + service = create_FirstInterface_service(); + erpc_add_service_to_server(service); + +#if defined(MU) + SignalReady(); +#endif // unblock server and client task xTaskNotifyGive(g_serverTask); @@ -184,9 +200,6 @@ void runInit(void *arg) vTaskSuspend(NULL); } -#ifdef __cplusplus -extern "C" { -#endif int main(int argc, char **argv) { BOARD_InitHardware(); @@ -202,9 +215,6 @@ int main(int argc, char **argv) { } } -#ifdef __cplusplus -} -#endif void stopSecondSide() { @@ -219,6 +229,10 @@ int32_t getResultFromSecondSide() void quitFirstInterfaceServer() { + /* removing the service from the server */ + erpc_remove_service_from_server(service); + destroy_FirstInterface_service(); + // Stop server part erpc_server_stop(); } diff --git a/test/common/unit_test_client.cpp b/test/common/unit_test_client.cpp index 7f5b5b617..9a070ab50 100644 --- a/test/common/unit_test_client.cpp +++ b/test/common/unit_test_client.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -9,12 +9,14 @@ #include "erpc_client_setup.h" #include "erpc_mbf_setup.h" #include "erpc_transport_setup.h" + +#include "board.h" #include "gtest.h" #include "gtestListener.h" #include "myAlloc.h" #include "test_unit_test_common.h" -#if (defined(RPMSG) || defined(UART) || defined(LPUART)) +#if (defined(RPMSG) || defined(UART) || defined(MU)) extern "C" { #include "app_core0.h" #include "board.h" @@ -22,6 +24,11 @@ extern "C" { #include "mcmgr.h" #if defined(RPMSG) #include "rpmsg_lite.h" +#elif defined(UART) +#include "fsl_usart_cmsis.h" +#endif +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +int main(int argc, char **argv); #endif } @@ -35,6 +42,12 @@ using namespace std; // Classes //////////////////////////////////////////////////////////////////////////////// +/************************************************************************************ + * Following snippet reused from https://github.com/google/googletest/blob/master/googletest/docs/advanced.md + * Copyright 2008, Google Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ + class MinimalistPrinter : public ::testing::EmptyTestEventListener { // Called before a test starts. @@ -46,8 +59,8 @@ class MinimalistPrinter : public ::testing::EmptyTestEventListener // Called after a failed assertion or a SUCCEED() invocation. virtual void OnTestPartResult(const ::testing::TestPartResult &test_part_result) { - PRINTF("%s in %s:%d\n%s\r\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), - test_part_result.line_number(), test_part_result.summary()); + PRINTF("%s in %s:%d\r\n%s\r\n", test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), test_part_result.line_number(), test_part_result.summary()); } // Called after a test ends. @@ -62,6 +75,9 @@ class MinimalistPrinter : public ::testing::EmptyTestEventListener test_case.failed_test_count()); } }; +/* + * end of reused snippet + ***********************************************************************************/ #endif //////////////////////////////////////////////////////////////////////////////// @@ -74,12 +90,15 @@ int MyAlloc::allocated_ = 0; #define APP_ERPC_READY_EVENT_DATA (1) extern char rpmsg_lite_base[]; volatile uint16_t eRPCReadyEventData = 0; +#elif defined(MU) +#define APP_ERPC_READY_EVENT_DATA (1) +volatile uint16_t eRPCReadyEventData = 0; #endif //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// -#if defined(RPMSG) +#if (defined(RPMSG) || defined(MU)) /*! * @brief eRPC server side ready event handler */ @@ -101,9 +120,6 @@ void SystemInitHook(void) } #endif -#ifdef __cplusplus -extern "C" { -#endif int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); @@ -111,7 +127,7 @@ int main(int argc, char **argv) ::testing::TestEventListeners &listeners = ::testing::UnitTest::GetInstance()->listeners(); listeners.Append(new LeakChecker); -#if (defined(RPMSG) || defined(UART) || defined(LPUART)) +#if (defined(RPMSG) || defined(UART) || defined(MU)) delete listeners.Release(listeners.default_result_printer()); listeners.Append(new MinimalistPrinter); #ifdef UNITY_DUMP_RESULTS @@ -125,10 +141,10 @@ int main(int argc, char **argv) /* Calculate size of the image */ uint32_t core1_image_size; core1_image_size = get_core1_image_size(); - PRINTF("Copy CORE1 image to address: 0x%x, size: %d\r\n", CORE1_BOOT_ADDRESS, core1_image_size); + PRINTF("Copy CORE1 image to address: 0x%x, size: %d\r\n", (void *)(char *)CORE1_BOOT_ADDRESS, core1_image_size); /* Copy application from FLASH to RAM */ - memcpy(CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size); + memcpy((void *)(char *)CORE1_BOOT_ADDRESS, (void *)CORE1_IMAGE_START, core1_image_size); #endif #if defined(RPMSG) @@ -144,7 +160,23 @@ int main(int argc, char **argv) MCMGR_RegisterEvent(kMCMGR_RemoteApplicationEvent, eRPCReadyEventHandler, NULL); /* Boot Secondary core application */ - MCMGR_StartCore(kMCMGR_Core1, CORE1_BOOT_ADDRESS, (uint32_t)rpmsg_lite_base, kMCMGR_Start_Synchronous); + MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, (uint32_t)rpmsg_lite_base, + kMCMGR_Start_Synchronous); + + /* Wait until the secondary core application signals the rpmsg remote has been initialized and is ready to + * communicate. */ + while (APP_ERPC_READY_EVENT_DATA != eRPCReadyEventData) + { + }; +#elif defined(MU) + /* Initialize MCMGR before calling its API */ + MCMGR_Init(); + + /* Register the application event before starting the secondary core */ + MCMGR_RegisterEvent(kMCMGR_RemoteApplicationEvent, eRPCReadyEventHandler, NULL); + + /* Boot Secondary core application */ + MCMGR_StartCore(kMCMGR_Core1, (void *)(char *)CORE1_BOOT_ADDRESS, (uint32_t)0, kMCMGR_Start_Asynchronous); /* Wait until the secondary core application signals the rpmsg remote has been initialized and is ready to * communicate. */ @@ -158,14 +190,11 @@ int main(int argc, char **argv) #if defined(RPMSG) transport = erpc_transport_rpmsg_lite_master_init(100, 101, ERPC_TRANSPORT_RPMSG_LITE_LINK_ID); message_buffer_factory = erpc_mbf_rpmsg_init(transport); -#else -#if defined(UART) - transport = erpc_transport_uart_init(ERPC_BOARD_UART_BASEADDR, ERPC_BOARD_UART_BAUDRATE, - CLOCK_GetFreq(ERPC_BOARD_UART_CLKSRC); -#elif defined(LPUART) - transport = erpc_transport_lpuart_init(ERPC_BOARD_UART_BASEADDR, ERPC_BOARD_UART_BAUDRATE, - CLOCK_GetFreq(ERPC_BOARD_UART_CLKSRC); -#endif +#elif defined(UART) + transport = erpc_transport_cmsis_uart_init((void *)&Driver_USART0); + message_buffer_factory = erpc_mbf_dynamic_init(); +#elif defined(MU) + transport = erpc_transport_mu_init(MU_BASE); message_buffer_factory = erpc_mbf_dynamic_init(); #endif @@ -183,6 +212,3 @@ int main(int argc, char **argv) return i; } -#ifdef __cplusplus -} -#endif diff --git a/test/common/unit_test_serial_client.cpp b/test/common/unit_test_serial_client.cpp index a2d4b2816..890a4185a 100644 --- a/test/common/unit_test_serial_client.cpp +++ b/test/common/unit_test_serial_client.cpp @@ -9,6 +9,7 @@ #include "erpc_basic_codec.h" #include "erpc_client_manager.h" #include "erpc_serial_transport.h" + #include "Logging.h" #include "gtest.h" #include "gtestListener.h" @@ -69,12 +70,12 @@ int main(int argc, char **argv) g_client->setTransport(&g_transport); g_client->setCodecFactory(&g_basicCodecFactory); - int i = RUN_ALL_TESTS(); + int ret = RUN_ALL_TESTS(); quit(); free(m_logger); free(g_client); - return i; + return ret; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_serial_server.cpp b/test/common/unit_test_serial_server.cpp index 786c14de5..5892b16dd 100644 --- a/test/common/unit_test_serial_server.cpp +++ b/test/common/unit_test_serial_server.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -9,10 +9,12 @@ #include "erpc_basic_codec.h" #include "erpc_serial_transport.h" #include "erpc_simple_server.h" + #include "Logging.h" #include "myAlloc.h" #include "test_unit_test_common_server.h" #include "unit_test.h" + #include using namespace erpc; @@ -43,6 +45,8 @@ SimpleServer g_server; int MyAlloc::allocated_ = 0; +Common_service *svc_common; + //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// @@ -79,17 +83,27 @@ int main(int argc, const char *argv[]) //////////////////////////////////////////////////////////////////////////////// void add_common_service(SimpleServer *server) { - Common_service *svc = new Common_service(); + svc_common = new Common_service(); - server->addService(svc); + server->addService(svc_common); +} + +void remove_common_service(SimpleServer *server) +{ + server->removeService(svc_common); + delete svc_common; } extern "C" void erpc_add_service_to_server(void *service) {} +extern "C" void erpc_remove_service_from_server(void *service) {} + //////////////////////////////////////////////////////////////////////////////// // Common service implementations here //////////////////////////////////////////////////////////////////////////////// void quit() { + remove_common_service(&g_server); + remove_services(&g_server); exit(0); } diff --git a/test/common/unit_test_server.cpp b/test/common/unit_test_server.cpp index d5a1779b2..bb15903d7 100644 --- a/test/common/unit_test_server.cpp +++ b/test/common/unit_test_server.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -10,17 +10,27 @@ #include "erpc_server_setup.h" #include "erpc_simple_server.h" #include "erpc_transport_setup.h" + +#include "board.h" #include "myAlloc.h" #include "test_unit_test_common_server.h" #include "unit_test_wrapped.h" -#if (defined(RPMSG) || defined(UART) || defined(LPUART)) +#if (defined(RPMSG) || defined(UART) || defined(MU)) extern "C" { #include "app_core1.h" #if defined(RPMSG) #define APP_ERPC_READY_EVENT_DATA (1) #include "mcmgr.h" #include "rpmsg_lite.h" +#elif defined(UART) +#include "fsl_usart_cmsis.h" +#elif defined(MU) +#define APP_ERPC_READY_EVENT_DATA (1) +#include "mcmgr.h" +#endif +#if defined(__CC_ARM) || defined(__ARMCC_VERSION) +int main(int argc, const char *argv[]); #endif } #endif @@ -30,11 +40,12 @@ extern "C" { //////////////////////////////////////////////////////////////////////////////// int MyAlloc::allocated_ = 0; +erpc_service_t service_common = NULL; //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// -#if defined(RPMSG) +#if (defined(RPMSG) || defined(MU)) static void SignalReady(void) { /* Signal the other core we are ready by trigerring the event and passing the APP_ERPC_READY_EVENT_DATA */ @@ -53,12 +64,11 @@ void SystemInitHook(void) } #endif -#ifdef __cplusplus -extern "C" { -#endif int main(int argc, const char *argv[]) { -#if defined(RPMSG) + BOARD_InitHardware(); + +#if (defined(RPMSG) || defined(MU)) uint32_t startupData; mcmgr_status_t status; @@ -77,14 +87,11 @@ int main(int argc, const char *argv[]) transport = erpc_transport_rpmsg_lite_remote_init(101, 100, (void *)startupData, ERPC_TRANSPORT_RPMSG_LITE_LINK_ID, SignalReady, NULL); message_buffer_factory = erpc_mbf_rpmsg_init(transport); -#else -#if defined(UART) - transport = erpc_transport_uart_init(ERPC_BOARD_UART_BASEADDR, ERPC_BOARD_UART_BAUDRATE, - CLOCK_GetFreq(ERPC_BOARD_UART_CLKSRC); -#elif defined(LPUART) - transport = erpc_transport_lpuart_init(ERPC_BOARD_UART_BASEADDR, ERPC_BOARD_UART_BAUDRATE, - CLOCK_GetFreq(ERPC_BOARD_UART_CLKSRC); -#endif +#elif defined(UART) + transport = erpc_transport_cmsis_uart_init((void *)&Driver_USART0); + message_buffer_factory = erpc_mbf_dynamic_init(); +#elif defined(MU) + transport = erpc_transport_mu_init(MU_BASE); message_buffer_factory = erpc_mbf_dynamic_init(); #endif @@ -97,6 +104,9 @@ int main(int argc, const char *argv[]) /* Add common service */ add_common_service(); +#if defined(MU) + SignalReady(); +#endif /* Add run server */ erpc_server_run(); @@ -105,9 +115,6 @@ int main(int argc, const char *argv[]) return 0; } -#ifdef __cplusplus -} -#endif //////////////////////////////////////////////////////////////////////////////// // Server helper functions @@ -115,7 +122,8 @@ int main(int argc, const char *argv[]) void add_common_service() { - erpc_add_service_to_server(create_Common_service()); + service_common = create_Common_service(); + erpc_add_service_to_server(service_common); } //////////////////////////////////////////////////////////////////////////////// @@ -124,6 +132,12 @@ void add_common_service() void quit() { + /* removing common services from the server */ + remove_common_services_from_server(service_common); + + /* removing individual test services from the server */ + remove_services_from_server(); + erpc_server_stop(); } diff --git a/test/common/unit_test_tcp_arbitrator_client.cpp b/test/common/unit_test_tcp_arbitrator_client.cpp index 743f40619..36bc9ed14 100644 --- a/test/common/unit_test_tcp_arbitrator_client.cpp +++ b/test/common/unit_test_tcp_arbitrator_client.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -11,11 +11,13 @@ #include "erpc_simple_server.h" #include "erpc_tcp_transport.h" #include "erpc_transport_arbitrator.h" + #include "Logging.h" #include "gtest.h" #include "test_firstInterface.h" #include "test_secondInterface.h" #include "unit_test.h" + #include using namespace erpc; @@ -186,6 +188,8 @@ int main(int argc, char **argv) void quitSecondInterfaceServer() { + // removing SecondInterface service from the server + remove_services(&g_server); // Stop server part g_server.stop(); increaseWaitQuit(); diff --git a/test/common/unit_test_tcp_arbitrator_server.cpp b/test/common/unit_test_tcp_arbitrator_server.cpp index d273134c7..7295117ce 100644 --- a/test/common/unit_test_tcp_arbitrator_server.cpp +++ b/test/common/unit_test_tcp_arbitrator_server.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -11,11 +11,13 @@ #include "erpc_simple_server.h" #include "erpc_tcp_transport.h" #include "erpc_transport_arbitrator.h" + #include "Logging.h" #include "myAlloc.h" #include "test_firstInterface.h" #include "test_secondInterface.h" #include "unit_test.h" + #include using namespace erpc; @@ -52,10 +54,10 @@ Mutex waitQuitMutex; extern const uint32_t erpc_generated_crc; Crc16 g_crc16(erpc_generated_crc); -int waitQuit = 0; -int waitClient = 0; -int isTestPassing = 0; -int stopTest = 0; +volatile int waitQuit = 0; +volatile int waitClient = 0; +volatile int isTestPassing = 0; +volatile int stopTest = 0; void increaseWaitQuit() { @@ -193,6 +195,8 @@ int32_t getResultFromSecondSide() void quitFirstInterfaceServer() { + // removing FirstInterface service from the server + remove_services(&g_server); // Stop server part g_server.stop(); } diff --git a/test/common/unit_test_tcp_client.cpp b/test/common/unit_test_tcp_client.cpp index 6f56405c3..1d4db5ca5 100644 --- a/test/common/unit_test_tcp_client.cpp +++ b/test/common/unit_test_tcp_client.cpp @@ -9,6 +9,7 @@ #include "erpc_basic_codec.h" #include "erpc_client_manager.h" #include "erpc_tcp_transport.h" + #include "Logging.h" #include "gtest.h" #include "gtestListener.h" @@ -90,13 +91,13 @@ int main(int argc, char **argv) g_client->addMessageLogger(&g_messageLogger); #endif // USE_MESSAGE_LOGGING - int i = RUN_ALL_TESTS(); + int ret = RUN_ALL_TESTS(); quit(); free(m_logger); g_transport.close(); free(g_client); - return i; + return ret; } //////////////////////////////////////////////////////////////////////////////// diff --git a/test/common/unit_test_tcp_server.cpp b/test/common/unit_test_tcp_server.cpp index 24453ee67..e79557cc3 100644 --- a/test/common/unit_test_tcp_server.cpp +++ b/test/common/unit_test_tcp_server.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -9,6 +9,7 @@ #include "erpc_basic_codec.h" #include "erpc_simple_server.h" #include "erpc_tcp_transport.h" + #include "Logging.h" #include "myAlloc.h" #include "test_unit_test_common_server.h" @@ -44,6 +45,8 @@ Crc16 g_crc16; int MyAlloc::allocated_ = 0; +Common_service *svc_common; + //////////////////////////////////////////////////////////////////////////////// // Code //////////////////////////////////////////////////////////////////////////////// @@ -89,18 +92,27 @@ int main(int argc, const char *argv[]) //////////////////////////////////////////////////////////////////////////////// void add_common_service(SimpleServer *server) { - Common_service *svc = new Common_service(); + svc_common = new Common_service(); - server->addService(svc); + server->addService(svc_common); +} + +void remove_common_service(SimpleServer *server) +{ + server->removeService(svc_common); + delete svc_common; } extern "C" void erpc_add_service_to_server(void *service) {} +extern "C" void erpc_remove_service_from_server(void *service) {} //////////////////////////////////////////////////////////////////////////////// // Common service implementations here //////////////////////////////////////////////////////////////////////////////// void quit() { + remove_common_service(&g_server); + remove_services(&g_server); g_server.stop(); } diff --git a/test/common/unit_test_wrapped.h b/test/common/unit_test_wrapped.h index b901ab51f..78c8016df 100644 --- a/test/common/unit_test_wrapped.h +++ b/test/common/unit_test_wrapped.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * @@ -17,6 +17,8 @@ extern "C" { #endif void add_services_to_server(); +void remove_services_from_server(); +void remove_common_services_from_server(erpc_service_t service); void add_common_service(); #ifdef __cplusplus } diff --git a/test/skeleton/server_skeleton.cpp b/test/skeleton/server_skeleton.cpp index fc69ec08e..561aa281c 100644 --- a/test/skeleton/server_skeleton.cpp +++ b/test/skeleton/server_skeleton.cpp @@ -9,6 +9,7 @@ #include "Logging.h" #include "out.h" #include "unit_test.h" + #include //////////////////////////////////////////////////////////////////////////////// //// Implementation of functions here @@ -21,8 +22,8 @@ void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ // NOTE: possible memory leak? not ever deleting /* Add services * Example: server->addService(svc); diff --git a/test/test_annotations/external.h b/test/test_annotations/external.h index 83ead35e2..2ccab8a7f 100644 --- a/test/test_annotations/external.h +++ b/test/test_annotations/external.h @@ -15,7 +15,12 @@ //////////////////////////////////////////////////////////////////////////////// // Enumerators data types declarations -typedef enum myEnum { one = 0, two = 1, three = 2 } myEnum; +typedef enum myEnum +{ + one = 0, + two = 1, + three = 2 +} myEnum; // Aliases data types declarations typedef int32_t myInt; diff --git a/test/test_annotations/test_annotations_client_impl.cpp b/test/test_annotations/test_annotations_client_impl.cpp index 276f32b6e..61c2f748f 100644 --- a/test/test_annotations/test_annotations_client_impl.cpp +++ b/test/test_annotations/test_annotations_client_impl.cpp @@ -22,8 +22,8 @@ TEST(test_annotations, IncludeAnnotationCheck) { EXPECT_TRUE(5 == addOne(4)); - includedInt_t myInt = 5; - EXPECT_TRUE(5 == myInt); + includedInt_t testInt = 5; + EXPECT_TRUE(5 == testInt); } TEST(test_annotations, testIfMyIntAndConstExist) diff --git a/test/test_annotations/test_annotations_server_impl.cpp b/test/test_annotations/test_annotations_server_impl.cpp index 83433ecf7..bcf466659 100644 --- a/test/test_annotations/test_annotations_server_impl.cpp +++ b/test/test_annotations/test_annotations_server_impl.cpp @@ -1,17 +1,22 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include +AnnotateTest_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -37,21 +42,50 @@ myInt testIfMyIntAndConstExist(myInt a) void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting - AnnotateTest_service *svc = new AnnotateTest_service(); + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ + svc = new AnnotateTest_service(); /* Add services * Example: server->addService (svc); */ server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_AnnotateTest_service()); + service_test = create_AnnotateTest_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_AnnotateTest_service(&service_test); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(&service); } #ifdef __cplusplus } diff --git a/test/test_arbitrator/test_arbitrator_client_impl.cpp b/test/test_arbitrator/test_arbitrator_client_impl.cpp index 4e3120958..3e498de81 100644 --- a/test/test_arbitrator/test_arbitrator_client_impl.cpp +++ b/test/test_arbitrator/test_arbitrator_client_impl.cpp @@ -6,8 +6,9 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include "gtest.h" #include "erpc_simple_server.h" + +#include "gtest.h" #include "test_firstInterface.h" #include "test_secondInterface_server.h" @@ -20,6 +21,7 @@ int i = 0; int numbers[number]; volatile bool enabled = false; +SecondInterface_service *svc; TEST(test_arbitrator, FirstSendReceiveInt) { @@ -95,12 +97,27 @@ void enableFirstSide() void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting - SecondInterface_service *svc = new SecondInterface_service(); + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ + svc = new SecondInterface_service(); /* Add services * Example: server->addService(svc); */ server->addService(svc); } + +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} diff --git a/test/test_arbitrator/test_arbitrator_server_impl.cpp b/test/test_arbitrator/test_arbitrator_server_impl.cpp index ae52fa71d..a9d52b2e5 100644 --- a/test/test_arbitrator/test_arbitrator_server_impl.cpp +++ b/test/test_arbitrator/test_arbitrator_server_impl.cpp @@ -7,6 +7,7 @@ */ #include "erpc_simple_server.h" + #include "test_firstInterface_server.h" #include "test_secondInterface.h" @@ -17,6 +18,7 @@ #define number 15 int i = 0; int numbers[number]; +FirstInterface_service *svc; void firstSendInt(int32_t a) { @@ -43,12 +45,27 @@ int32_t callSecondSide() void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting - FirstInterface_service *svc = new FirstInterface_service(); + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ + svc = new FirstInterface_service(); /* Add services * Example: server->addService(svc); */ server->addService(svc); } + +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} diff --git a/test/test_arrays/test_arrays_client_impl.cpp b/test/test_arrays/test_arrays_client_impl.cpp index ab2907ffa..1db0d3a68 100644 --- a/test/test_arrays/test_arrays_client_impl.cpp +++ b/test/test_arrays/test_arrays_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/test/test_arrays/test_arrays_server_impl.cpp b/test/test_arrays/test_arrays_server_impl.cpp index 81cf34c28..8e37c85af 100644 --- a/test/test_arrays/test_arrays_server_impl.cpp +++ b/test/test_arrays/test_arrays_server_impl.cpp @@ -1,18 +1,23 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +PointersService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -43,7 +48,7 @@ int32_t (*sendReceived2Int32(int32_t arrayNumbers[12][10]))[12][10] char *(*sendReceivedString(char *arrayStrings[12]))[12] { - char *(*sendArrays)[12] = (char *(*)[12])erpc_malloc(sizeof(char * [12])); + char *(*sendArrays)[12] = (char *(*)[12])erpc_malloc(sizeof(char *[12])); for (int32_t i = 0; i < 12; ++i) { uint32_t textLen = strlen(arrayStrings[i]); @@ -55,7 +60,7 @@ char *(*sendReceivedString(char *arrayStrings[12]))[12] char *(*sendReceived2String(char *arrayStrings[3][5]))[3][5] { - char *(*sendArrays)[3][5] = (char *(*)[3][5])erpc_malloc(sizeof(char * [3][5])); + char *(*sendArrays)[3][5] = (char *(*)[3][5])erpc_malloc(sizeof(char *[3][5])); for (int32_t i = 0; i < 3; ++i) { for (int32_t j = 0; j < 5; ++j) @@ -377,19 +382,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - PointersService_service *svc = new PointersService_service(); + svc = new PointersService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_PointersService_service()); + service_test = create_PointersService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_PointersService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_binary/test_binary_server_impl.cpp b/test/test_binary/test_binary_server_impl.cpp index d6207a2c5..93d6f52ec 100644 --- a/test/test_binary/test_binary_server_impl.cpp +++ b/test/test_binary/test_binary_server_impl.cpp @@ -1,17 +1,22 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include +Binary_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -73,9 +78,9 @@ void test_binary_allDirectionLength(const uint8_t *a, const binary_t *b, binary_ void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting - Binary_service *svc = new Binary_service(); + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ + svc = new Binary_service(); /* Add services * Example: server->addService(svc); @@ -83,12 +88,41 @@ void add_services(erpc::SimpleServer *server) server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_Binary_service()); + service_test = create_Binary_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_Binary_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_builtin/test_builtin_client_impl.cpp b/test/test_builtin/test_builtin_client_impl.cpp index 322b7a7e5..47bc8a0a2 100644 --- a/test/test_builtin/test_builtin_client_impl.cpp +++ b/test/test_builtin/test_builtin_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test.h" + #include using namespace std; diff --git a/test/test_builtin/test_builtin_server_impl.cpp b/test/test_builtin/test_builtin_server_impl.cpp index b6ffd334b..25e86e046 100644 --- a/test/test_builtin/test_builtin_server_impl.cpp +++ b/test/test_builtin/test_builtin_server_impl.cpp @@ -1,18 +1,23 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +BuiltinServices_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -153,19 +158,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - BuiltinServices_service *svc = new BuiltinServices_service(); + svc = new BuiltinServices_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_BuiltinServices_service()); + service_test = create_BuiltinServices_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_BuiltinServices_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_callbacks/callbacks1.h b/test/test_callbacks/callbacks1.h index 57ef3c6ed..b1d511c73 100644 --- a/test/test_callbacks/callbacks1.h +++ b/test/test_callbacks/callbacks1.h @@ -6,6 +6,6 @@ * SPDX-License-Identifier: BSD-3-Clause */ -void callback1(int32_t a, int32_t b); +void callback1a(int32_t a, int32_t b); -void callback2(int32_t param1, int32_t param2); +void callback1b(int32_t param1, int32_t param2); diff --git a/test/test_callbacks/callbacks2.h b/test/test_callbacks/callbacks2.h index 3208ecead..f3f4120c8 100644 --- a/test/test_callbacks/callbacks2.h +++ b/test/test_callbacks/callbacks2.h @@ -6,4 +6,4 @@ * SPDX-License-Identifier: BSD-3-Clause */ -void callback3(int32_t param1, int32_t param2); +void callback2(int32_t param1, int32_t param2); diff --git a/test/test_callbacks/test_callbacks.erpc b/test/test_callbacks/test_callbacks.erpc index 45ae4da77..3c3aff2ec 100644 --- a/test/test_callbacks/test_callbacks.erpc +++ b/test/test_callbacks/test_callbacks.erpc @@ -12,25 +12,34 @@ import "../common/unit_test_common.erpc" oneway callback1_t(int32 a, int32 b) oneway callback2_t(int32, int32) +callback3_t(int32 arg1, int32 arg2) -> int32 @include("test_core1.h") @group("core0") interface ClientCore0Services { - myFun(in callback1_t pCallback1_t, out callback1_t pCallback2_t) -> void + myFun(in callback1_t pCallback1_in, out callback1_t pCallback1_out) -> void - myFun2(callback2_t pCallback1_t, out callback2_t pCallback2_t) -> void + myFun2(callback2_t pCallback2_in, out callback2_t pCallback2_out) -> void + + myFun3(callback3_t callback, in int32 arg1, in int32 arg2) -> int32 + + callback3_t my_add; + callback3_t my_sub; + callback3_t my_mul; + callback3_t my_div; @include("callbacks1.h") - callback1_t callback1; + callback1_t callback1a; + @include("callbacks1.h") - callback1_t callback2(param1, param2); + callback1_t callback1b(param1, param2); } @group("core1") interface ClientCore1Services { @include("callbacks2.h") - callback2_t callback3(param1, param2); + callback2_t callback2(param1, param2); } \ No newline at end of file diff --git a/test/test_callbacks/test_callbacks_client_impl.cpp b/test/test_callbacks/test_callbacks_client_impl.cpp index 11bb1291f..7b21043df 100644 --- a/test/test_callbacks/test_callbacks_client_impl.cpp +++ b/test/test_callbacks/test_callbacks_client_impl.cpp @@ -9,24 +9,47 @@ #include "test_core0.h" #include "test_core1_server.h" -void callback3(int32_t param1, int32_t param2) {} +void callback2(int32_t param1, int32_t param2) {} //////////////////////////////////////////////////////////////////////////////// // Unit test Implementation code //////////////////////////////////////////////////////////////////////////////// -TEST(test_callbacks, In_Out_table) +TEST(test_callbacks, In_Out_table_1) { - callback1_t pCallback2_t = NULL; - myFun(callback1, &pCallback2_t); + callback1_t pCallback1_out = NULL; + myFun(callback1a, &pCallback1_out); - EXPECT_TRUE(callback1 == *pCallback2_t); + EXPECT_TRUE(callback1a == *pCallback1_out); +} + +TEST(test_callbacks, In_Out_table_2) +{ + callback1_t pCallback1_out = NULL; + myFun(callback1b, &pCallback1_out); + + EXPECT_TRUE(callback1b == *pCallback1_out); } TEST(test_callbacks, In_Out_withoutTable) { - callback2_t pCallback2_t = NULL; - myFun2(callback3, &pCallback2_t); + callback2_t pCallback2_out = NULL; + myFun2(callback2, &pCallback2_out); - EXPECT_TRUE(callback3 == *pCallback2_t); + EXPECT_TRUE(callback2 == *pCallback2_out); } + +TEST(test_callbacks, Common_Callback) +{ + callback3_t callback = my_add; + EXPECT_TRUE(12 == myFun3(callback, 9, 3)); + + callback = my_sub; + EXPECT_TRUE(6 == myFun3(callback, 9, 3)); + + callback = my_mul; + EXPECT_TRUE(27 == myFun3(callback, 9, 3)); + + callback = my_div; + EXPECT_TRUE(3 == myFun3(callback, 9, 3)); +} \ No newline at end of file diff --git a/test/test_callbacks/test_callbacks_server_impl.cpp b/test/test_callbacks/test_callbacks_server_impl.cpp index 69bae214a..657c00478 100644 --- a/test/test_callbacks/test_callbacks_server_impl.cpp +++ b/test/test_callbacks/test_callbacks_server_impl.cpp @@ -1,52 +1,87 @@ /* - * Copyright 2017 NXP + * Copyright 2017 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_core0_server.h" #include "test_core1.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include +ClientCore0Services_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// -void myFun(const callback1_t pCallback1_t, callback1_t *pCallback2_t) +callback1_t *cb1 = NULL; +callback2_t *cb2 = NULL; + +void myFun(const callback1_t pCallback1_in, callback1_t *pCallback1_out) { - if (pCallback1_t == callback1) - { - *pCallback2_t = pCallback1_t; - } - else - { - *pCallback2_t = callback2; - } + cb1 = NULL; + pCallback1_in(1, 2); + *pCallback1_out = (callback1_t)cb1; } -void myFun2(const callback2_t pCallback1_t, callback2_t *pCallback2_t) +void myFun2(const callback2_t pCallback2_in, callback2_t *pCallback2_out) { - - if (pCallback1_t == callback3) - { - *pCallback2_t = pCallback1_t; - } - else - { - *pCallback2_t = NULL; - } + cb2 = NULL; + pCallback2_in(1, 2); + *pCallback2_out = (callback2_t)cb2; } -void callback1(int32_t a, int32_t b) {} +void callback1a(int32_t a, int32_t b) +{ + cb1 = (callback1_t *)callback1a; +} -void callback2(int32_t param1, int32_t param2) {} +void callback1b(int32_t param1, int32_t param2) +{ + cb1 = (callback1_t *)callback1b; +} /* will be shim code in real use case */ -void callback3(int32_t param1, int32_t param2) {} +void callback2(int32_t param1, int32_t param2) +{ + cb2 = (callback2_t *)callback2; +} + +int32_t myFun3(const callback3_t callback, int32_t arg1, int32_t arg2) +{ + return callback(arg1, arg2); +} + +int32_t my_add(int32_t arg1, int32_t arg2) +{ + return arg1 + arg2; +} + +int32_t my_sub(int32_t arg1, int32_t arg2) +{ + return arg1 - arg2; +} + +int32_t my_mul(int32_t arg1, int32_t arg2) +{ + return arg1 * arg2; +} + +int32_t my_div(int32_t arg1, int32_t arg2) +{ + if (arg2) + { + return arg1 / arg2; + } + return 0; +} //////////////////////////////////////////////////////////////////////////////// // Add service to server code @@ -56,19 +91,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - ClientCore0Services_service *svc = new ClientCore0Services_service(); + svc = new ClientCore0Services_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_ClientCore0Services_service()); + service_test = create_ClientCore0Services_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_ClientCore0Services_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_const/test_const_server_impl.cpp b/test/test_const/test_const_server_impl.cpp index 80465ad45..0cecb8a1d 100644 --- a/test/test_const/test_const_server_impl.cpp +++ b/test/test_const/test_const_server_impl.cpp @@ -1,14 +1,18 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include //////////////////////////////////////////////////////////////////////////////// @@ -22,18 +26,39 @@ void add_services(erpc::SimpleServer *server) { /* Define services to add using dynamic memory allocation - * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); - */ // NOTE: possible memory leak? not ever deleting + * Exapmle:ArithmeticService_service * svc = new ArithmeticService_service(); + */ /* Add services * Example: server->addService(svc); */ } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + + /* Delete unused service + */ +} + #ifdef __cplusplus extern "C" { #endif void add_services_to_server() {} +void remove_services_from_server() {} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); +} #ifdef __cplusplus } #endif diff --git a/test/test_enums/test_enums_server_impl.cpp b/test/test_enums/test_enums_server_impl.cpp index a1674022f..579584da9 100644 --- a/test/test_enums/test_enums_server_impl.cpp +++ b/test/test_enums/test_enums_server_impl.cpp @@ -1,17 +1,22 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include +EnumsService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -71,19 +76,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - EnumsService_service *svc = new EnumsService_service(); + svc = new EnumsService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_EnumsService_service()); + service_test = create_EnumsService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_EnumsService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_lists/test_lists_client_impl.cpp b/test/test_lists/test_lists_client_impl.cpp index f5bca8b5e..5c8a2e376 100644 --- a/test/test_lists/test_lists_client_impl.cpp +++ b/test/test_lists/test_lists_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test.h" + #include using namespace std; diff --git a/test/test_lists/test_lists_server_impl.cpp b/test/test_lists/test_lists_server_impl.cpp index b5175b4d6..9990d8aff 100644 --- a/test/test_lists/test_lists_server_impl.cpp +++ b/test/test_lists/test_lists_server_impl.cpp @@ -1,18 +1,23 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +PointersService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -312,19 +317,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - PointersService_service *svc = new PointersService_service(); + svc = new PointersService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_PointersService_service()); + service_test = create_PointersService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_PointersService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_shared/test_shared_server_impl.cpp b/test/test_shared/test_shared_server_impl.cpp index 1be335d3d..fb4388b8d 100644 --- a/test/test_shared/test_shared_server_impl.cpp +++ b/test/test_shared/test_shared_server_impl.cpp @@ -1,16 +1,21 @@ /* - * Copyright 2017 NXP + * Copyright 2017 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include +SharedService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -32,19 +37,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - SharedService_service *svc = new SharedService_service(); + svc = new SharedService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_SharedService_service()); + service_test = create_SharedService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_SharedService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_struct/test_struct_client_impl.cpp b/test/test_struct/test_struct_client_impl.cpp index 6eb54fc64..3a99fc4aa 100644 --- a/test/test_struct/test_struct_client_impl.cpp +++ b/test/test_struct/test_struct_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test_ArithmeticService.h" + #include using namespace std; diff --git a/test/test_struct/test_struct_server_impl.cpp b/test/test_struct/test_struct_server_impl.cpp index 9f9b2c467..be0b27160 100644 --- a/test/test_struct/test_struct_server_impl.cpp +++ b/test/test_struct/test_struct_server_impl.cpp @@ -1,18 +1,24 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_ArithmeticService_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +ArithmeticService1_service *svc1; +ArithmeticService2_service *svc2; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -181,22 +187,56 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - ArithmeticService1_service *svc1 = new ArithmeticService1_service(); - ArithmeticService2_service *svc2 = new ArithmeticService2_service(); + svc1 = new ArithmeticService1_service(); + svc2 = new ArithmeticService2_service(); // add services server->addService(svc1); server->addService(svc2); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc1); + server->removeService(svc2); + /* Delete unused service + */ + delete svc1; + delete svc2; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service1 = NULL; +erpc_service_t service2 = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_ArithmeticService1_service()); - erpc_add_service_to_server(create_ArithmeticService2_service()); + service1 = create_ArithmeticService1_service(); + service2 = create_ArithmeticService2_service(); + erpc_add_service_to_server(service1); + erpc_add_service_to_server(service2); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service1); + erpc_remove_service_from_server(service2); + destroy_ArithmeticService1_service(); + destroy_ArithmeticService2_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_typedef/test_typedef_client_impl.cpp b/test/test_typedef/test_typedef_client_impl.cpp index 44c5df4cb..6ab651523 100644 --- a/test/test_typedef/test_typedef_client_impl.cpp +++ b/test/test_typedef/test_typedef_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test.h" + #include //////////////////////////////////////////////////////////////////////////////// diff --git a/test/test_typedef/test_typedef_server_impl.cpp b/test/test_typedef/test_typedef_server_impl.cpp index 3b7642e8c..fbc04b456 100644 --- a/test/test_typedef/test_typedef_server_impl.cpp +++ b/test/test_typedef/test_typedef_server_impl.cpp @@ -1,18 +1,23 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016 - 2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +TypedefService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -132,19 +137,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - TypedefService_service *svc = new TypedefService_service(); + svc = new TypedefService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_TypedefService_service()); + service_test = create_TypedefService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_TypedefService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/test/test_unions/test_unions_client_impl.cpp b/test/test_unions/test_unions_client_impl.cpp index cc754a912..5d955d124 100644 --- a/test/test_unions/test_unions_client_impl.cpp +++ b/test/test_unions/test_unions_client_impl.cpp @@ -8,6 +8,7 @@ #include "gtest.h" #include "test.h" + #include using namespace std; diff --git a/test/test_unions/test_unions_server_impl.cpp b/test/test_unions/test_unions_server_impl.cpp index 94a86ef66..7c4f3907f 100644 --- a/test/test_unions/test_unions_server_impl.cpp +++ b/test/test_unions/test_unions_server_impl.cpp @@ -1,18 +1,23 @@ /* * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP + * Copyright 2016-2020 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "erpc_server_setup.h" + #include "test_server.h" +#include "test_unit_test_common_server.h" #include "unit_test.h" #include "unit_test_wrapped.h" + #include #include +ArithmeticService_service *svc; + //////////////////////////////////////////////////////////////////////////////// // Implementation of function code //////////////////////////////////////////////////////////////////////////////// @@ -22,8 +27,7 @@ gapGenericEvent_t *testGenericCallback(const gapGenericEvent_t *event) gapGenericEvent_t *newEvent = (gapGenericEvent_t *)erpc_malloc(sizeof(gapGenericEvent_t)); switch (event->eventType) { - case gInternalError_c: - { + case gInternalError_c: { if (event->eventData.internalError.errorCode == gBleSuccess_c && event->eventData.internalError.errorSource == gHciCommandStatus_c && event->eventData.internalError.hciCommandOpcode == 5) @@ -36,8 +40,7 @@ gapGenericEvent_t *testGenericCallback(const gapGenericEvent_t *event) } break; } - case gRandomAddressReady_c: - { + case gRandomAddressReady_c: { int x = 0xAA; int success = 1; int i = 0; @@ -60,8 +63,7 @@ gapGenericEvent_t *testGenericCallback(const gapGenericEvent_t *event) } break; } - case gWhiteListSizeReady_c: - { + case gWhiteListSizeReady_c: { newEvent->eventType = gTestCaseReturn_c; if (100 == event->eventData.whiteListSize) { @@ -76,8 +78,7 @@ gapGenericEvent_t *testGenericCallback(const gapGenericEvent_t *event) case gPublicAddressRead_c: case gAdvertisingSetupFailed_c: case gAdvTxPowerLevelRead_c: - default: - { + default: { } } return newEvent; @@ -88,8 +89,7 @@ foo *sendMyFoo(const foo *f) foo *newFoo = (foo *)erpc_malloc(sizeof(foo)); switch (f->discriminator) { - case apple: - { + case apple: { for (uint32_t i = 0; i < f->bing.myFoobar.rawString.dataLength; ++i) { if ((i + 1) != f->bing.myFoobar.rawString.data[i]) @@ -104,8 +104,7 @@ foo *sendMyFoo(const foo *f) erpc_free(f->bing.myFoobar.rawString.data); break; } - case banana: - { + case banana: { if ((f->bing.x == 3) && (f->bing.y == 4.0)) { newFoo->discriminator = papaya; @@ -120,8 +119,7 @@ foo *sendMyFoo(const foo *f) } break; } - case orange: - { + case orange: { for (uint32_t i = 1; i <= f->bing.a.elementsCount; ++i) { // If data sent across is incorrect, return 0x55 @@ -138,8 +136,7 @@ foo *sendMyFoo(const foo *f) erpc_free(f->bing.a.elements); break; } - default: - { + default: { break; } } @@ -152,8 +149,7 @@ foo *sendMyUnion(fruit discriminator, const unionType *unionVariable) foo *newFoo = (foo *)erpc_malloc(sizeof(foo)); switch (discriminator) { - case apple: - { + case apple: { for (uint32_t i = 0; i < unionVariable->myFoobar.rawString.dataLength; ++i) { if ((i + 1) != unionVariable->myFoobar.rawString.data[i]) @@ -167,8 +163,7 @@ foo *sendMyUnion(fruit discriminator, const unionType *unionVariable) newFoo->bing.ret = 0xAA; break; } - case banana: - { + case banana: { if ((unionVariable->x == 3) && (unionVariable->y == 4.0)) { newFoo->discriminator = papaya; @@ -183,8 +178,7 @@ foo *sendMyUnion(fruit discriminator, const unionType *unionVariable) } break; } - case orange: - { + case orange: { for (uint32_t i = 1; i <= unionVariable->a.elementsCount; ++i) { // If data sent across is incorrect, return 0x55 @@ -200,8 +194,7 @@ foo *sendMyUnion(fruit discriminator, const unionType *unionVariable) newFoo->bing.ret = 0xAA; break; } - default: - { + default: { break; } } @@ -222,19 +215,47 @@ void add_services(erpc::SimpleServer *server) { // define services to add on heap // allocate on heap so service doesn't go out of scope at end of method - // NOTE: possible memory leak? not ever deleting - ArithmeticService_service *svc = new ArithmeticService_service(); + svc = new ArithmeticService_service(); // add services server->addService(svc); } +//////////////////////////////////////////////////////////////////////////////// +// Remove service from server code +//////////////////////////////////////////////////////////////////////////////// + +void remove_services(erpc::SimpleServer *server) +{ + /* Remove services + * Example: server->removeService (svc); + */ + server->removeService(svc); + /* Delete unused service + */ + delete svc; +} + #ifdef __cplusplus extern "C" { #endif +erpc_service_t service_test = NULL; void add_services_to_server() { - erpc_add_service_to_server(create_ArithmeticService_service()); + service_test = create_ArithmeticService_service(); + erpc_add_service_to_server(service_test); +} + +void remove_services_from_server() +{ + erpc_remove_service_from_server(service_test); + destroy_ArithmeticService_service(); +} + +void remove_common_services_from_server(erpc_service_t service) +{ + erpc_remove_service_from_server(service); + destroy_Common_service(); } #ifdef __cplusplus } diff --git a/utilities/styles/VSC/.vscode/launch.json b/utilities/styles/VSC/.vscode/launch.json new file mode 100644 index 000000000..25f73a1b9 --- /dev/null +++ b/utilities/styles/VSC/.vscode/launch.json @@ -0,0 +1,15 @@ +// A launch configuration that launches the extension inside a new window +// Use IntelliSense to learn about possible attributes. +// Hover to view descriptions of existing attributes. +// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 +{ + "version": "1.0.0", + "configurations": [{ + "name": "Debug eRPC syntax highlighting", + "type": "extensionHost", + "request": "launch", + "args": [ + "--extensionDevelopmentPath=${workspaceFolder}" + ] + }] +} diff --git a/utilities/styles/VSC/.vscodeignore b/utilities/styles/VSC/.vscodeignore new file mode 100644 index 000000000..f369b5e55 --- /dev/null +++ b/utilities/styles/VSC/.vscodeignore @@ -0,0 +1,4 @@ +.vscode/** +.vscode-test/** +.gitignore +vsc-extension-quickstart.md diff --git a/utilities/styles/VSC/CHANGELOG.md b/utilities/styles/VSC/CHANGELOG.md new file mode 100644 index 000000000..55784e862 --- /dev/null +++ b/utilities/styles/VSC/CHANGELOG.md @@ -0,0 +1,9 @@ +# Change Log + +All notable changes to the "erpc-code-style" extension will be documented in this file. + +Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. + +## [Unreleased] + +- Initial release \ No newline at end of file diff --git a/utilities/styles/VSC/README.md b/utilities/styles/VSC/README.md new file mode 100644 index 000000000..7dc984ce3 --- /dev/null +++ b/utilities/styles/VSC/README.md @@ -0,0 +1,38 @@ +# erpc-code-style README + +This exension formats code for eRPC related files. More about eRPC project is described on webpage: https://github.com/EmbeddedRPC/erpc + +This extension was created thankfully this page and author of post: +https://gcthesoftwareengineer.com/2017/01/how-to-create-custom-syntax-highlighting-in-a-visual-studio-code-extension/ + + +## Features + +This extension format erpc idl files and cpptemplate related files. + +eRPC IDL example: +![eRPC IDL example](img/erpcPic.png) + +template example: +![cpptemplate example](img/templatePic.png) + + +## Requirements + +-- + +## Extension Settings + +-- + +## Known Issues + +-- + +## Release Notes + + +### 1.0.0 + +Initial release + - Covering most of usecases. Still some need be covered. diff --git a/utilities/styles/VSC/img/erpcPic.png b/utilities/styles/VSC/img/erpcPic.png new file mode 100644 index 000000000..099510b9e Binary files /dev/null and b/utilities/styles/VSC/img/erpcPic.png differ diff --git a/utilities/styles/VSC/img/templatePic.png b/utilities/styles/VSC/img/templatePic.png new file mode 100644 index 000000000..4a09def19 Binary files /dev/null and b/utilities/styles/VSC/img/templatePic.png differ diff --git a/utilities/styles/VSC/language-configuration.json b/utilities/styles/VSC/language-configuration.json new file mode 100644 index 000000000..8f162a0c4 --- /dev/null +++ b/utilities/styles/VSC/language-configuration.json @@ -0,0 +1,30 @@ +{ + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "//", + // symbols used for start and end a block comment. Remove this entry if your language does not support block comments + "blockComment": [ "/*", "*/" ] + }, + // symbols used as brackets + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that can be used to surround a selection + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +} \ No newline at end of file diff --git a/utilities/styles/VSC/package.json b/utilities/styles/VSC/package.json new file mode 100644 index 000000000..ae0e22036 --- /dev/null +++ b/utilities/styles/VSC/package.json @@ -0,0 +1,39 @@ +{ + "publisher": "Hadatko", + "name": "erpc-code-style", + "displayName": "ERPC code style", + "description": "Formatting code relevant to eRPC language", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/EmbeddedRPC/erpc.git" + }, + "engines": { + "vscode": "^1.49.0" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [{ + "id": "erpc", + "aliases": ["erpc", "erpc"], + "extensions": [".erpc"], + "configuration": "./language-configuration.json" + }, { + "id": "template", + "aliases": ["template", "template"], + "extensions": [".template"], + "configuration": "./language-configuration.json" + }], + "grammars": [{ + "language": "erpc", + "scopeName": "source.erpc", + "path": "./syntaxes/erpc.tmLanguage.json" + }, { + "language": "template", + "scopeName": "source.template", + "path": "./syntaxes/template.tmLanguage.json" + }] + } +} diff --git a/utilities/styles/VSC/syntaxes/erpc.tmLanguage.json b/utilities/styles/VSC/syntaxes/erpc.tmLanguage.json new file mode 100644 index 000000000..76714bc5e --- /dev/null +++ b/utilities/styles/VSC/syntaxes/erpc.tmLanguage.json @@ -0,0 +1,174 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "erpc", + "patterns": [{ + "include": "#multilineCommentsDocument" + }, { + "include": "#multilineCommentsDocument2" + }, + { + "include": "#multilineComments" + }, + { + "include": "#comments" + }, + { + "include": "#annotations" + }, + { + "include": "#enums" + }, + { + "include": "#structs" + }, + { + "include": "#structsMembers" + }, + { + "include": "#members" + }, + { + "include": "#typeNames" + }, + { + "include": "#functionTypeNames" + }, + { + "include": "#returnTypes" + }, + { + "include": "#keywords" + }, + { + "include": "#strings" + } + ], + "repository": { + "keywords": { + "patterns": [{ + "name": "keyword.control.erpc", + "match": "\\b(const|enum|in|inout|interface|oneway|out|program|struct|type)\\b" + }, { + "name": "entity.name.type", + "match": "\\b(binary|bool|uint8|uint16|uint32|int8|int16|int32|void)\\b" + }, { + "name": "keyword.other.erpc", + "match": "[{}(),=\\->;\\[\\]+*/;]" + }] + }, + "strings": { + "name": "string.quoted.double.erpc", + "begin": "\"", + "end": "\"", + "patterns": [{ + "name": "constant.character.escape.erpc", + "match": "\\\\." + }] + }, + "comments": { + "name": "comment.line.erpc", + "match": "\\\\.*" + }, + "multilineCommentsDocument": { + "name": "comment.block.erpc", + "begin": "/\\*\\*", + "end": "\\*/" + }, + "multilineCommentsDocument2": { + "name": "comment.block.erpc", + "begin": "/\\*\\!", + "end": "\\*/" + }, + "multilineComments": { + "name": "comment.block.erpc", + "begin": "/\\*", + "end": "\\*/" + }, + "annotations": { + "name": "support.property-value.erpc", + "begin": "@[^\\(]*\\(", + "end": "\\)", + "patterns": [{ + "name": "string.quoted.double.erpc", + "match": "\"[^)]*" + }, { + "name": "string.unquoted.erpc", + "match": "[^\")][^)]*" + }] + }, + "enums": { + "name": "keyword.control.erpc", + "match": "enum\\s*([a-zA-Z0-9_]+)", + "captures": { + "1": { + "name": "entity.name.type.erpc" + } + } + }, + "structs": { + "name": "keyword.control.erpc", + "match": "struct\\s*([a-zA-Z0-9_]+)", + "captures": { + "1": { + "name": "entity.name.type.erpc" + } + } + }, + "structsMembers": { + "name": "variable.name", + "match": "([a-zA-Z0-9_]*)\\s([a-zA-Z0-9_]*)(;)", + "captures": { + "1": { + "name": "entity.name.type.erpc" + }, + "3": { + "name": "keyword.other.erpc" + } + } + }, + "typeNames": { + "name": "keyword.control.erpc", + "match": "type\\s[^=]*", + "captures": { + "0": { + "patterns": [{ + "name": "entity.name.type.erpc", + "match": "\\s.*" + }] + } + } + }, + "functionTypeNames": { + "name": "keyword.other.erpc", + "begin": "\\(", + "end": "\\)", + "patterns": [{ + "name": "", + "match": "(in\\s|out\\s|inout\\s)?([a-zA-Z0-9_\\[\\]]+\\s)([a-zA-Z0-9_]+)", + "captures": { + "1": { + "name": "keyword.control.erpc" + }, + "2": { + "name": "entity.name.type.erpc" + }, + "3": { + "name": "variable.name.erpc" + } + } + }] + }, + "returnTypes": { + "match": "(->)\\s*([a-zA-Z0-9_]*)", + "captures": { + "1": { + "name": "keyword.other.erpc" + }, + "2": { + "name": "entity.name.type.erpc" + } + } + } + }, + "scopeName": "source.erpc" +} diff --git a/utilities/styles/VSC/syntaxes/template.tmLanguage.json b/utilities/styles/VSC/syntaxes/template.tmLanguage.json new file mode 100644 index 000000000..cef0700b9 --- /dev/null +++ b/utilities/styles/VSC/syntaxes/template.tmLanguage.json @@ -0,0 +1,65 @@ +{ + "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json", + "name": "template", + "patterns": [{ + "include": "#condition" + }, { + "include": "#variable" + }, { + "include": "#variable" + }], + "repository": { + "condition": { + "name": "", + "match": "{%[^}]*}", + "captures": { + "0": { + "name": "", + "patterns": [{ + "name": "comment.line", + "match": "({%)\\s*([a-zA-Z0-9_]*)([^-%>]*)?([^}]*})", + "captures": { + "1": { + "name": "comment.line" + }, + "2": { + "name": "keyword.control" + }, + "3": { + "name": "entity.name.function" + }, + "4": { + "name": "comment.line" + } + } + }] + } + } + }, + "variable": { + "name": "", + "match": "{\\$[^}]*}", + "captures": { + "0": { + "name": "", + "patterns": [{ + "name": "comment.line", + "match": "({\\$>?)\\s*([^>}]*)(>?})", + "captures": { + "1": { + "name": "comment.line" + }, + "2": { + "name": "variable.other" + }, + "3": { + "name": "comment.line" + } + } + }] + } + } + } + }, + "scopeName": "source.template" +} diff --git a/utilities/styles/VSC/vsc-extension-quickstart.md b/utilities/styles/VSC/vsc-extension-quickstart.md new file mode 100644 index 000000000..1ae0d0a62 --- /dev/null +++ b/utilities/styles/VSC/vsc-extension-quickstart.md @@ -0,0 +1,29 @@ +# Welcome to your VS Code Extension + +## What's in the folder + +* This folder contains all of the files necessary for your extension. +* `package.json` - this is the manifest file in which you declare your language support and define the location of the grammar file that has been copied into your extension. +* `syntaxes/erpc.tmLanguage.json` - this is the Text mate grammar file that is used for tokenization. +* `language-configuration.json` - this is the language configuration, defining the tokens that are used for comments and brackets. + +## Get up and running straight away + +* Make sure the language configuration settings in `language-configuration.json` are accurate. +* Press `F5` to open a new window with your extension loaded. +* Create a new file with a file name suffix matching your language. +* Verify that syntax highlighting works and that the language configuration settings are working. + +## Make changes + +* You can relaunch the extension from the debug toolbar after making changes to the files listed above. +* You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. + +## Add more language features + +* To add features such as intellisense, hovers and validators check out the VS Code extenders documentation at https://code.visualstudio.com/docs + +## Install your extension + +* To start using your extension with Visual Studio Code copy it into the `/.vscode/extensions` folder and restart Code. +* To share your extension with the world, read on https://code.visualstudio.com/docs about publishing an extension.