diff --git a/UNITTESTS/CMakeLists.txt b/UNITTESTS/CMakeLists.txt index d149c3c..612155a 100644 --- a/UNITTESTS/CMakeLists.txt +++ b/UNITTESTS/CMakeLists.txt @@ -114,6 +114,7 @@ "${PROJECT_SOURCE_DIR}/../features" "${PROJECT_SOURCE_DIR}/../platform/include" "${PROJECT_SOURCE_DIR}/../platform/include/platform" + "${PROJECT_SOURCE_DIR}/../platform/mbed-trace/include" "${PROJECT_SOURCE_DIR}/../storage/filesystem/littlefs/include" "${PROJECT_SOURCE_DIR}/../storage/filesystem/fat/include" "${PROJECT_SOURCE_DIR}/../storage/blockdevice/include" @@ -132,7 +133,6 @@ "${PROJECT_SOURCE_DIR}/../events/source" "${PROJECT_SOURCE_DIR}/../rtos/include" "${PROJECT_SOURCE_DIR}/../features/frameworks" - "${PROJECT_SOURCE_DIR}/../features/frameworks/mbed-trace" "${PROJECT_SOURCE_DIR}/../connectivity/libraries/nanostack-libservice" "${PROJECT_SOURCE_DIR}/../connectivity/libraries/nanostack-libservice/mbed-client-libservice" "${PROJECT_SOURCE_DIR}/../connectivity/netsocket/include" diff --git a/UNITTESTS/empty_baseline/unittest.cmake b/UNITTESTS/empty_baseline/unittest.cmake index 88fc349..e4b8499 100644 --- a/UNITTESTS/empty_baseline/unittest.cmake +++ b/UNITTESTS/empty_baseline/unittest.cmake @@ -8,7 +8,7 @@ .. ../connectivity/mbedtls/include/mbedtls/ ../connectivity/mbedtls/platform/inc/ - ../features/frameworks/mbed-trace/mbed-trace/ + ../platform/mbed-trace/mbed-trace/ ) set(unittest-test-sources diff --git a/connectivity/drivers/cellular/COMPONENT_STMOD_CELLULAR/README.md b/connectivity/drivers/cellular/COMPONENT_STMOD_CELLULAR/README.md index 4ce8070..395acc3 100644 --- a/connectivity/drivers/cellular/COMPONENT_STMOD_CELLULAR/README.md +++ b/connectivity/drivers/cellular/COMPONENT_STMOD_CELLULAR/README.md @@ -13,7 +13,7 @@ ## Debug print -mbed_trace feature is used: https://github.com/ARMmbed/mbed-os/blob/master/features/frameworks/mbed-trace/README.md +mbed_trace feature is used: https://github.com/ARMmbed/mbed-os/blob/master/platform/mbed-trace/README.md Enable it in your mbed_app.json file: diff --git a/drivers/source/SFDP.cpp b/drivers/source/SFDP.cpp index 193c707..745f4b0 100644 --- a/drivers/source/SFDP.cpp +++ b/drivers/source/SFDP.cpp @@ -26,7 +26,7 @@ #if (DEVICE_SPI || DEVICE_QSPI) -#include "features/frameworks/mbed-trace/mbed-trace/mbed_trace.h" +#include "platform/mbed-trace/mbed-trace/mbed_trace.h" #define TRACE_GROUP "SFDP" namespace { diff --git a/features/frameworks/mbed-trace/.gitignore b/features/frameworks/mbed-trace/.gitignore deleted file mode 100644 index f55542c..0000000 --- a/features/frameworks/mbed-trace/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -yotta_modules/ -yotta_targets/ -build/ -test_coverage/ -**/*.info -**/*~ -output/* - -# Yotta files -.yotta.json diff --git a/features/frameworks/mbed-trace/.mbedignore b/features/frameworks/mbed-trace/.mbedignore deleted file mode 100644 index 67ab365..0000000 --- a/features/frameworks/mbed-trace/.mbedignore +++ /dev/null @@ -1,5 +0,0 @@ -build/* -yotta_modules/* -yotta_targets/* -test/* -example/* diff --git a/features/frameworks/mbed-trace/CMakeLists.txt b/features/frameworks/mbed-trace/CMakeLists.txt deleted file mode 100644 index 86396b4..0000000 --- a/features/frameworks/mbed-trace/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -INCLUDE(CMakeForceCompiler) - -cmake_minimum_required (VERSION 2.8) -SET(CMAKE_SYSTEM_NAME Generic) - -project(mbedTrace) - - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mbed-trace/) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../nanostack-libservice/mbed-client-libservice/) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../nanostack-libservice/) - -set (MBED_TRACE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/source/mbed_trace.c) - - -CREATE_LIBRARY(mbedTrace "${MBED_TRACE_SRC}" "") - diff --git a/features/frameworks/mbed-trace/CONTRIBUTING.md b/features/frameworks/mbed-trace/CONTRIBUTING.md deleted file mode 100644 index be25df1..0000000 --- a/features/frameworks/mbed-trace/CONTRIBUTING.md +++ /dev/null @@ -1,9 +0,0 @@ -# Hello! -We are an open source project of [ARM mbed](www.mbed.com). Contributions via [pull request](https://github.com/armmbed/mbed-client-trace/pulls), and [bug reports](https://github.com/armmbed/mbed-client-trace/issues) are welcome! - -For more details please see our general [CONTRIBUTING.md](https://github.com/ARMmbed/greentea/blob/master/docs/CONTRIBUTING.md) document. - -# Contributor agreement -For your pull request to be accepted, we will need you to agree to our [contributor agreement](http://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.) - -<3 diff --git a/features/frameworks/mbed-trace/Jenkinsfile b/features/frameworks/mbed-trace/Jenkinsfile deleted file mode 100644 index 2793e1c..0000000 --- a/features/frameworks/mbed-trace/Jenkinsfile +++ /dev/null @@ -1,279 +0,0 @@ -echo "Start to build" - -properties ([ - buildDiscarder( - logRotator( - artifactNumToKeepStr: '10', - numToKeepStr: '100' - ) - ) -]) - -// List of targets to compile -def morpheusTargets = [ - //"LPC1768", - //"NUCLEO_F401RE", - "K64F" -] -// Map morpheus toolchains to compiler labels on Jenkins -def toolchains = [ - ARM: "armcc", - IAR: "iar_arm", - GCC_ARM: "arm-none-eabi-gcc" -] -// yotta target includes toolchain -def yottaTargets = [ - "frdm-k64f-gcc": "gcc", - "frdm-k64f-armcc": "armcc", - "stm32f429i-disco-gcc": "gcc", - "x86-linux-native": "linux && astyle" -] - -// Initial maps for parallel build steps -def stepsForParallel = [:] -// Jenkins pipeline does not support map.each, we need to use oldschool for loop -for (int i = 0; i < morpheusTargets.size(); i++) { - for(int j = 0; j < toolchains.size(); j++) { - def target = morpheusTargets.get(i) - def toolchain = toolchains.keySet().asList().get(j) - def compilerLabel = toolchains.get(toolchain) - def stepName = "mbed-os5-${target} ${toolchain}" - stepsForParallel[stepName] = morpheusBuildStep(target, compilerLabel, toolchain) - } -} -// map yotta steps -for (int i = 0; i < yottaTargets.size(); i++) { - def target = yottaTargets.keySet().asList().get(i) - def compilerLabel = yottaTargets.get(target) - def stepName = "mbed-os3-${target}" - stepsForParallel[stepName] = yottaBuildStep(target, compilerLabel) -} - -/* Jenkins does not allow stages inside parallel execution, - * https://issues.jenkins-ci.org/browse/JENKINS-26107 will solve this by adding labeled blocks - */ -// Actually run the steps in parallel - parallel takes a map as an argument, hence the above. -timestamps { - timeout(time: 30, unit: "MINUTES") { - parallel stepsForParallel - } -} - -def execute(cmd) { - if(isUnix()) { - sh "${cmd}" - } else { - bat "${cmd}" - } -} - -//Create morpheus build steps for parallel execution -def morpheusBuildStep(target, compilerLabel, toolchain) { - return { - node ("${compilerLabel}") { - deleteDir() - dir("mbed-trace") { - String buildName = "mbed-os5-${target}-${toolchain}" - def scmVars = checkout scm - env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT - setBuildStatus('PENDING', "build ${buildName}", 'build starts') - stage ("build:${buildName}") { - try{ - execute("mbed --version") - execute("echo https://github.com/armmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 > mbed-os.lib") - execute("mbed deploy") - execute("rm -rf ./mbed-os/features/frameworks/mbed-trace") - execute("mbed compile -m ${target} -t ${toolchain} --library") - setBuildStatus('SUCCESS', "build ${buildName}", "build done") - } catch (err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "build ${buildName}", "build failed") - throw err - } - } - stage("build:example:${buildName}") { - execute("mkdir ../example-mbed-os-5 || true") - execute("cp -R example/mbed-os-5 ../example-mbed-os-5") - dir("../example-mbed-os-5") { - def exampleName = "example-${buildName}" - setBuildStatus('PENDING', "build ${exampleName}", 'build starts') - try { - execute("echo \"https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9\" > mbed-os.lib") - execute("echo \"https://github.com/ARMmbed/mbed-trace#${env.GIT_COMMIT_HASH}\" > mbed-trace.lib") - execute("mbed new .") - execute("mbed deploy") - execute("rm -rf ./mbed-os/features/frameworks/mbed-trace") - execute("rm -rf ./mbed-trace/example") - execute("rm -rf ./mbed-trace/test") - execute("mbed compile -t ${toolchain} -m ${target}") - setBuildStatus('SUCCESS', "build ${exampleName}", "build done") - } catch(err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "build ${exampleName}", "build failed") - currentBuild.result = 'FAILURE' - } finally { - // clean up - postBuild(buildName, false) - step([$class: 'WsCleanup']) - } - } - } - } - } - } -} - -//Create yotta build steps for parallel execution -def yottaBuildStep(target, compilerLabel) { - return { - String buildName = "mbed-os3-${target}" - node ("${compilerLabel}") { - deleteDir() - dir("mbed-trace") { - def scmVars = checkout scm - env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT - def isTest = target == "x86-linux-native" // tests are valid only in linux target - stage ("build:${buildName}") { - setBuildStatus('PENDING', "build ${buildName}", 'build starts') - try{ - execute("yotta --version") - execute("yotta target $target") - execute("yotta --plain build mbed-trace") - setBuildStatus('SUCCESS', "build ${buildName}", "build done") - } catch (err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "build ${buildName}", "build failed") - currentBuild.result = 'FAILURE' - } - } // stage - if (isTest) { - stage("test:${buildName}") { - setBuildStatus('PENDING', "test ${buildName}", 'test starts') - try { - execute("yotta test mbed_trace_test") - execute("lcov --base-directory . --directory . --capture --output-file coverage.info") - execute("genhtml -o ./test_coverage coverage.info") - execute("gcovr -x -o junit.xml") - execute("cppcheck --enable=all --std=c99 --inline-suppr --template=\"{file},{line},{severity},{id},{message}\" source 2> cppcheck.txt") - - // check if astyle is correct - execute("astyle --options=.astylerc source/*.c mbed-trace/*.h") - // check differency - execute("git diff-index -p --exit-code HEAD") - - setBuildStatus('SUCCESS', "test ${buildName}", "test done") - } catch(err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "test ${buildName}", "test failed") - currentBuild.result = 'FAILURE' - } - } // stage - stage("example:${buildName}") { - dir("example/linux") { - def exampleName = "example-linux" - setBuildStatus('PENDING', "build ${exampleName}", 'build starts') - try { - execute("make") - setBuildStatus('SUCCESS', "build ${exampleName}", "build done") - } catch(err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "build ${exampleName}", "build failed") - currentBuild.result = 'FAILURE' - } - } - } // stage - - stage("leak-check:${buildName}") { - dir("example/linux") { - def stageName = "leak-check" - setBuildStatus('PENDING', "test ${stageName}", 'test starts') - try { - execute("./memtest.sh") - setBuildStatus('SUCCESS', "test ${stageName}", "test done") - } catch(err) { - echo "Caught exception: ${err}" - setBuildStatus('FAILURE', "test ${stageName}", "test failed") - currentBuild.result = 'FAILURE' - } - } - } // stage - } // if linux - postBuild(buildName, isTest) - step([$class: 'WsCleanup']) - } // dir - } - } -} - -def postBuild(buildName, isTest) { - // move files to target+toolchain specific folder - execute("mkdir -p output/${buildName}") - execute("find . -name 'libmbed-trace.a' -exec mv {} 'output/${buildName}' \\;") - execute("find . -name 'mbed-trace.ar' -exec mv {} 'output/${buildName}' \\;") - execute("find ../example-mbed-os-5 -name 'example-mbed-os-5.bin' -exec mv {} 'output/${buildName}/example-mbed-os-5.bin' \\; || true") - // Archive artifacts - step([ - $class: 'ArtifactArchiver', - artifacts: "cppcheck.txt,output/**", - fingerprint: true, - allowEmptyArchive: true - ]) - if (isTest) { - // Publish cobertura - step([ - $class: 'CoberturaPublisher', - coberturaReportFile: 'junit.xml' - ]) - // Publish compiler warnings - step([ - $class: 'WarningsPublisher', - parserConfigurations: [[ - parserName: 'GNU Make + GNU C Compiler (gcc)', - pattern: 'mbed-trace/*.h,source/*.c,test/*.cpp' - ]], - unstableTotalAll: '0', - useDeltaValues: true, - usePreviousBuildAsReference: true - ]) - // Publish HTML reports - publishHTML(target: [ - alwayLinkToLastBuild: false, - keepAll: true, - reportDir: "test_coverage", - reportFiles: "index.html", - reportName: "Build HTML Report" - ]) - } -} -// helper function to set build status to github PR -def setBuildStatus(String state, String context, String message) { - step([ - $class: "GitHubCommitStatusSetter", - reposSource: [ - $class: "ManuallyEnteredRepositorySource", - url: "https://github.com/ARMmbed/mbed-trace.git" - ], - contextSource: [ - $class: "ManuallyEnteredCommitContextSource", - context: context - ], - errorHandlers: [[ - $class: "ChangingBuildStatusErrorHandler", - result: "UNSTABLE" - ]], - commitShaSource: [ - $class: "ManuallyEnteredShaSource", - sha: env.GIT_COMMIT_HASH - ], - statusResultSource: [ - $class: 'ConditionalStatusResultSource', - results: [ - [ - $class: 'AnyBuildResult', - message: message, - state: state - ] - ] - ] - ]) -} diff --git a/features/frameworks/mbed-trace/LICENSE b/features/frameworks/mbed-trace/LICENSE deleted file mode 100644 index 5c304d1..0000000 --- a/features/frameworks/mbed-trace/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ -Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/features/frameworks/mbed-trace/Makefile.nanomesh b/features/frameworks/mbed-trace/Makefile.nanomesh deleted file mode 100644 index efd7820..0000000 --- a/features/frameworks/mbed-trace/Makefile.nanomesh +++ /dev/null @@ -1,5 +0,0 @@ -SRCS := $(wildcard source/*.c) -LIB := libmbed-trace.a -EXPORT_HEADERS := mbed-trace - -include ../exported_rules.mk diff --git a/features/frameworks/mbed-trace/README.md b/features/frameworks/mbed-trace/README.md deleted file mode 100644 index 203759c..0000000 --- a/features/frameworks/mbed-trace/README.md +++ /dev/null @@ -1,278 +0,0 @@ -# mbed-trace - -A general purpose tracing abstraction library for mbed devices. - -## Description - -The purpose of the library is to provide a light, simple and general tracing solution for mbed devices. By default, it prints traces to `stdout` (usually, a serial port), but the output can also be redirected to other targets. The library was developed using ANSI C language, but it can be used with C++ as well. Currently, there is no C++ wrapper available, but it can be created easily on top of this library. - -## Philosophy - -* The library needs to be light, fast, simple and abstract. -* Dependencies must be minimal. -* The memory space required by the library is allocated at the initialization only once during the application lifetime. -* No new malloc/free are needed when running the library. -* The trace methods must be as fast as possible. -* After a trace method call, the trace function needs to release the required resources. -* A trace method call produces a single line containing ``, `` and `` -* It must be possible to filter messages on the fly. Compile time filtering is not fully supported yet. - -## Compromises - -* The traces are stored as ASCII arrays in the flash memory (pretty high memory consumption). Therefore, it is not necessary to: - * encode/decode the trace messages on the fly (this may take too much CPU time) or - * have external dev-env dependencies to encode the traces compile time and an external application to decode the traces. -* The group name length is limited to four characters. This makes the lines cleaner and it is enough for most use cases for separating the module names. The group name length may not be suitable for a clean human readable format, but still four characters is enough for unique module names. -* The trace function uses `stdout` as the default output target because it goes directly to serial port in mbed-os. -* The trace function produces traces like: `[][grp ]: msg`. This provides an easy way to detect trace prints and separate traces from normal prints (for example with _regex_). -* This approach requires a `sprintf` implementation (`stdio.h`). The memory consumption is pretty high, but it allows an efficient way to format traces. -* The solution is not Interrupt safe. ([PRs](https://github.com/ARMmbed/mbed-trace/pulls) are more than welcome.) -* The solution is not thread safe by default. Thread safety for the actual trace calls can be enabled by providing wait and release callback functions that use mutexes defined by the application. - -## Examples of traces - -``` -[DBG ][abc ]: This is a debug message from module abc -[INFO][br ]: Hi there. -[WARN][br ]: Oh no, br warning occurs! -[ERR ][abc ]: Something goes wrong in module abc -``` - -## Usage - -### Prerequisites - -* Initialize the serial port so that `stdout` works. You can verify that the serial port works using the `printf()` function. - * If you want to redirect the traces somewhere else, see the [trace API](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h#L245). -* To enable the tracing API: - * With yotta: set `YOTTA_CFG_MBED_TRACE` to 1 or true. Setting the flag to 0 or false disables tracing. - * [With mbed OS 5](#enabling-the-tracing-api-in-mbed-os-5) -* By default, trace uses 1024 bytes buffer for trace lines, but you can change it by setting the configuration macro `MBED_TRACE_LINE_LENGTH` to the desired value. -* To disable the IPv6 conversion: - * With yotta: set `YOTTA_CFG_MBED_TRACE_FEA_IPV6 = 0`. - * With mbed OS 5: set `MBED_CONF_MBED_TRACE_FEA_IPV6 = 0`. -* If thread safety is needed, configure the wait and release callback functions before initialization to enable the protection. Usually, this needs to be done only once in the application's lifetime. - * If [helping functions](#helping-functions) are used the mutex must be **recursive** (counting) so it can be acquired from a single thread repeatedly. -* Call the trace initialization (`mbed_trace_init`) once before using any other APIs. It allocates the trace buffer and initializes the internal variables. -* Define `TRACE_GROUP` in your **source code (not in the header)** to use traces. It is a 1-4 characters long char-array (for example `#define TRACE_GROUP "APPL"`). This will be printed on every trace line. - -### Enabling the tracing API in mbed OS 5 - -* Set `MBED_CONF_MBED_TRACE_ENABLE` to 1 or true - -To do so, add the following to your mbed_app.json: - -```json -{ - "target_overrides": { - "*": { - "mbed-trace.enable": 1 - } - } -} -``` - -Do not forget to fulfill the other [prerequisites](#prerequisites)! - -([Click here for more information on the configuration system](https://docs.mbed.com/docs/mbed-os-api/en/latest/config_system/)) - - -## Examples - -* [mbed-os-5](example/mbed-os-5) -* [linux](example/linux) - -### Traces - -When you want to print traces, use the `tr_` macros. The macros behave like `printf()`. For example, -`tr_debug("hello %s", "trace")` produces the following trace line: `[DBG ][APPL] hello trace`. - -Available levels: - -* debug -* info -* warning -* error -* cmdline (special behavior, should not be used) - -For the thread safety, set the mutex wait and release functions. You need do this before the initialization to have the functions available right away: - -```c -mbed_trace_mutex_wait_function_set(my_mutex_wait); -mbed_trace_mutex_release_function_set(my_mutex_release); -``` - -Initialization (once in application's lifetime): - -```c -int mbed_trace_init(void); -``` - -Set the output function, `printf` by default: - -```c -mbed_trace_print_function_set(printf) -``` - -### Tracing level - -Run time tracing level is set using `mbed_trace_set_config()` function. Possible levels and examples how to set them is presented below. - -```c -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_ALL); -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_DEBUG); // (same as ALL) -mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO); -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_WARN); -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_ERROR); -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_CMD); -//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_NONE); -``` - -Build time optimization can be done with `MBED_TRACE_MAX_LEVEL` definition. Setting max level to `TRACE_LEVEL_DEBUG` includes all traces to the build. Setting max level to `TRACE_LEVEL_INFO` includes all but `tr_debug()` traces to the build. Other maximum tracing levels follow the same behavior and no messages above the selected level are included in the build. - -```c -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_DEBUG -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_WARN -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_ERROR -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_CMD -``` - -In Mbed OS, the build time maximum tracing level can be set through `mbed_app.json` as shown below. - -``` -{ - "target_overrides":{ - "*":{ - "mbed-trace.enable": true, - "mbed-trace.max-level": "TRACE_LEVEL_INFO" - } - } -} -``` - -When max-level is not set by the application, default level is INFO. - -### Helping functions - -The purpose of the helping functions is to provide simple conversions, -for example from an array to C string, so that you can print everything to single trace line. -They must be called inside the actual trace calls, for example: - -``` -tr_debug("My IP6 address: %s", mbed_trace_ipv6(addr)); -``` - -Available conversion functions: - -``` -char *mbed_trace_ipv6(const void *addr_ptr) -char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) -char *mbed_trace_array(const uint8_t *buf, uint16_t len) -``` - -See more in [mbed_trace.h](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h). - - -## Usage example: - -```c++ -#define MBED_CONF_MBED_TRACE_ENABLE 1 //this could be defined also in the mbed-cli configuration file mbed_app.json -#include "mbed-trace/mbed_trace.h" -#define TRACE_GROUP "main" - - // These are necessary only if thread safety is needed -static Mutex MyMutex; -static void my_mutex_wait() -{ - MyMutex.lock(); -} -static void my_mutex_release() -{ - MyMutex.unlock(); -} - -int main(void){ - mbed_trace_mutex_wait_function_set( my_mutex_wait ); // only if thread safety is needed - mbed_trace_mutex_release_function_set( my_mutex_release ); // only if thread safety is needed - mbed_trace_init(); // initialize the trace library - tr_debug("this is debug msg"); //-> "[DBG ][main]: this is a debug msg" - tr_info("this is info msg"); //-> "[INFO][main]: this is an info msg" - tr_warn("this is warning msg"); //-> "[WARN][main]: this is a warning msg" - tr_err("this is error msg"); //-> "[ERR ][main]: this is an error msg" - char arr[] = {30, 31, 32}; - tr_debug("printing array: %s", mbed_trace_array(arr, 3)); //-> "[DBG ][main]: printing array: 01:02:03" - return 0; -} -``` - -## Run-time trace group filtering - -The trace groups you have defined using the `TRACE_GROUP` macro in your .c/.cpp files can be used to control tracing at run-time. - -| Function | Explanation | -|-----------------------------------|--------------------------------------------------------------| -|`mbed_trace_include_filters_get()` | Get the exclusion filter list string. | -|`mbed_trace_include_filters_set()` | Set trace list to include only the traces matching the list. | -|`mbed_trace_exclude_filters_get()` | Get the inclusion filter list string. | -|`mbed_trace_exclude_filters_set()` | Set trace list to exclude the traces matching the list. | - -The filter list is a null terminated string of comma (`,`) separated trace group names. The default maximum length of the string is 24 characters, including the terminating null. Length can be changed by defining the macro `DEFAULT_TRACE_FILTER_LENGTH`. Exclude and include filters can be combined freely as they both have their own filtering list. - -The matching is done simply using `strstr()` from C standard libraries. - -### Examples of trace group filtering - -Assuming we have 4 modules called "MAIN", "HELP", "CALC" and "PRNT" we could use the filters in the following ways. - -#### Inclusion filter - -To include only "MAIN" and "CALC" traces to the trace prints, we can do: - -``` - mbed_trace_include_filters_set("MAIN,CALC"); -``` - -This would print out only the traces from "MAIN" and "CALC", since they are the trace groups matching the filter list. Trace groups "HELP" and "PRNT" would not be printed out at all. - -## Exclusion filter - -``` - mbed_trace_exclude_filters_set("HELP,PRNT"); -``` - -This would exclue trace groups "HELP" and "PRNT" out of trace printing, thus leaving only prints from "MAIN" and "CALC" visible in the tracing. - -### Reset filter - -``` - mbed_trace_include_filters_set(NULL); -``` - -This would reset the inclusion filters back to nothing and assuming no exclusion filter is in place either, all trace groups prints would get printed. - - -## Unit tests - -To run unit tests: - -* In Linux - -``` -yotta target x86-linux-native -yotta test mbed_trace_test -``` - -* In Mac - -``` -yotta target x86-osx-native -yotta test mbed_trace_test -``` - -* In Windows - -``` -yotta target x86-windows-native -yotta test mbed_trace_test -``` diff --git a/features/frameworks/mbed-trace/mbed-trace/mbed_trace.h b/features/frameworks/mbed-trace/mbed-trace/mbed_trace.h deleted file mode 100644 index 16e54fb..0000000 --- a/features/frameworks/mbed-trace/mbed-trace/mbed_trace.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2015 ARM Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * \file mbed_trace.h - * Trace interface for MbedOS applications. - * This file provide simple but flexible way to handle software traces. - * Trace library are abstract layer, which use stdout (printf) by default, - * but outputs can be easily redirect to custom function, for example to - * store traces to memory or other interfaces. - * - * usage example: - * \code(main.c:) - * #include "mbed_trace.h" - * #define TRACE_GROUP "main" - * - * int main(void){ - * mbed_trace_init(); // initialize trace library - * tr_debug("this is debug msg"); //print debug message to stdout: "[DBG] - * tr_info("this is info msg"); - * tr_warn("this is warning msg"); - * tr_err("this is error msg"); - * return 0; - * } - * \endcode - * Activate with compiler flag: YOTTA_CFG_MBED_TRACE - * Configure trace line buffer size with compiler flag: YOTTA_CFG_MBED_TRACE_LINE_LENGTH. Default length: 1024. - * Limit the size of flash by setting MBED_TRACE_MAX_LEVEL value. Default is TRACE_LEVEL_DEBUG (all included) - * - */ -#ifndef MBED_TRACE_H_ -#define MBED_TRACE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include -#include -#include - -#ifndef YOTTA_CFG_MBED_TRACE -#define YOTTA_CFG_MBED_TRACE 0 -#endif - -#ifndef YOTTA_CFG_MBED_TRACE_FEA_IPV6 -#define YOTTA_CFG_MBED_TRACE_FEA_IPV6 1 -#else -#warning YOTTA_CFG_MBED_TRACE_FEA_IPV6 is deprecated and will be removed in the future! Use MBED_CONF_MBED_TRACE_FEA_IPV6 instead. -#define MBED_CONF_MBED_TRACE_FEA_IPV6 YOTTA_CFG_MBED_TRACE_FEA_IPV6 -#endif - -#ifndef MBED_CONF_MBED_TRACE_ENABLE -#define MBED_CONF_MBED_TRACE_ENABLE 0 -#endif - -#ifndef MBED_CONF_MBED_TRACE_FEA_IPV6 -#define MBED_CONF_MBED_TRACE_FEA_IPV6 1 -#endif - -/** 3 upper bits are trace modes related, - and 5 lower bits are trace level configuration */ - -/** Config mask */ -#define TRACE_MASK_CONFIG 0xE0 -/** Trace level mask */ -#define TRACE_MASK_LEVEL 0x1F - -/** plain trace data instead of "headers" */ -#define TRACE_MODE_PLAIN 0x80 -/** color mode */ -#define TRACE_MODE_COLOR 0x40 -/** Use print CR before trace line */ -#define TRACE_CARRIAGE_RETURN 0x20 - -/** used to activate all trace levels */ -#define TRACE_ACTIVE_LEVEL_ALL 0x1F -/** print all traces same as above */ -#define TRACE_ACTIVE_LEVEL_DEBUG 0x1f -/** print info,warn and error traces */ -#define TRACE_ACTIVE_LEVEL_INFO 0x0f -/** print warn and error traces */ -#define TRACE_ACTIVE_LEVEL_WARN 0x07 -/** print only error trace */ -#define TRACE_ACTIVE_LEVEL_ERROR 0x03 -/** print only cmd line data */ -#define TRACE_ACTIVE_LEVEL_CMD 0x01 -/** trace nothing */ -#define TRACE_ACTIVE_LEVEL_NONE 0x00 - -/** this print is some deep information for debug purpose */ -#define TRACE_LEVEL_DEBUG 0x10 -/** Info print, for general purpose prints */ -#define TRACE_LEVEL_INFO 0x08 -/** warning prints, which shouldn't causes any huge problems */ -#define TRACE_LEVEL_WARN 0x04 -/** Error prints, which causes probably problems, e.g. out of mem. */ -#define TRACE_LEVEL_ERROR 0x02 -/** special level for cmdline. Behaviours like "plain mode" */ -#define TRACE_LEVEL_CMD 0x01 - -#ifndef MBED_TRACE_MAX_LEVEL -#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO -#endif - -//usage macros: -#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG -#define tr_debug(...) mbed_tracef(TRACE_LEVEL_DEBUG, TRACE_GROUP, __VA_ARGS__) //!< Print debug message -#else -#define tr_debug(...) -#endif - -#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_INFO -#define tr_info(...) mbed_tracef(TRACE_LEVEL_INFO, TRACE_GROUP, __VA_ARGS__) //!< Print info message -#else -#define tr_info(...) -#endif - -#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_WARN -#define tr_warning(...) mbed_tracef(TRACE_LEVEL_WARN, TRACE_GROUP, __VA_ARGS__) //!< Print warning message -#define tr_warn(...) mbed_tracef(TRACE_LEVEL_WARN, TRACE_GROUP, __VA_ARGS__) //!< Alternative warning message -#else -#define tr_warning(...) -#define tr_warn(...) -#endif - -#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_ERROR -#define tr_error(...) mbed_tracef(TRACE_LEVEL_ERROR, TRACE_GROUP, __VA_ARGS__) //!< Print Error Message -#define tr_err(...) mbed_tracef(TRACE_LEVEL_ERROR, TRACE_GROUP, __VA_ARGS__) //!< Alternative error message -#else -#define tr_error(...) -#define tr_err(...) -#endif - -#define tr_cmdline(...) mbed_tracef(TRACE_LEVEL_CMD, TRACE_GROUP, __VA_ARGS__) //!< Special print for cmdline. See more from TRACE_LEVEL_CMD -level - -//aliases for the most commonly used functions and the helper functions -#define tracef(dlevel, grp, ...) mbed_tracef(dlevel, grp, __VA_ARGS__) //!< Alias for mbed_tracef() -#define vtracef(dlevel, grp, fmt, ap) mbed_vtracef(dlevel, grp, fmt, ap) //!< Alias for mbed_vtracef() -#define tr_array(buf, len) mbed_trace_array(buf, len) //!< Alias for mbed_trace_array() -#define tr_ipv6(addr_ptr) mbed_trace_ipv6(addr_ptr) //!< Alias for mbed_trace_ipv6() -#define tr_ipv6_prefix(prefix, prefix_len) mbed_trace_ipv6_prefix(prefix, prefix_len) //!< Alias for mbed_trace_ipv6_prefix() -#define trace_array(buf, len) mbed_trace_array(buf, len) //!< Alias for mbed_trace_array() -#define trace_ipv6(addr_ptr) mbed_trace_ipv6(addr_ptr) //!< Alias for mbed_trace_ipv6() -#define trace_ipv6_prefix(prefix, prefix_len) mbed_trace_ipv6_prefix(prefix, prefix_len) //!< Alias for mbed_trace_ipv6_prefix() - - -/** - * Allow specification of default TRACE_GROUP to be used if not specified by application - */ - -#ifndef TRACE_GROUP -#ifdef YOTTA_CFG_MBED_TRACE_GROUP -#define TRACE_GROUP_STR_HELPER(x) #x -#define TRACE_GROUP_STR(x) TRACE_GROUP_STR_HELPER(x) -#define TRACE_GROUP TRACE_GROUP_STR(YOTTA_CFG_MBED_TRACE_GROUP) -#endif -#endif - -/** - * Initialize trace functionality - * @return 0 when all success, otherwise non zero - */ -int mbed_trace_init(void); -/** - * Free trace memory - */ -void mbed_trace_free(void); -/** - * Resize buffers (line / tmp ) sizes - * @param lineLength new maximum length for trace line (0 = do no resize) - * @param tmpLength new maximum length for trace tmp buffer (used for trace_array, etc) (0 = do no resize) - */ -void mbed_trace_buffer_sizes(int lineLength, int tmpLength); -/** - * Set trace configurations - * Possible parameters: - * - * TRACE_MODE_COLOR - * TRACE_MODE_PLAIN (this exclude color mode) - * TRACE_CARRIAGE_RETURN (print CR before trace line) - * - * TRACE_ACTIVE_LEVEL_ALL - to activate all trace levels - * or TRACE_ACTIVE_LEVEL_DEBUG (alternative) - * TRACE_ACTIVE_LEVEL_INFO - * TRACE_ACTIVE_LEVEL_WARN - * TRACE_ACTIVE_LEVEL_ERROR - * TRACE_ACTIVE_LEVEL_CMD - * TRACE_LEVEL_NONE - to deactivate all traces - * - * @param config Byte size Bit-mask. Bits are descripted above. - * usage e.g. - * @code - * mbed_trace_config_set( TRACE_ACTIVE_LEVEL_ALL|TRACE_MODE_COLOR ); - * @endcode - */ -void mbed_trace_config_set(uint8_t config); -/** get trace configurations - * @return trace configuration byte - */ -uint8_t mbed_trace_config_get(void); -/** - * Set trace prefix function - * pref_f -function return string with null terminated - * Can be used for e.g. time string - * e.g. - * char* trace_time(){ return "rtc-time-in-string"; } - * mbed_trace_prefix_function_set( &trace_time ); - */ -void mbed_trace_prefix_function_set(char *(*pref_f)(size_t)); -/** - * Set trace suffix function - * suffix -function return string with null terminated - * Can be used for e.g. time string - * e.g. - * char* trace_suffix(){ return " END"; } - * mbed_trace_suffix_function_set( &trace_suffix ); - */ -void mbed_trace_suffix_function_set(char *(*suffix_f)(void)); -/** - * Set trace print function - * By default, trace module print using printf() function, - * but with this you can write own print function, - * for e.g. to other IO device. - */ -void mbed_trace_print_function_set(void (*print_f)(const char *)); -/** - * Set trace print function for tr_cmdline() - */ -void mbed_trace_cmdprint_function_set(void (*printf)(const char *)); -/** - * Set trace mutex wait function - * By default, trace calls are not thread safe. - * If thread safety is required this can be used to set a callback function that will be called before each trace call. - * The specific implementation is up to the application developer, but the mutex must count so it can - * be acquired from a single thread repeatedly. - */ -void mbed_trace_mutex_wait_function_set(void (*mutex_wait_f)(void)); -/** - * Set trace mutex release function - * By default, trace calls are not thread safe. - * If thread safety is required this can be used to set a callback function that will be called before returning from - * each trace call. The specific implementation is up to the application developer, but the mutex must count so it can - * be acquired from a single thread repeatedly. - */ -void mbed_trace_mutex_release_function_set(void (*mutex_release_f)(void)); -/** - * When trace group contains text in filters, - * trace print will be ignored. - * e.g.: - * mbed_trace_exclude_filters_set("mygr"); - * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "ougr", "This is not printed"); - */ -void mbed_trace_exclude_filters_set(char *filters); -/** get trace exclude filters - */ -const char *mbed_trace_exclude_filters_get(void); -/** - * When trace group contains text in filter, - * trace will be printed. - * e.g.: - * set_trace_include_filters("mygr"); - * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "mygr", "Hi There"); - * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "grp2", "This is not printed"); - */ -void mbed_trace_include_filters_set(char *filters); -/** get trace include filters - */ -const char *mbed_trace_include_filters_get(void); -/** - * General trace function - * This should be used every time when user want to print out something important thing - * Usage e.g. - * mbed_tracef( TRACE_LEVEL_INFO, "mygr", "Hello world!"); - * - * @param dlevel debug level - * @param grp trace group - * @param fmt trace format (like printf) - * @param ... variable arguments related to fmt - */ -#if defined(__GNUC__) || defined(__CC_ARM) -void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...) __attribute__((__format__(__printf__, 3, 4))); -#else -void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...); -#endif -/** - * General trace function - * This should be used every time when user want to print out something important thing - * and vprintf functionality is desired - * Usage e.g. - * va_list ap; - * va_start (ap, fmt); - * mbed_vtracef( TRACE_LEVEL_INFO, "mygr", fmt, ap ); - * va_end (ap); - * - * @param dlevel debug level - * @param grp trace group - * @param fmt trace format (like vprintf) - * @param ap variable arguments list (like vprintf) - */ -#if defined(__GNUC__) || defined(__CC_ARM) -void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap) __attribute__((__format__(__printf__, 3, 0))); -#else -void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap); -#endif - - -/** - * Get last trace from buffer - */ -const char *mbed_trace_last(void); -#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 -/** - * mbed_tracef helping function for convert ipv6 - * table to human readable string. - * usage e.g. - * char ipv6[16] = {...}; // ! array length is 16 bytes ! - * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "ipv6 addr: %s", mbed_trace_ipv6(ipv6)); - * - * @param add_ptr IPv6 Address pointer - * @return temporary buffer where ipv6 is in string format - */ -char *mbed_trace_ipv6(const void *addr_ptr); -/** - * mbed_tracef helping function for print ipv6 prefix - * usage e.g. - * char ipv6[16] = {...}; // ! array length is 16 bytes ! - * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "ipv6 addr: %s", mbed_trace_ipv6_prefix(ipv6, 4)); - * - * @param prefix IPv6 Address pointer - * @param prefix_len prefix length - * @return temporary buffer where ipv6 is in string format - */ -char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len); -#endif -/** - * mbed_tracef helping function for convert hex-array to string. - * usage e.g. - * char myarr[] = {0x10, 0x20}; - * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "arr: %s", mbed_trace_array(myarr, 2)); - * - * @param buf hex array pointer - * @param len buffer length - * @return temporary buffer where string copied - * if array as string not fit to temp buffer, this function write '*' as last character, - * which indicate that buffer is too small for array. - */ -char *mbed_trace_array(const uint8_t *buf, uint16_t len); - -#ifdef __cplusplus -} -#endif - -#endif /* MBED_TRACE_H_ */ - -/* These macros are outside the inclusion guard so they will be re-evaluated for every inclusion of the header. - * If tracing is disabled, the dummies will hide the real functions. The real functions can still be reached by - * surrounding the name of the function with brackets, e.g. "(mbed_tracef)(dlevel, grp, "like so");" - * */ -#if defined(FEA_TRACE_SUPPORT) || MBED_CONF_MBED_TRACE_ENABLE || YOTTA_CFG_MBED_TRACE || (defined(YOTTA_CFG) && !defined(NDEBUG)) -// Make sure FEA_TRACE_SUPPORT is always set whenever traces are enabled. -#ifndef FEA_TRACE_SUPPORT -#define FEA_TRACE_SUPPORT -#endif -// undefine dummies, revealing the real functions -#undef MBED_TRACE_DUMMIES_DEFINED -#undef mbed_trace_init -#undef mbed_trace_free -#undef mbed_trace_buffer_sizes -#undef mbed_trace_config_set -#undef mbed_trace_config_get -#undef mbed_trace_prefix_function_set -#undef mbed_trace_suffix_function_set -#undef mbed_trace_print_function_set -#undef mbed_trace_cmdprint_function_set -#undef mbed_trace_mutex_wait_function_set -#undef mbed_trace_mutex_release_function_set -#undef mbed_trace_exclude_filters_set -#undef mbed_trace_exclude_filters_get -#undef mbed_trace_include_filters_set -#undef mbed_trace_include_filters_get -#undef mbed_tracef -#undef mbed_vtracef -#undef mbed_trace_last -#undef mbed_trace_ipv6 -#undef mbed_trace_ipv6_prefix -#undef mbed_trace_array - -#elif !defined(MBED_TRACE_DUMMIES_DEFINED) -// define dummies, hiding the real functions -#define MBED_TRACE_DUMMIES_DEFINED -#define mbed_trace_init(...) ((int) 0) -#define mbed_trace_free(...) ((void) 0) -#define mbed_trace_buffer_sizes(...) ((void) 0) -#define mbed_trace_config_set(...) ((void) 0) -#define mbed_trace_config_get(...) ((uint8_t) 0) -#define mbed_trace_prefix_function_set(...) ((void) 0) -#define mbed_trace_suffix_function_set(...) ((void) 0) -#define mbed_trace_print_function_set(...) ((void) 0) -#define mbed_trace_cmdprint_function_set(...) ((void) 0) -#define mbed_trace_mutex_wait_function_set(...) ((void) 0) -#define mbed_trace_mutex_release_function_set(...) ((void) 0) -#define mbed_trace_exclude_filters_set(...) ((void) 0) -#define mbed_trace_exclude_filters_get(...) ((const char *) 0) -#define mbed_trace_include_filters_set(...) ((void) 0) -#define mbed_trace_include_filters_get(...) ((const char *) 0) -#define mbed_trace_last(...) ((const char *) 0) -#define mbed_tracef(...) ((void) 0) -#define mbed_vtracef(...) ((void) 0) -/** - * These helper functions accumulate strings in a buffer that is only flushed by actual trace calls. Using these - * functions outside trace calls could cause the buffer to overflow. - */ -#define mbed_trace_ipv6(...) dont_use_trace_helpers_outside_trace_calls -#define mbed_trace_ipv6_prefix(...) dont_use_trace_helpers_outside_trace_calls -#define mbed_trace_array(...) dont_use_trace_helpers_outside_trace_calls - -#endif /* FEA_TRACE_SUPPORT */ diff --git a/features/frameworks/mbed-trace/mbed_lib.json b/features/frameworks/mbed-trace/mbed_lib.json deleted file mode 100644 index f58ccb2..0000000 --- a/features/frameworks/mbed-trace/mbed_lib.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "mbed-trace", - "config": { - "enable": { - "help": "Used to globally enable traces.", - "value": null - }, - "max-level": { - "help": "This flag is used to optimize the code size. For example, setting trace optimization level to TRACE_LEVEL_INFO will define all tr_debug() macros empty, which reduces the binary size. The possible optimization levels are TRACE_LEVEL_DEBUG, TRACE_LEVEL_INFO, TRACE_LEVEL_WARN, TRACE_LEVEL_ERROR and TRACE_LEVEL_CMD. To set the output tracing level, please use mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO). The possible tracing levels for mbed_trace_config_set() are TRACE_ACTIVE_LEVEL_ALL, TRACE_ACTIVE_LEVEL_DEBUG (same as ALL), TRACE_ACTIVE_LEVEL_INFO, TRACE_ACTIVE_LEVEL_WARN, TRACE_ACTIVE_LEVEL_ERROR, TRACE_ACTIVE_LEVEL_CMD and TRACE_LEVEL_NONE.", - "value": null, - "macro_name": "MBED_TRACE_MAX_LEVEL" - - }, - "fea-ipv6": { - "help": "Used to globally disable ipv6 tracing features.", - "value": null - }, - "allocator": { - "value": "malloc", - "macro_name": "MEM_ALLOC" - }, - "deallocator": { - "value": "free", - "macro_name": "MEM_FREE" - } - - } -} \ No newline at end of file diff --git a/features/frameworks/mbed-trace/source/CMakeLists.txt b/features/frameworks/mbed-trace/source/CMakeLists.txt deleted file mode 100644 index 7e7a0a08..0000000 --- a/features/frameworks/mbed-trace/source/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -if(DEFINED TARGET_LIKE_X86_LINUX_NATIVE) - add_library( mbed-trace - mbed_trace.c - ) - add_definitions("-g -O0 -fprofile-arcs -ftest-coverage") - target_link_libraries(mbed-trace gcov nanostack-libservice) -elseif(DEFINED TARGET_LIKE_X86_OSX_NATIVE) - add_library( mbed-trace - mbed_trace.c - ) - add_definitions("-g -O0") - target_link_libraries(mbed-trace nanostack-libservice) -else() - add_library( mbed-trace - mbed_trace.c - ) - target_link_libraries(mbed-trace nanostack-libservice) -endif() diff --git a/features/frameworks/mbed-trace/source/mbed_trace.c b/features/frameworks/mbed-trace/source/mbed_trace.c deleted file mode 100644 index f90e0ea..0000000 --- a/features/frameworks/mbed-trace/source/mbed_trace.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright (c) 2014-2015 ARM Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include -#include -#include - -#ifdef MBED_CONF_MBED_TRACE_ENABLE -#undef MBED_CONF_MBED_TRACE_ENABLE -#endif -#define MBED_CONF_MBED_TRACE_ENABLE 1 -#ifndef MBED_CONF_MBED_TRACE_FEA_IPV6 -#define MBED_CONF_MBED_TRACE_FEA_IPV6 1 -#endif - -#include "mbed-trace/mbed_trace.h" -#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 -#include "mbed-client-libservice/ip6string.h" -#include "mbed-client-libservice/common_functions.h" -#endif - -#if defined(YOTTA_CFG_MBED_TRACE_MEM) -#define MBED_TRACE_MEM_INCLUDE YOTTA_CFG_MBED_TRACE_MEM_INCLUDE -#define MBED_TRACE_MEM_ALLOC YOTTA_CFG_MBED_TRACE_MEM_ALLOC -#define MBED_TRACE_MEM_FREE YOTTA_CFG_MBED_TRACE_MEM_FREE -#else /* YOTTA_CFG_MEMLIB */ -// Default options -#ifndef MBED_TRACE_MEM_INCLUDE -#define MBED_TRACE_MEM_INCLUDE -#endif -#include MBED_TRACE_MEM_INCLUDE -#ifndef MBED_TRACE_MEM_ALLOC -#define MBED_TRACE_MEM_ALLOC malloc -#endif -#ifndef MBED_TRACE_MEM_FREE -#define MBED_TRACE_MEM_FREE free -#endif -#endif /* YOTTA_CFG_MEMLIB */ - -#define VT100_COLOR_ERROR "\x1b[31m" -#define VT100_COLOR_WARN "\x1b[33m" -#define VT100_COLOR_INFO "\x1b[39m" -#define VT100_COLOR_DEBUG "\x1b[90m" - -/** default max trace line size in bytes */ -#ifdef MBED_TRACE_LINE_LENGTH -#define DEFAULT_TRACE_LINE_LENGTH MBED_TRACE_LINE_LENGTH -#elif defined YOTTA_CFG_MBED_TRACE_LINE_LENGTH -#warning YOTTA_CFG_MBED_TRACE_LINE_LENGTH is deprecated and will be removed in the future! Use MBED_TRACE_LINE_LENGTH instead. -#define DEFAULT_TRACE_LINE_LENGTH YOTTA_CFG_MBED_TRACE_LINE_LENGTH -#else -#define DEFAULT_TRACE_LINE_LENGTH 1024 -#endif - -/** default max temporary buffer size in bytes, used in - trace_ipv6, trace_ipv6_prefix and trace_array */ -#ifdef MBED_TRACE_TMP_LINE_LENGTH -#define DEFAULT_TRACE_TMP_LINE_LEN MBED_TRACE_TMP_LINE_LENGTH -#elif defined YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN -#warning The YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. -#define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN -#elif defined YOTTA_CFG_MTRACE_TMP_LINE_LEN -#warning The YOTTA_CFG_MTRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. -#define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MTRACE_TMP_LINE_LEN -#else -#define DEFAULT_TRACE_TMP_LINE_LEN 128 -#endif - -/** default max filters (include/exclude) length in bytes */ -#ifdef MBED_TRACE_FILTER_LENGTH -#define DEFAULT_TRACE_FILTER_LENGTH MBED_TRACE_FILTER_LENGTH -#else -#define DEFAULT_TRACE_FILTER_LENGTH 24 -#endif - -/** default trace configuration bitmask */ -#ifdef MBED_TRACE_CONFIG -#define DEFAULT_TRACE_CONFIG MBED_TRACE_CONFIG -#else -#define DEFAULT_TRACE_CONFIG TRACE_MODE_COLOR | TRACE_ACTIVE_LEVEL_ALL | TRACE_CARRIAGE_RETURN -#endif - -/** default print function, just redirect str to printf */ -static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length); -static void mbed_trace_default_print(const char *str); -static void mbed_trace_reset_tmp(void); - -typedef struct trace_s { - /** trace configuration bits */ - uint8_t trace_config; - /** exclude filters list, related group name */ - char *filters_exclude; - /** include filters list, related group name */ - char *filters_include; - /** Filters length */ - int filters_length; - /** trace line */ - char *line; - /** trace line length */ - int line_length; - /** temporary data */ - char *tmp_data; - /** temporary data array length */ - int tmp_data_length; - /** temporary data pointer */ - char *tmp_data_ptr; - - /** prefix function, which can be used to put time to the trace line */ - char *(*prefix_f)(size_t); - /** suffix function, which can be used to some string to the end of trace line */ - char *(*suffix_f)(void); - /** print out function. Can be redirect to flash for example. */ - void (*printf)(const char *); - /** print out function for TRACE_LEVEL_CMD */ - void (*cmd_printf)(const char *); - /** mutex wait function which can be called to lock against a mutex. */ - void (*mutex_wait_f)(void); - /** mutex release function which must be used to release the mutex locked by mutex_wait_f. */ - void (*mutex_release_f)(void); - /** number of times the mutex has been locked */ - int mutex_lock_count; -} trace_t; - -static trace_t m_trace = { - .trace_config = DEFAULT_TRACE_CONFIG, - .filters_exclude = 0, - .filters_include = 0, - .filters_length = DEFAULT_TRACE_FILTER_LENGTH, - .line = 0, - .line_length = DEFAULT_TRACE_LINE_LENGTH, - .tmp_data = 0, - .tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN, - .tmp_data_ptr = 0, - .prefix_f = 0, - .suffix_f = 0, - .printf = mbed_trace_default_print, - .cmd_printf = 0, - .mutex_wait_f = 0, - .mutex_release_f = 0, - .mutex_lock_count = 0 -}; - -int mbed_trace_init(void) -{ - if (m_trace.line == NULL) { - m_trace.line = MBED_TRACE_MEM_ALLOC(m_trace.line_length); - } - - if (m_trace.tmp_data == NULL) { - m_trace.tmp_data = MBED_TRACE_MEM_ALLOC(m_trace.tmp_data_length); - } - m_trace.tmp_data_ptr = m_trace.tmp_data; - - if (m_trace.filters_exclude == NULL) { - m_trace.filters_exclude = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); - } - if (m_trace.filters_include == NULL) { - m_trace.filters_include = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); - } - - if (m_trace.line == NULL || - m_trace.tmp_data == NULL || - m_trace.filters_exclude == NULL || - m_trace.filters_include == NULL) { - //memory allocation fail - mbed_trace_free(); - return -1; - } - memset(m_trace.tmp_data, 0, m_trace.tmp_data_length); - memset(m_trace.filters_exclude, 0, m_trace.filters_length); - memset(m_trace.filters_include, 0, m_trace.filters_length); - memset(m_trace.line, 0, m_trace.line_length); - - return 0; -} -void mbed_trace_free(void) -{ - // release memory - MBED_TRACE_MEM_FREE(m_trace.line); - MBED_TRACE_MEM_FREE(m_trace.tmp_data); - MBED_TRACE_MEM_FREE(m_trace.filters_exclude); - MBED_TRACE_MEM_FREE(m_trace.filters_include); - - // reset to default values - m_trace.trace_config = DEFAULT_TRACE_CONFIG; - m_trace.filters_exclude = 0; - m_trace.filters_include = 0; - m_trace.filters_length = DEFAULT_TRACE_FILTER_LENGTH; - m_trace.line = 0; - m_trace.line_length = DEFAULT_TRACE_LINE_LENGTH; - m_trace.tmp_data = 0; - m_trace.tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN; - m_trace.prefix_f = 0; - m_trace.suffix_f = 0; - m_trace.printf = mbed_trace_default_print; - m_trace.cmd_printf = 0; - m_trace.mutex_wait_f = 0; - m_trace.mutex_release_f = 0; - m_trace.mutex_lock_count = 0; -} -static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length) -{ - MBED_TRACE_MEM_FREE(*buffer); - *buffer = MBED_TRACE_MEM_ALLOC(new_length); - *length_ptr = new_length; -} -void mbed_trace_buffer_sizes(int lineLength, int tmpLength) -{ - if (lineLength > 0) { - mbed_trace_realloc(&(m_trace.line), &m_trace.line_length, lineLength); - } - if (tmpLength > 0) { - mbed_trace_realloc(&(m_trace.tmp_data), &m_trace.tmp_data_length, tmpLength); - mbed_trace_reset_tmp(); - } -} -void mbed_trace_config_set(uint8_t config) -{ - m_trace.trace_config = config; -} -uint8_t mbed_trace_config_get(void) -{ - return m_trace.trace_config; -} -void mbed_trace_prefix_function_set(char *(*pref_f)(size_t)) -{ - m_trace.prefix_f = pref_f; -} -void mbed_trace_suffix_function_set(char *(*suffix_f)(void)) -{ - m_trace.suffix_f = suffix_f; -} -void mbed_trace_print_function_set(void (*printf)(const char *)) -{ - m_trace.printf = printf; -} -void mbed_trace_cmdprint_function_set(void (*printf)(const char *)) -{ - m_trace.cmd_printf = printf; -} -void mbed_trace_mutex_wait_function_set(void (*mutex_wait_f)(void)) -{ - m_trace.mutex_wait_f = mutex_wait_f; -} -void mbed_trace_mutex_release_function_set(void (*mutex_release_f)(void)) -{ - m_trace.mutex_release_f = mutex_release_f; -} -void mbed_trace_exclude_filters_set(char *filters) -{ - if (filters) { - (void)strncpy(m_trace.filters_exclude, filters, m_trace.filters_length); - } else { - m_trace.filters_exclude[0] = 0; - } -} -const char *mbed_trace_exclude_filters_get(void) -{ - return m_trace.filters_exclude; -} -const char *mbed_trace_include_filters_get(void) -{ - return m_trace.filters_include; -} -void mbed_trace_include_filters_set(char *filters) -{ - if (filters) { - (void)strncpy(m_trace.filters_include, filters, m_trace.filters_length); - } else { - m_trace.filters_include[0] = 0; - } -} -static int8_t mbed_trace_skip(int8_t dlevel, const char *grp) -{ - if (dlevel >= 0 && grp != 0) { - // filter debug prints only when dlevel is >0 and grp is given - - /// @TODO this could be much better.. - if (m_trace.filters_exclude[0] != '\0' && - strstr(m_trace.filters_exclude, grp) != 0) { - //grp was in exclude list - return 1; - } - if (m_trace.filters_include[0] != '\0' && - strstr(m_trace.filters_include, grp) == 0) { - //grp was in include list - return 1; - } - } - return 0; -} -static void mbed_trace_default_print(const char *str) -{ - puts(str); -} -void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - mbed_vtracef(dlevel, grp, fmt, ap); - va_end(ap); -} -void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap) -{ - if (m_trace.mutex_wait_f) { - m_trace.mutex_wait_f(); - m_trace.mutex_lock_count++; - } - - if (NULL == m_trace.line) { - goto end; - } - - m_trace.line[0] = 0; //by default trace is empty - - if (mbed_trace_skip(dlevel, grp) || fmt == 0 || grp == 0 || !m_trace.printf) { - //return tmp data pointer back to the beginning - mbed_trace_reset_tmp(); - goto end; - } - if ((m_trace.trace_config & TRACE_MASK_LEVEL) & dlevel) { - bool color = (m_trace.trace_config & TRACE_MODE_COLOR) != 0; - bool plain = (m_trace.trace_config & TRACE_MODE_PLAIN) != 0; - bool cr = (m_trace.trace_config & TRACE_CARRIAGE_RETURN) != 0; - - int retval = 0, bLeft = m_trace.line_length; - char *ptr = m_trace.line; - if (plain == true || dlevel == TRACE_LEVEL_CMD) { - //add trace data - retval = vsnprintf(ptr, bLeft, fmt, ap); - if (dlevel == TRACE_LEVEL_CMD && m_trace.cmd_printf) { - m_trace.cmd_printf(m_trace.line); - m_trace.cmd_printf("\n"); - } else { - //print out whole data - m_trace.printf(m_trace.line); - } - } else { - if (color) { - if (cr) { - retval = snprintf(ptr, bLeft, "\r\x1b[2K"); - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - ptr += retval; - bLeft -= retval; - } - } - if (bLeft > 0) { - //include color in ANSI/VT100 escape code - switch (dlevel) { - case (TRACE_LEVEL_ERROR): - retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_ERROR); - break; - case (TRACE_LEVEL_WARN): - retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_WARN); - break; - case (TRACE_LEVEL_INFO): - retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_INFO); - break; - case (TRACE_LEVEL_DEBUG): - retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_DEBUG); - break; - default: - color = 0; //avoid unneeded color-terminate code - retval = 0; - break; - } - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0 && color) { - ptr += retval; - bLeft -= retval; - } - } - - } - if (bLeft > 0 && m_trace.prefix_f) { - //find out length of body - size_t sz = 0; - va_list ap2; - va_copy(ap2, ap); - sz = vsnprintf(NULL, 0, fmt, ap2) + retval + (retval ? 4 : 0); - va_end(ap2); - //add prefix string - retval = snprintf(ptr, bLeft, "%s", m_trace.prefix_f(sz)); - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - ptr += retval; - bLeft -= retval; - } - } - if (bLeft > 0) { - //add group tag - switch (dlevel) { - case (TRACE_LEVEL_ERROR): - retval = snprintf(ptr, bLeft, "[ERR ][%-4s]: ", grp); - break; - case (TRACE_LEVEL_WARN): - retval = snprintf(ptr, bLeft, "[WARN][%-4s]: ", grp); - break; - case (TRACE_LEVEL_INFO): - retval = snprintf(ptr, bLeft, "[INFO][%-4s]: ", grp); - break; - case (TRACE_LEVEL_DEBUG): - retval = snprintf(ptr, bLeft, "[DBG ][%-4s]: ", grp); - break; - default: - retval = snprintf(ptr, bLeft, " "); - break; - } - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - ptr += retval; - bLeft -= retval; - } - } - if (retval > 0 && bLeft > 0) { - //add trace text - retval = vsnprintf(ptr, bLeft, fmt, ap); - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - ptr += retval; - bLeft -= retval; - } - } - - if (retval > 0 && bLeft > 0 && m_trace.suffix_f) { - //add suffix string - retval = snprintf(ptr, bLeft, "%s", m_trace.suffix_f()); - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - ptr += retval; - bLeft -= retval; - } - } - - if (retval > 0 && bLeft > 0 && color) { - //add zero color VT100 when color mode - retval = snprintf(ptr, bLeft, "\x1b[0m"); - if (retval >= bLeft) { - retval = 0; - } - if (retval > 0) { - // not used anymore - //ptr += retval; - //bLeft -= retval; - } - } - //print out whole data - m_trace.printf(m_trace.line); - } - //return tmp data pointer back to the beginning - mbed_trace_reset_tmp(); - } - -end: - if (m_trace.mutex_release_f) { - // Store the mutex lock count to temp variable so that it won't get - // clobbered during last loop iteration when mutex gets released - int count = m_trace.mutex_lock_count; - m_trace.mutex_lock_count = 0; - // Since the helper functions (eg. mbed_trace_array) are used like this: - // mbed_tracef(TRACE_LEVEL_INFO, "grp", "%s", mbed_trace_array(some_array)) - // The helper function MUST acquire the mutex if it modifies any buffers. However - // it CANNOT unlock the mutex because that would allow another thread to acquire - // the mutex after helper function unlocks it and before mbed_tracef acquires it - // for itself. This means that here we have to unlock the mutex as many times - // as it was acquired by trace function and any possible helper functions. - do { - m_trace.mutex_release_f(); - } while (--count > 0); - } -} -static void mbed_trace_reset_tmp(void) -{ - m_trace.tmp_data_ptr = m_trace.tmp_data; -} -const char *mbed_trace_last(void) -{ - return m_trace.line; -} -/* Helping functions */ -#define tmp_data_left() m_trace.tmp_data_length-(m_trace.tmp_data_ptr-m_trace.tmp_data) -#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 -char *mbed_trace_ipv6(const void *addr_ptr) -{ - /** Acquire mutex. It is released before returning from mbed_vtracef. */ - if (m_trace.mutex_wait_f) { - m_trace.mutex_wait_f(); - m_trace.mutex_lock_count++; - } - char *str = m_trace.tmp_data_ptr; - if (str == NULL) { - return ""; - } - if (tmp_data_left() < 41) { - return ""; - } - if (addr_ptr == NULL) { - return ""; - } - str[0] = 0; - m_trace.tmp_data_ptr += ip6tos(addr_ptr, str) + 1; - return str; -} -char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) -{ - /** Acquire mutex. It is released before returning from mbed_vtracef. */ - if (m_trace.mutex_wait_f) { - m_trace.mutex_wait_f(); - m_trace.mutex_lock_count++; - } - char *str = m_trace.tmp_data_ptr; - if (str == NULL) { - return ""; - } - if (tmp_data_left() < 45) { - return ""; - } - - if ((prefix_len != 0 && prefix == NULL) || prefix_len > 128) { - return ""; - } - - m_trace.tmp_data_ptr += ip6_prefix_tos(prefix, prefix_len, str) + 1; - return str; -} -#endif //MBED_CONF_MBED_TRACE_FEA_IPV6 -char *mbed_trace_array(const uint8_t *buf, uint16_t len) -{ - /** Acquire mutex. It is released before returning from mbed_vtracef. */ - if (m_trace.mutex_wait_f) { - m_trace.mutex_wait_f(); - m_trace.mutex_lock_count++; - } - int i, bLeft = tmp_data_left(); - char *str, *wptr; - str = m_trace.tmp_data_ptr; - if (len == 0 || str == NULL || bLeft == 0) { - return ""; - } - if (buf == NULL) { - return ""; - } - wptr = str; - wptr[0] = 0; - const uint8_t *ptr = buf; - char overflow = 0; - for (i = 0; i < len; i++) { - if (bLeft <= 3) { - overflow = 1; - break; - } - int retval = snprintf(wptr, bLeft, "%02x:", *ptr++); - if (retval <= 0 || retval > bLeft) { - break; - } - bLeft -= retval; - wptr += retval; - } - if (wptr > str) { - if (overflow) { - // replace last character as 'star', - // which indicate buffer len is not enough - *(wptr - 1) = '*'; - } else { - //null to replace last ':' character - *(wptr - 1) = 0; - } - } - m_trace.tmp_data_ptr = wptr; - return str; -} diff --git a/platform/mbed-trace/.gitignore b/platform/mbed-trace/.gitignore new file mode 100644 index 0000000..f55542c --- /dev/null +++ b/platform/mbed-trace/.gitignore @@ -0,0 +1,42 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +yotta_modules/ +yotta_targets/ +build/ +test_coverage/ +**/*.info +**/*~ +output/* + +# Yotta files +.yotta.json diff --git a/platform/mbed-trace/.mbedignore b/platform/mbed-trace/.mbedignore new file mode 100644 index 0000000..67ab365 --- /dev/null +++ b/platform/mbed-trace/.mbedignore @@ -0,0 +1,5 @@ +build/* +yotta_modules/* +yotta_targets/* +test/* +example/* diff --git a/platform/mbed-trace/CMakeLists.txt b/platform/mbed-trace/CMakeLists.txt new file mode 100644 index 0000000..1b0db50 --- /dev/null +++ b/platform/mbed-trace/CMakeLists.txt @@ -0,0 +1,17 @@ +INCLUDE(CMakeForceCompiler) + +cmake_minimum_required (VERSION 2.8) +SET(CMAKE_SYSTEM_NAME Generic) + +project(mbedTrace) + + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/mbed-trace/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../nanostack-libservice/mbed-client-libservice/) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../nanostack-libservice/) + +set (MBED_TRACE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/source/mbed_trace.c) + + +CREATE_LIBRARY(mbedTrace "${MBED_TRACE_SRC}" "") diff --git a/platform/mbed-trace/CONTRIBUTING.md b/platform/mbed-trace/CONTRIBUTING.md new file mode 100644 index 0000000..be25df1 --- /dev/null +++ b/platform/mbed-trace/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Hello! +We are an open source project of [ARM mbed](www.mbed.com). Contributions via [pull request](https://github.com/armmbed/mbed-client-trace/pulls), and [bug reports](https://github.com/armmbed/mbed-client-trace/issues) are welcome! + +For more details please see our general [CONTRIBUTING.md](https://github.com/ARMmbed/greentea/blob/master/docs/CONTRIBUTING.md) document. + +# Contributor agreement +For your pull request to be accepted, we will need you to agree to our [contributor agreement](http://developer.mbed.org/contributor_agreement/) to give us the necessary rights to use and distribute your contributions. (To click through the agreement create an account on mbed.com and log in.) + +<3 diff --git a/platform/mbed-trace/Jenkinsfile b/platform/mbed-trace/Jenkinsfile new file mode 100644 index 0000000..8ac585c --- /dev/null +++ b/platform/mbed-trace/Jenkinsfile @@ -0,0 +1,279 @@ +echo "Start to build" + +properties ([ + buildDiscarder( + logRotator( + artifactNumToKeepStr: '10', + numToKeepStr: '100' + ) + ) +]) + +// List of targets to compile +def morpheusTargets = [ + //"LPC1768", + //"NUCLEO_F401RE", + "K64F" +] +// Map morpheus toolchains to compiler labels on Jenkins +def toolchains = [ + ARM: "armcc", + IAR: "iar_arm", + GCC_ARM: "arm-none-eabi-gcc" +] +// yotta target includes toolchain +def yottaTargets = [ + "frdm-k64f-gcc": "gcc", + "frdm-k64f-armcc": "armcc", + "stm32f429i-disco-gcc": "gcc", + "x86-linux-native": "linux && astyle" +] + +// Initial maps for parallel build steps +def stepsForParallel = [:] +// Jenkins pipeline does not support map.each, we need to use oldschool for loop +for (int i = 0; i < morpheusTargets.size(); i++) { + for(int j = 0; j < toolchains.size(); j++) { + def target = morpheusTargets.get(i) + def toolchain = toolchains.keySet().asList().get(j) + def compilerLabel = toolchains.get(toolchain) + def stepName = "mbed-os5-${target} ${toolchain}" + stepsForParallel[stepName] = morpheusBuildStep(target, compilerLabel, toolchain) + } +} +// map yotta steps +for (int i = 0; i < yottaTargets.size(); i++) { + def target = yottaTargets.keySet().asList().get(i) + def compilerLabel = yottaTargets.get(target) + def stepName = "mbed-os3-${target}" + stepsForParallel[stepName] = yottaBuildStep(target, compilerLabel) +} + +/* Jenkins does not allow stages inside parallel execution, + * https://issues.jenkins-ci.org/browse/JENKINS-26107 will solve this by adding labeled blocks + */ +// Actually run the steps in parallel - parallel takes a map as an argument, hence the above. +timestamps { + timeout(time: 30, unit: "MINUTES") { + parallel stepsForParallel + } +} + +def execute(cmd) { + if(isUnix()) { + sh "${cmd}" + } else { + bat "${cmd}" + } +} + +//Create morpheus build steps for parallel execution +def morpheusBuildStep(target, compilerLabel, toolchain) { + return { + node ("${compilerLabel}") { + deleteDir() + dir("mbed-trace") { + String buildName = "mbed-os5-${target}-${toolchain}" + def scmVars = checkout scm + env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT + setBuildStatus('PENDING', "build ${buildName}", 'build starts') + stage ("build:${buildName}") { + try{ + execute("mbed --version") + execute("echo https://github.com/armmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 > mbed-os.lib") + execute("mbed deploy") + execute("rm -rf ./mbed-os/platform/mbed-trace") + execute("mbed compile -m ${target} -t ${toolchain} --library") + setBuildStatus('SUCCESS', "build ${buildName}", "build done") + } catch (err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "build ${buildName}", "build failed") + throw err + } + } + stage("build:example:${buildName}") { + execute("mkdir ../example-mbed-os-5 || true") + execute("cp -R example/mbed-os-5 ../example-mbed-os-5") + dir("../example-mbed-os-5") { + def exampleName = "example-${buildName}" + setBuildStatus('PENDING', "build ${exampleName}", 'build starts') + try { + execute("echo \"https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9\" > mbed-os.lib") + execute("echo \"https://github.com/ARMmbed/mbed-trace#${env.GIT_COMMIT_HASH}\" > mbed-trace.lib") + execute("mbed new .") + execute("mbed deploy") + execute("rm -rf ./mbed-os/platform/mbed-trace") + execute("rm -rf ./mbed-trace/example") + execute("rm -rf ./mbed-trace/test") + execute("mbed compile -t ${toolchain} -m ${target}") + setBuildStatus('SUCCESS', "build ${exampleName}", "build done") + } catch(err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "build ${exampleName}", "build failed") + currentBuild.result = 'FAILURE' + } finally { + // clean up + postBuild(buildName, false) + step([$class: 'WsCleanup']) + } + } + } + } + } + } +} + +//Create yotta build steps for parallel execution +def yottaBuildStep(target, compilerLabel) { + return { + String buildName = "mbed-os3-${target}" + node ("${compilerLabel}") { + deleteDir() + dir("mbed-trace") { + def scmVars = checkout scm + env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT + def isTest = target == "x86-linux-native" // tests are valid only in linux target + stage ("build:${buildName}") { + setBuildStatus('PENDING', "build ${buildName}", 'build starts') + try{ + execute("yotta --version") + execute("yotta target $target") + execute("yotta --plain build mbed-trace") + setBuildStatus('SUCCESS', "build ${buildName}", "build done") + } catch (err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "build ${buildName}", "build failed") + currentBuild.result = 'FAILURE' + } + } // stage + if (isTest) { + stage("test:${buildName}") { + setBuildStatus('PENDING', "test ${buildName}", 'test starts') + try { + execute("yotta test mbed_trace_test") + execute("lcov --base-directory . --directory . --capture --output-file coverage.info") + execute("genhtml -o ./test_coverage coverage.info") + execute("gcovr -x -o junit.xml") + execute("cppcheck --enable=all --std=c99 --inline-suppr --template=\"{file},{line},{severity},{id},{message}\" source 2> cppcheck.txt") + + // check if astyle is correct + execute("astyle --options=.astylerc source/*.c mbed-trace/*.h") + // check differency + execute("git diff-index -p --exit-code HEAD") + + setBuildStatus('SUCCESS', "test ${buildName}", "test done") + } catch(err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "test ${buildName}", "test failed") + currentBuild.result = 'FAILURE' + } + } // stage + stage("example:${buildName}") { + dir("example/linux") { + def exampleName = "example-linux" + setBuildStatus('PENDING', "build ${exampleName}", 'build starts') + try { + execute("make") + setBuildStatus('SUCCESS', "build ${exampleName}", "build done") + } catch(err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "build ${exampleName}", "build failed") + currentBuild.result = 'FAILURE' + } + } + } // stage + + stage("leak-check:${buildName}") { + dir("example/linux") { + def stageName = "leak-check" + setBuildStatus('PENDING', "test ${stageName}", 'test starts') + try { + execute("./memtest.sh") + setBuildStatus('SUCCESS', "test ${stageName}", "test done") + } catch(err) { + echo "Caught exception: ${err}" + setBuildStatus('FAILURE', "test ${stageName}", "test failed") + currentBuild.result = 'FAILURE' + } + } + } // stage + } // if linux + postBuild(buildName, isTest) + step([$class: 'WsCleanup']) + } // dir + } + } +} + +def postBuild(buildName, isTest) { + // move files to target+toolchain specific folder + execute("mkdir -p output/${buildName}") + execute("find . -name 'libmbed-trace.a' -exec mv {} 'output/${buildName}' \\;") + execute("find . -name 'mbed-trace.ar' -exec mv {} 'output/${buildName}' \\;") + execute("find ../example-mbed-os-5 -name 'example-mbed-os-5.bin' -exec mv {} 'output/${buildName}/example-mbed-os-5.bin' \\; || true") + // Archive artifacts + step([ + $class: 'ArtifactArchiver', + artifacts: "cppcheck.txt,output/**", + fingerprint: true, + allowEmptyArchive: true + ]) + if (isTest) { + // Publish cobertura + step([ + $class: 'CoberturaPublisher', + coberturaReportFile: 'junit.xml' + ]) + // Publish compiler warnings + step([ + $class: 'WarningsPublisher', + parserConfigurations: [[ + parserName: 'GNU Make + GNU C Compiler (gcc)', + pattern: 'mbed-trace/*.h,source/*.c,test/*.cpp' + ]], + unstableTotalAll: '0', + useDeltaValues: true, + usePreviousBuildAsReference: true + ]) + // Publish HTML reports + publishHTML(target: [ + alwayLinkToLastBuild: false, + keepAll: true, + reportDir: "test_coverage", + reportFiles: "index.html", + reportName: "Build HTML Report" + ]) + } +} +// helper function to set build status to github PR +def setBuildStatus(String state, String context, String message) { + step([ + $class: "GitHubCommitStatusSetter", + reposSource: [ + $class: "ManuallyEnteredRepositorySource", + url: "https://github.com/ARMmbed/mbed-trace.git" + ], + contextSource: [ + $class: "ManuallyEnteredCommitContextSource", + context: context + ], + errorHandlers: [[ + $class: "ChangingBuildStatusErrorHandler", + result: "UNSTABLE" + ]], + commitShaSource: [ + $class: "ManuallyEnteredShaSource", + sha: env.GIT_COMMIT_HASH + ], + statusResultSource: [ + $class: 'ConditionalStatusResultSource', + results: [ + [ + $class: 'AnyBuildResult', + message: message, + state: state + ] + ] + ] + ]) +} diff --git a/platform/mbed-trace/LICENSE b/platform/mbed-trace/LICENSE new file mode 100644 index 0000000..5c304d1 --- /dev/null +++ b/platform/mbed-trace/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/platform/mbed-trace/Makefile.nanomesh b/platform/mbed-trace/Makefile.nanomesh new file mode 100644 index 0000000..efd7820 --- /dev/null +++ b/platform/mbed-trace/Makefile.nanomesh @@ -0,0 +1,5 @@ +SRCS := $(wildcard source/*.c) +LIB := libmbed-trace.a +EXPORT_HEADERS := mbed-trace + +include ../exported_rules.mk diff --git a/platform/mbed-trace/README.md b/platform/mbed-trace/README.md new file mode 100644 index 0000000..203759c --- /dev/null +++ b/platform/mbed-trace/README.md @@ -0,0 +1,278 @@ +# mbed-trace + +A general purpose tracing abstraction library for mbed devices. + +## Description + +The purpose of the library is to provide a light, simple and general tracing solution for mbed devices. By default, it prints traces to `stdout` (usually, a serial port), but the output can also be redirected to other targets. The library was developed using ANSI C language, but it can be used with C++ as well. Currently, there is no C++ wrapper available, but it can be created easily on top of this library. + +## Philosophy + +* The library needs to be light, fast, simple and abstract. +* Dependencies must be minimal. +* The memory space required by the library is allocated at the initialization only once during the application lifetime. +* No new malloc/free are needed when running the library. +* The trace methods must be as fast as possible. +* After a trace method call, the trace function needs to release the required resources. +* A trace method call produces a single line containing ``, `` and `` +* It must be possible to filter messages on the fly. Compile time filtering is not fully supported yet. + +## Compromises + +* The traces are stored as ASCII arrays in the flash memory (pretty high memory consumption). Therefore, it is not necessary to: + * encode/decode the trace messages on the fly (this may take too much CPU time) or + * have external dev-env dependencies to encode the traces compile time and an external application to decode the traces. +* The group name length is limited to four characters. This makes the lines cleaner and it is enough for most use cases for separating the module names. The group name length may not be suitable for a clean human readable format, but still four characters is enough for unique module names. +* The trace function uses `stdout` as the default output target because it goes directly to serial port in mbed-os. +* The trace function produces traces like: `[][grp ]: msg`. This provides an easy way to detect trace prints and separate traces from normal prints (for example with _regex_). +* This approach requires a `sprintf` implementation (`stdio.h`). The memory consumption is pretty high, but it allows an efficient way to format traces. +* The solution is not Interrupt safe. ([PRs](https://github.com/ARMmbed/mbed-trace/pulls) are more than welcome.) +* The solution is not thread safe by default. Thread safety for the actual trace calls can be enabled by providing wait and release callback functions that use mutexes defined by the application. + +## Examples of traces + +``` +[DBG ][abc ]: This is a debug message from module abc +[INFO][br ]: Hi there. +[WARN][br ]: Oh no, br warning occurs! +[ERR ][abc ]: Something goes wrong in module abc +``` + +## Usage + +### Prerequisites + +* Initialize the serial port so that `stdout` works. You can verify that the serial port works using the `printf()` function. + * If you want to redirect the traces somewhere else, see the [trace API](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h#L245). +* To enable the tracing API: + * With yotta: set `YOTTA_CFG_MBED_TRACE` to 1 or true. Setting the flag to 0 or false disables tracing. + * [With mbed OS 5](#enabling-the-tracing-api-in-mbed-os-5) +* By default, trace uses 1024 bytes buffer for trace lines, but you can change it by setting the configuration macro `MBED_TRACE_LINE_LENGTH` to the desired value. +* To disable the IPv6 conversion: + * With yotta: set `YOTTA_CFG_MBED_TRACE_FEA_IPV6 = 0`. + * With mbed OS 5: set `MBED_CONF_MBED_TRACE_FEA_IPV6 = 0`. +* If thread safety is needed, configure the wait and release callback functions before initialization to enable the protection. Usually, this needs to be done only once in the application's lifetime. + * If [helping functions](#helping-functions) are used the mutex must be **recursive** (counting) so it can be acquired from a single thread repeatedly. +* Call the trace initialization (`mbed_trace_init`) once before using any other APIs. It allocates the trace buffer and initializes the internal variables. +* Define `TRACE_GROUP` in your **source code (not in the header)** to use traces. It is a 1-4 characters long char-array (for example `#define TRACE_GROUP "APPL"`). This will be printed on every trace line. + +### Enabling the tracing API in mbed OS 5 + +* Set `MBED_CONF_MBED_TRACE_ENABLE` to 1 or true + +To do so, add the following to your mbed_app.json: + +```json +{ + "target_overrides": { + "*": { + "mbed-trace.enable": 1 + } + } +} +``` + +Do not forget to fulfill the other [prerequisites](#prerequisites)! + +([Click here for more information on the configuration system](https://docs.mbed.com/docs/mbed-os-api/en/latest/config_system/)) + + +## Examples + +* [mbed-os-5](example/mbed-os-5) +* [linux](example/linux) + +### Traces + +When you want to print traces, use the `tr_` macros. The macros behave like `printf()`. For example, +`tr_debug("hello %s", "trace")` produces the following trace line: `[DBG ][APPL] hello trace`. + +Available levels: + +* debug +* info +* warning +* error +* cmdline (special behavior, should not be used) + +For the thread safety, set the mutex wait and release functions. You need do this before the initialization to have the functions available right away: + +```c +mbed_trace_mutex_wait_function_set(my_mutex_wait); +mbed_trace_mutex_release_function_set(my_mutex_release); +``` + +Initialization (once in application's lifetime): + +```c +int mbed_trace_init(void); +``` + +Set the output function, `printf` by default: + +```c +mbed_trace_print_function_set(printf) +``` + +### Tracing level + +Run time tracing level is set using `mbed_trace_set_config()` function. Possible levels and examples how to set them is presented below. + +```c +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_ALL); +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_DEBUG); // (same as ALL) +mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO); +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_WARN); +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_ERROR); +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_CMD); +//mbed_trace_config_set(TRACE_ACTIVE_LEVEL_NONE); +``` + +Build time optimization can be done with `MBED_TRACE_MAX_LEVEL` definition. Setting max level to `TRACE_LEVEL_DEBUG` includes all traces to the build. Setting max level to `TRACE_LEVEL_INFO` includes all but `tr_debug()` traces to the build. Other maximum tracing levels follow the same behavior and no messages above the selected level are included in the build. + +```c +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_DEBUG +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_WARN +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_ERROR +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_CMD +``` + +In Mbed OS, the build time maximum tracing level can be set through `mbed_app.json` as shown below. + +``` +{ + "target_overrides":{ + "*":{ + "mbed-trace.enable": true, + "mbed-trace.max-level": "TRACE_LEVEL_INFO" + } + } +} +``` + +When max-level is not set by the application, default level is INFO. + +### Helping functions + +The purpose of the helping functions is to provide simple conversions, +for example from an array to C string, so that you can print everything to single trace line. +They must be called inside the actual trace calls, for example: + +``` +tr_debug("My IP6 address: %s", mbed_trace_ipv6(addr)); +``` + +Available conversion functions: + +``` +char *mbed_trace_ipv6(const void *addr_ptr) +char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) +char *mbed_trace_array(const uint8_t *buf, uint16_t len) +``` + +See more in [mbed_trace.h](https://github.com/ARMmbed/mbed-trace/blob/master/mbed-trace/mbed_trace.h). + + +## Usage example: + +```c++ +#define MBED_CONF_MBED_TRACE_ENABLE 1 //this could be defined also in the mbed-cli configuration file mbed_app.json +#include "mbed-trace/mbed_trace.h" +#define TRACE_GROUP "main" + + // These are necessary only if thread safety is needed +static Mutex MyMutex; +static void my_mutex_wait() +{ + MyMutex.lock(); +} +static void my_mutex_release() +{ + MyMutex.unlock(); +} + +int main(void){ + mbed_trace_mutex_wait_function_set( my_mutex_wait ); // only if thread safety is needed + mbed_trace_mutex_release_function_set( my_mutex_release ); // only if thread safety is needed + mbed_trace_init(); // initialize the trace library + tr_debug("this is debug msg"); //-> "[DBG ][main]: this is a debug msg" + tr_info("this is info msg"); //-> "[INFO][main]: this is an info msg" + tr_warn("this is warning msg"); //-> "[WARN][main]: this is a warning msg" + tr_err("this is error msg"); //-> "[ERR ][main]: this is an error msg" + char arr[] = {30, 31, 32}; + tr_debug("printing array: %s", mbed_trace_array(arr, 3)); //-> "[DBG ][main]: printing array: 01:02:03" + return 0; +} +``` + +## Run-time trace group filtering + +The trace groups you have defined using the `TRACE_GROUP` macro in your .c/.cpp files can be used to control tracing at run-time. + +| Function | Explanation | +|-----------------------------------|--------------------------------------------------------------| +|`mbed_trace_include_filters_get()` | Get the exclusion filter list string. | +|`mbed_trace_include_filters_set()` | Set trace list to include only the traces matching the list. | +|`mbed_trace_exclude_filters_get()` | Get the inclusion filter list string. | +|`mbed_trace_exclude_filters_set()` | Set trace list to exclude the traces matching the list. | + +The filter list is a null terminated string of comma (`,`) separated trace group names. The default maximum length of the string is 24 characters, including the terminating null. Length can be changed by defining the macro `DEFAULT_TRACE_FILTER_LENGTH`. Exclude and include filters can be combined freely as they both have their own filtering list. + +The matching is done simply using `strstr()` from C standard libraries. + +### Examples of trace group filtering + +Assuming we have 4 modules called "MAIN", "HELP", "CALC" and "PRNT" we could use the filters in the following ways. + +#### Inclusion filter + +To include only "MAIN" and "CALC" traces to the trace prints, we can do: + +``` + mbed_trace_include_filters_set("MAIN,CALC"); +``` + +This would print out only the traces from "MAIN" and "CALC", since they are the trace groups matching the filter list. Trace groups "HELP" and "PRNT" would not be printed out at all. + +## Exclusion filter + +``` + mbed_trace_exclude_filters_set("HELP,PRNT"); +``` + +This would exclue trace groups "HELP" and "PRNT" out of trace printing, thus leaving only prints from "MAIN" and "CALC" visible in the tracing. + +### Reset filter + +``` + mbed_trace_include_filters_set(NULL); +``` + +This would reset the inclusion filters back to nothing and assuming no exclusion filter is in place either, all trace groups prints would get printed. + + +## Unit tests + +To run unit tests: + +* In Linux + +``` +yotta target x86-linux-native +yotta test mbed_trace_test +``` + +* In Mac + +``` +yotta target x86-osx-native +yotta test mbed_trace_test +``` + +* In Windows + +``` +yotta target x86-windows-native +yotta test mbed_trace_test +``` diff --git a/platform/mbed-trace/mbed-trace/mbed_trace.h b/platform/mbed-trace/mbed-trace/mbed_trace.h new file mode 100644 index 0000000..16e54fb --- /dev/null +++ b/platform/mbed-trace/mbed-trace/mbed_trace.h @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file mbed_trace.h + * Trace interface for MbedOS applications. + * This file provide simple but flexible way to handle software traces. + * Trace library are abstract layer, which use stdout (printf) by default, + * but outputs can be easily redirect to custom function, for example to + * store traces to memory or other interfaces. + * + * usage example: + * \code(main.c:) + * #include "mbed_trace.h" + * #define TRACE_GROUP "main" + * + * int main(void){ + * mbed_trace_init(); // initialize trace library + * tr_debug("this is debug msg"); //print debug message to stdout: "[DBG] + * tr_info("this is info msg"); + * tr_warn("this is warning msg"); + * tr_err("this is error msg"); + * return 0; + * } + * \endcode + * Activate with compiler flag: YOTTA_CFG_MBED_TRACE + * Configure trace line buffer size with compiler flag: YOTTA_CFG_MBED_TRACE_LINE_LENGTH. Default length: 1024. + * Limit the size of flash by setting MBED_TRACE_MAX_LEVEL value. Default is TRACE_LEVEL_DEBUG (all included) + * + */ +#ifndef MBED_TRACE_H_ +#define MBED_TRACE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#ifndef YOTTA_CFG_MBED_TRACE +#define YOTTA_CFG_MBED_TRACE 0 +#endif + +#ifndef YOTTA_CFG_MBED_TRACE_FEA_IPV6 +#define YOTTA_CFG_MBED_TRACE_FEA_IPV6 1 +#else +#warning YOTTA_CFG_MBED_TRACE_FEA_IPV6 is deprecated and will be removed in the future! Use MBED_CONF_MBED_TRACE_FEA_IPV6 instead. +#define MBED_CONF_MBED_TRACE_FEA_IPV6 YOTTA_CFG_MBED_TRACE_FEA_IPV6 +#endif + +#ifndef MBED_CONF_MBED_TRACE_ENABLE +#define MBED_CONF_MBED_TRACE_ENABLE 0 +#endif + +#ifndef MBED_CONF_MBED_TRACE_FEA_IPV6 +#define MBED_CONF_MBED_TRACE_FEA_IPV6 1 +#endif + +/** 3 upper bits are trace modes related, + and 5 lower bits are trace level configuration */ + +/** Config mask */ +#define TRACE_MASK_CONFIG 0xE0 +/** Trace level mask */ +#define TRACE_MASK_LEVEL 0x1F + +/** plain trace data instead of "headers" */ +#define TRACE_MODE_PLAIN 0x80 +/** color mode */ +#define TRACE_MODE_COLOR 0x40 +/** Use print CR before trace line */ +#define TRACE_CARRIAGE_RETURN 0x20 + +/** used to activate all trace levels */ +#define TRACE_ACTIVE_LEVEL_ALL 0x1F +/** print all traces same as above */ +#define TRACE_ACTIVE_LEVEL_DEBUG 0x1f +/** print info,warn and error traces */ +#define TRACE_ACTIVE_LEVEL_INFO 0x0f +/** print warn and error traces */ +#define TRACE_ACTIVE_LEVEL_WARN 0x07 +/** print only error trace */ +#define TRACE_ACTIVE_LEVEL_ERROR 0x03 +/** print only cmd line data */ +#define TRACE_ACTIVE_LEVEL_CMD 0x01 +/** trace nothing */ +#define TRACE_ACTIVE_LEVEL_NONE 0x00 + +/** this print is some deep information for debug purpose */ +#define TRACE_LEVEL_DEBUG 0x10 +/** Info print, for general purpose prints */ +#define TRACE_LEVEL_INFO 0x08 +/** warning prints, which shouldn't causes any huge problems */ +#define TRACE_LEVEL_WARN 0x04 +/** Error prints, which causes probably problems, e.g. out of mem. */ +#define TRACE_LEVEL_ERROR 0x02 +/** special level for cmdline. Behaviours like "plain mode" */ +#define TRACE_LEVEL_CMD 0x01 + +#ifndef MBED_TRACE_MAX_LEVEL +#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO +#endif + +//usage macros: +#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_DEBUG +#define tr_debug(...) mbed_tracef(TRACE_LEVEL_DEBUG, TRACE_GROUP, __VA_ARGS__) //!< Print debug message +#else +#define tr_debug(...) +#endif + +#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_INFO +#define tr_info(...) mbed_tracef(TRACE_LEVEL_INFO, TRACE_GROUP, __VA_ARGS__) //!< Print info message +#else +#define tr_info(...) +#endif + +#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_WARN +#define tr_warning(...) mbed_tracef(TRACE_LEVEL_WARN, TRACE_GROUP, __VA_ARGS__) //!< Print warning message +#define tr_warn(...) mbed_tracef(TRACE_LEVEL_WARN, TRACE_GROUP, __VA_ARGS__) //!< Alternative warning message +#else +#define tr_warning(...) +#define tr_warn(...) +#endif + +#if MBED_TRACE_MAX_LEVEL >= TRACE_LEVEL_ERROR +#define tr_error(...) mbed_tracef(TRACE_LEVEL_ERROR, TRACE_GROUP, __VA_ARGS__) //!< Print Error Message +#define tr_err(...) mbed_tracef(TRACE_LEVEL_ERROR, TRACE_GROUP, __VA_ARGS__) //!< Alternative error message +#else +#define tr_error(...) +#define tr_err(...) +#endif + +#define tr_cmdline(...) mbed_tracef(TRACE_LEVEL_CMD, TRACE_GROUP, __VA_ARGS__) //!< Special print for cmdline. See more from TRACE_LEVEL_CMD -level + +//aliases for the most commonly used functions and the helper functions +#define tracef(dlevel, grp, ...) mbed_tracef(dlevel, grp, __VA_ARGS__) //!< Alias for mbed_tracef() +#define vtracef(dlevel, grp, fmt, ap) mbed_vtracef(dlevel, grp, fmt, ap) //!< Alias for mbed_vtracef() +#define tr_array(buf, len) mbed_trace_array(buf, len) //!< Alias for mbed_trace_array() +#define tr_ipv6(addr_ptr) mbed_trace_ipv6(addr_ptr) //!< Alias for mbed_trace_ipv6() +#define tr_ipv6_prefix(prefix, prefix_len) mbed_trace_ipv6_prefix(prefix, prefix_len) //!< Alias for mbed_trace_ipv6_prefix() +#define trace_array(buf, len) mbed_trace_array(buf, len) //!< Alias for mbed_trace_array() +#define trace_ipv6(addr_ptr) mbed_trace_ipv6(addr_ptr) //!< Alias for mbed_trace_ipv6() +#define trace_ipv6_prefix(prefix, prefix_len) mbed_trace_ipv6_prefix(prefix, prefix_len) //!< Alias for mbed_trace_ipv6_prefix() + + +/** + * Allow specification of default TRACE_GROUP to be used if not specified by application + */ + +#ifndef TRACE_GROUP +#ifdef YOTTA_CFG_MBED_TRACE_GROUP +#define TRACE_GROUP_STR_HELPER(x) #x +#define TRACE_GROUP_STR(x) TRACE_GROUP_STR_HELPER(x) +#define TRACE_GROUP TRACE_GROUP_STR(YOTTA_CFG_MBED_TRACE_GROUP) +#endif +#endif + +/** + * Initialize trace functionality + * @return 0 when all success, otherwise non zero + */ +int mbed_trace_init(void); +/** + * Free trace memory + */ +void mbed_trace_free(void); +/** + * Resize buffers (line / tmp ) sizes + * @param lineLength new maximum length for trace line (0 = do no resize) + * @param tmpLength new maximum length for trace tmp buffer (used for trace_array, etc) (0 = do no resize) + */ +void mbed_trace_buffer_sizes(int lineLength, int tmpLength); +/** + * Set trace configurations + * Possible parameters: + * + * TRACE_MODE_COLOR + * TRACE_MODE_PLAIN (this exclude color mode) + * TRACE_CARRIAGE_RETURN (print CR before trace line) + * + * TRACE_ACTIVE_LEVEL_ALL - to activate all trace levels + * or TRACE_ACTIVE_LEVEL_DEBUG (alternative) + * TRACE_ACTIVE_LEVEL_INFO + * TRACE_ACTIVE_LEVEL_WARN + * TRACE_ACTIVE_LEVEL_ERROR + * TRACE_ACTIVE_LEVEL_CMD + * TRACE_LEVEL_NONE - to deactivate all traces + * + * @param config Byte size Bit-mask. Bits are descripted above. + * usage e.g. + * @code + * mbed_trace_config_set( TRACE_ACTIVE_LEVEL_ALL|TRACE_MODE_COLOR ); + * @endcode + */ +void mbed_trace_config_set(uint8_t config); +/** get trace configurations + * @return trace configuration byte + */ +uint8_t mbed_trace_config_get(void); +/** + * Set trace prefix function + * pref_f -function return string with null terminated + * Can be used for e.g. time string + * e.g. + * char* trace_time(){ return "rtc-time-in-string"; } + * mbed_trace_prefix_function_set( &trace_time ); + */ +void mbed_trace_prefix_function_set(char *(*pref_f)(size_t)); +/** + * Set trace suffix function + * suffix -function return string with null terminated + * Can be used for e.g. time string + * e.g. + * char* trace_suffix(){ return " END"; } + * mbed_trace_suffix_function_set( &trace_suffix ); + */ +void mbed_trace_suffix_function_set(char *(*suffix_f)(void)); +/** + * Set trace print function + * By default, trace module print using printf() function, + * but with this you can write own print function, + * for e.g. to other IO device. + */ +void mbed_trace_print_function_set(void (*print_f)(const char *)); +/** + * Set trace print function for tr_cmdline() + */ +void mbed_trace_cmdprint_function_set(void (*printf)(const char *)); +/** + * Set trace mutex wait function + * By default, trace calls are not thread safe. + * If thread safety is required this can be used to set a callback function that will be called before each trace call. + * The specific implementation is up to the application developer, but the mutex must count so it can + * be acquired from a single thread repeatedly. + */ +void mbed_trace_mutex_wait_function_set(void (*mutex_wait_f)(void)); +/** + * Set trace mutex release function + * By default, trace calls are not thread safe. + * If thread safety is required this can be used to set a callback function that will be called before returning from + * each trace call. The specific implementation is up to the application developer, but the mutex must count so it can + * be acquired from a single thread repeatedly. + */ +void mbed_trace_mutex_release_function_set(void (*mutex_release_f)(void)); +/** + * When trace group contains text in filters, + * trace print will be ignored. + * e.g.: + * mbed_trace_exclude_filters_set("mygr"); + * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "ougr", "This is not printed"); + */ +void mbed_trace_exclude_filters_set(char *filters); +/** get trace exclude filters + */ +const char *mbed_trace_exclude_filters_get(void); +/** + * When trace group contains text in filter, + * trace will be printed. + * e.g.: + * set_trace_include_filters("mygr"); + * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "mygr", "Hi There"); + * mbed_tracef(TRACE_ACTIVE_LEVEL_DEBUG, "grp2", "This is not printed"); + */ +void mbed_trace_include_filters_set(char *filters); +/** get trace include filters + */ +const char *mbed_trace_include_filters_get(void); +/** + * General trace function + * This should be used every time when user want to print out something important thing + * Usage e.g. + * mbed_tracef( TRACE_LEVEL_INFO, "mygr", "Hello world!"); + * + * @param dlevel debug level + * @param grp trace group + * @param fmt trace format (like printf) + * @param ... variable arguments related to fmt + */ +#if defined(__GNUC__) || defined(__CC_ARM) +void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...) __attribute__((__format__(__printf__, 3, 4))); +#else +void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...); +#endif +/** + * General trace function + * This should be used every time when user want to print out something important thing + * and vprintf functionality is desired + * Usage e.g. + * va_list ap; + * va_start (ap, fmt); + * mbed_vtracef( TRACE_LEVEL_INFO, "mygr", fmt, ap ); + * va_end (ap); + * + * @param dlevel debug level + * @param grp trace group + * @param fmt trace format (like vprintf) + * @param ap variable arguments list (like vprintf) + */ +#if defined(__GNUC__) || defined(__CC_ARM) +void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap) __attribute__((__format__(__printf__, 3, 0))); +#else +void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap); +#endif + + +/** + * Get last trace from buffer + */ +const char *mbed_trace_last(void); +#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 +/** + * mbed_tracef helping function for convert ipv6 + * table to human readable string. + * usage e.g. + * char ipv6[16] = {...}; // ! array length is 16 bytes ! + * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "ipv6 addr: %s", mbed_trace_ipv6(ipv6)); + * + * @param add_ptr IPv6 Address pointer + * @return temporary buffer where ipv6 is in string format + */ +char *mbed_trace_ipv6(const void *addr_ptr); +/** + * mbed_tracef helping function for print ipv6 prefix + * usage e.g. + * char ipv6[16] = {...}; // ! array length is 16 bytes ! + * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "ipv6 addr: %s", mbed_trace_ipv6_prefix(ipv6, 4)); + * + * @param prefix IPv6 Address pointer + * @param prefix_len prefix length + * @return temporary buffer where ipv6 is in string format + */ +char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len); +#endif +/** + * mbed_tracef helping function for convert hex-array to string. + * usage e.g. + * char myarr[] = {0x10, 0x20}; + * mbed_tracef(TRACE_LEVEL_INFO, "mygr", "arr: %s", mbed_trace_array(myarr, 2)); + * + * @param buf hex array pointer + * @param len buffer length + * @return temporary buffer where string copied + * if array as string not fit to temp buffer, this function write '*' as last character, + * which indicate that buffer is too small for array. + */ +char *mbed_trace_array(const uint8_t *buf, uint16_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* MBED_TRACE_H_ */ + +/* These macros are outside the inclusion guard so they will be re-evaluated for every inclusion of the header. + * If tracing is disabled, the dummies will hide the real functions. The real functions can still be reached by + * surrounding the name of the function with brackets, e.g. "(mbed_tracef)(dlevel, grp, "like so");" + * */ +#if defined(FEA_TRACE_SUPPORT) || MBED_CONF_MBED_TRACE_ENABLE || YOTTA_CFG_MBED_TRACE || (defined(YOTTA_CFG) && !defined(NDEBUG)) +// Make sure FEA_TRACE_SUPPORT is always set whenever traces are enabled. +#ifndef FEA_TRACE_SUPPORT +#define FEA_TRACE_SUPPORT +#endif +// undefine dummies, revealing the real functions +#undef MBED_TRACE_DUMMIES_DEFINED +#undef mbed_trace_init +#undef mbed_trace_free +#undef mbed_trace_buffer_sizes +#undef mbed_trace_config_set +#undef mbed_trace_config_get +#undef mbed_trace_prefix_function_set +#undef mbed_trace_suffix_function_set +#undef mbed_trace_print_function_set +#undef mbed_trace_cmdprint_function_set +#undef mbed_trace_mutex_wait_function_set +#undef mbed_trace_mutex_release_function_set +#undef mbed_trace_exclude_filters_set +#undef mbed_trace_exclude_filters_get +#undef mbed_trace_include_filters_set +#undef mbed_trace_include_filters_get +#undef mbed_tracef +#undef mbed_vtracef +#undef mbed_trace_last +#undef mbed_trace_ipv6 +#undef mbed_trace_ipv6_prefix +#undef mbed_trace_array + +#elif !defined(MBED_TRACE_DUMMIES_DEFINED) +// define dummies, hiding the real functions +#define MBED_TRACE_DUMMIES_DEFINED +#define mbed_trace_init(...) ((int) 0) +#define mbed_trace_free(...) ((void) 0) +#define mbed_trace_buffer_sizes(...) ((void) 0) +#define mbed_trace_config_set(...) ((void) 0) +#define mbed_trace_config_get(...) ((uint8_t) 0) +#define mbed_trace_prefix_function_set(...) ((void) 0) +#define mbed_trace_suffix_function_set(...) ((void) 0) +#define mbed_trace_print_function_set(...) ((void) 0) +#define mbed_trace_cmdprint_function_set(...) ((void) 0) +#define mbed_trace_mutex_wait_function_set(...) ((void) 0) +#define mbed_trace_mutex_release_function_set(...) ((void) 0) +#define mbed_trace_exclude_filters_set(...) ((void) 0) +#define mbed_trace_exclude_filters_get(...) ((const char *) 0) +#define mbed_trace_include_filters_set(...) ((void) 0) +#define mbed_trace_include_filters_get(...) ((const char *) 0) +#define mbed_trace_last(...) ((const char *) 0) +#define mbed_tracef(...) ((void) 0) +#define mbed_vtracef(...) ((void) 0) +/** + * These helper functions accumulate strings in a buffer that is only flushed by actual trace calls. Using these + * functions outside trace calls could cause the buffer to overflow. + */ +#define mbed_trace_ipv6(...) dont_use_trace_helpers_outside_trace_calls +#define mbed_trace_ipv6_prefix(...) dont_use_trace_helpers_outside_trace_calls +#define mbed_trace_array(...) dont_use_trace_helpers_outside_trace_calls + +#endif /* FEA_TRACE_SUPPORT */ diff --git a/platform/mbed-trace/mbed_lib.json b/platform/mbed-trace/mbed_lib.json new file mode 100644 index 0000000..f58ccb2 --- /dev/null +++ b/platform/mbed-trace/mbed_lib.json @@ -0,0 +1,28 @@ +{ + "name": "mbed-trace", + "config": { + "enable": { + "help": "Used to globally enable traces.", + "value": null + }, + "max-level": { + "help": "This flag is used to optimize the code size. For example, setting trace optimization level to TRACE_LEVEL_INFO will define all tr_debug() macros empty, which reduces the binary size. The possible optimization levels are TRACE_LEVEL_DEBUG, TRACE_LEVEL_INFO, TRACE_LEVEL_WARN, TRACE_LEVEL_ERROR and TRACE_LEVEL_CMD. To set the output tracing level, please use mbed_trace_config_set(TRACE_ACTIVE_LEVEL_INFO). The possible tracing levels for mbed_trace_config_set() are TRACE_ACTIVE_LEVEL_ALL, TRACE_ACTIVE_LEVEL_DEBUG (same as ALL), TRACE_ACTIVE_LEVEL_INFO, TRACE_ACTIVE_LEVEL_WARN, TRACE_ACTIVE_LEVEL_ERROR, TRACE_ACTIVE_LEVEL_CMD and TRACE_LEVEL_NONE.", + "value": null, + "macro_name": "MBED_TRACE_MAX_LEVEL" + + }, + "fea-ipv6": { + "help": "Used to globally disable ipv6 tracing features.", + "value": null + }, + "allocator": { + "value": "malloc", + "macro_name": "MEM_ALLOC" + }, + "deallocator": { + "value": "free", + "macro_name": "MEM_FREE" + } + + } +} \ No newline at end of file diff --git a/platform/mbed-trace/source/CMakeLists.txt b/platform/mbed-trace/source/CMakeLists.txt new file mode 100644 index 0000000..7e7a0a08 --- /dev/null +++ b/platform/mbed-trace/source/CMakeLists.txt @@ -0,0 +1,18 @@ +if(DEFINED TARGET_LIKE_X86_LINUX_NATIVE) + add_library( mbed-trace + mbed_trace.c + ) + add_definitions("-g -O0 -fprofile-arcs -ftest-coverage") + target_link_libraries(mbed-trace gcov nanostack-libservice) +elseif(DEFINED TARGET_LIKE_X86_OSX_NATIVE) + add_library( mbed-trace + mbed_trace.c + ) + add_definitions("-g -O0") + target_link_libraries(mbed-trace nanostack-libservice) +else() + add_library( mbed-trace + mbed_trace.c + ) + target_link_libraries(mbed-trace nanostack-libservice) +endif() diff --git a/platform/mbed-trace/source/mbed_trace.c b/platform/mbed-trace/source/mbed_trace.c new file mode 100644 index 0000000..f90e0ea --- /dev/null +++ b/platform/mbed-trace/source/mbed_trace.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2014-2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#ifdef MBED_CONF_MBED_TRACE_ENABLE +#undef MBED_CONF_MBED_TRACE_ENABLE +#endif +#define MBED_CONF_MBED_TRACE_ENABLE 1 +#ifndef MBED_CONF_MBED_TRACE_FEA_IPV6 +#define MBED_CONF_MBED_TRACE_FEA_IPV6 1 +#endif + +#include "mbed-trace/mbed_trace.h" +#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 +#include "mbed-client-libservice/ip6string.h" +#include "mbed-client-libservice/common_functions.h" +#endif + +#if defined(YOTTA_CFG_MBED_TRACE_MEM) +#define MBED_TRACE_MEM_INCLUDE YOTTA_CFG_MBED_TRACE_MEM_INCLUDE +#define MBED_TRACE_MEM_ALLOC YOTTA_CFG_MBED_TRACE_MEM_ALLOC +#define MBED_TRACE_MEM_FREE YOTTA_CFG_MBED_TRACE_MEM_FREE +#else /* YOTTA_CFG_MEMLIB */ +// Default options +#ifndef MBED_TRACE_MEM_INCLUDE +#define MBED_TRACE_MEM_INCLUDE +#endif +#include MBED_TRACE_MEM_INCLUDE +#ifndef MBED_TRACE_MEM_ALLOC +#define MBED_TRACE_MEM_ALLOC malloc +#endif +#ifndef MBED_TRACE_MEM_FREE +#define MBED_TRACE_MEM_FREE free +#endif +#endif /* YOTTA_CFG_MEMLIB */ + +#define VT100_COLOR_ERROR "\x1b[31m" +#define VT100_COLOR_WARN "\x1b[33m" +#define VT100_COLOR_INFO "\x1b[39m" +#define VT100_COLOR_DEBUG "\x1b[90m" + +/** default max trace line size in bytes */ +#ifdef MBED_TRACE_LINE_LENGTH +#define DEFAULT_TRACE_LINE_LENGTH MBED_TRACE_LINE_LENGTH +#elif defined YOTTA_CFG_MBED_TRACE_LINE_LENGTH +#warning YOTTA_CFG_MBED_TRACE_LINE_LENGTH is deprecated and will be removed in the future! Use MBED_TRACE_LINE_LENGTH instead. +#define DEFAULT_TRACE_LINE_LENGTH YOTTA_CFG_MBED_TRACE_LINE_LENGTH +#else +#define DEFAULT_TRACE_LINE_LENGTH 1024 +#endif + +/** default max temporary buffer size in bytes, used in + trace_ipv6, trace_ipv6_prefix and trace_array */ +#ifdef MBED_TRACE_TMP_LINE_LENGTH +#define DEFAULT_TRACE_TMP_LINE_LEN MBED_TRACE_TMP_LINE_LENGTH +#elif defined YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN +#warning The YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. +#define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MBED_TRACE_TMP_LINE_LEN +#elif defined YOTTA_CFG_MTRACE_TMP_LINE_LEN +#warning The YOTTA_CFG_MTRACE_TMP_LINE_LEN flag is deprecated and will be removed in the future! Use MBED_TRACE_TMP_LINE_LENGTH instead. +#define DEFAULT_TRACE_TMP_LINE_LEN YOTTA_CFG_MTRACE_TMP_LINE_LEN +#else +#define DEFAULT_TRACE_TMP_LINE_LEN 128 +#endif + +/** default max filters (include/exclude) length in bytes */ +#ifdef MBED_TRACE_FILTER_LENGTH +#define DEFAULT_TRACE_FILTER_LENGTH MBED_TRACE_FILTER_LENGTH +#else +#define DEFAULT_TRACE_FILTER_LENGTH 24 +#endif + +/** default trace configuration bitmask */ +#ifdef MBED_TRACE_CONFIG +#define DEFAULT_TRACE_CONFIG MBED_TRACE_CONFIG +#else +#define DEFAULT_TRACE_CONFIG TRACE_MODE_COLOR | TRACE_ACTIVE_LEVEL_ALL | TRACE_CARRIAGE_RETURN +#endif + +/** default print function, just redirect str to printf */ +static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length); +static void mbed_trace_default_print(const char *str); +static void mbed_trace_reset_tmp(void); + +typedef struct trace_s { + /** trace configuration bits */ + uint8_t trace_config; + /** exclude filters list, related group name */ + char *filters_exclude; + /** include filters list, related group name */ + char *filters_include; + /** Filters length */ + int filters_length; + /** trace line */ + char *line; + /** trace line length */ + int line_length; + /** temporary data */ + char *tmp_data; + /** temporary data array length */ + int tmp_data_length; + /** temporary data pointer */ + char *tmp_data_ptr; + + /** prefix function, which can be used to put time to the trace line */ + char *(*prefix_f)(size_t); + /** suffix function, which can be used to some string to the end of trace line */ + char *(*suffix_f)(void); + /** print out function. Can be redirect to flash for example. */ + void (*printf)(const char *); + /** print out function for TRACE_LEVEL_CMD */ + void (*cmd_printf)(const char *); + /** mutex wait function which can be called to lock against a mutex. */ + void (*mutex_wait_f)(void); + /** mutex release function which must be used to release the mutex locked by mutex_wait_f. */ + void (*mutex_release_f)(void); + /** number of times the mutex has been locked */ + int mutex_lock_count; +} trace_t; + +static trace_t m_trace = { + .trace_config = DEFAULT_TRACE_CONFIG, + .filters_exclude = 0, + .filters_include = 0, + .filters_length = DEFAULT_TRACE_FILTER_LENGTH, + .line = 0, + .line_length = DEFAULT_TRACE_LINE_LENGTH, + .tmp_data = 0, + .tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN, + .tmp_data_ptr = 0, + .prefix_f = 0, + .suffix_f = 0, + .printf = mbed_trace_default_print, + .cmd_printf = 0, + .mutex_wait_f = 0, + .mutex_release_f = 0, + .mutex_lock_count = 0 +}; + +int mbed_trace_init(void) +{ + if (m_trace.line == NULL) { + m_trace.line = MBED_TRACE_MEM_ALLOC(m_trace.line_length); + } + + if (m_trace.tmp_data == NULL) { + m_trace.tmp_data = MBED_TRACE_MEM_ALLOC(m_trace.tmp_data_length); + } + m_trace.tmp_data_ptr = m_trace.tmp_data; + + if (m_trace.filters_exclude == NULL) { + m_trace.filters_exclude = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); + } + if (m_trace.filters_include == NULL) { + m_trace.filters_include = MBED_TRACE_MEM_ALLOC(m_trace.filters_length); + } + + if (m_trace.line == NULL || + m_trace.tmp_data == NULL || + m_trace.filters_exclude == NULL || + m_trace.filters_include == NULL) { + //memory allocation fail + mbed_trace_free(); + return -1; + } + memset(m_trace.tmp_data, 0, m_trace.tmp_data_length); + memset(m_trace.filters_exclude, 0, m_trace.filters_length); + memset(m_trace.filters_include, 0, m_trace.filters_length); + memset(m_trace.line, 0, m_trace.line_length); + + return 0; +} +void mbed_trace_free(void) +{ + // release memory + MBED_TRACE_MEM_FREE(m_trace.line); + MBED_TRACE_MEM_FREE(m_trace.tmp_data); + MBED_TRACE_MEM_FREE(m_trace.filters_exclude); + MBED_TRACE_MEM_FREE(m_trace.filters_include); + + // reset to default values + m_trace.trace_config = DEFAULT_TRACE_CONFIG; + m_trace.filters_exclude = 0; + m_trace.filters_include = 0; + m_trace.filters_length = DEFAULT_TRACE_FILTER_LENGTH; + m_trace.line = 0; + m_trace.line_length = DEFAULT_TRACE_LINE_LENGTH; + m_trace.tmp_data = 0; + m_trace.tmp_data_length = DEFAULT_TRACE_TMP_LINE_LEN; + m_trace.prefix_f = 0; + m_trace.suffix_f = 0; + m_trace.printf = mbed_trace_default_print; + m_trace.cmd_printf = 0; + m_trace.mutex_wait_f = 0; + m_trace.mutex_release_f = 0; + m_trace.mutex_lock_count = 0; +} +static void mbed_trace_realloc(char **buffer, int *length_ptr, int new_length) +{ + MBED_TRACE_MEM_FREE(*buffer); + *buffer = MBED_TRACE_MEM_ALLOC(new_length); + *length_ptr = new_length; +} +void mbed_trace_buffer_sizes(int lineLength, int tmpLength) +{ + if (lineLength > 0) { + mbed_trace_realloc(&(m_trace.line), &m_trace.line_length, lineLength); + } + if (tmpLength > 0) { + mbed_trace_realloc(&(m_trace.tmp_data), &m_trace.tmp_data_length, tmpLength); + mbed_trace_reset_tmp(); + } +} +void mbed_trace_config_set(uint8_t config) +{ + m_trace.trace_config = config; +} +uint8_t mbed_trace_config_get(void) +{ + return m_trace.trace_config; +} +void mbed_trace_prefix_function_set(char *(*pref_f)(size_t)) +{ + m_trace.prefix_f = pref_f; +} +void mbed_trace_suffix_function_set(char *(*suffix_f)(void)) +{ + m_trace.suffix_f = suffix_f; +} +void mbed_trace_print_function_set(void (*printf)(const char *)) +{ + m_trace.printf = printf; +} +void mbed_trace_cmdprint_function_set(void (*printf)(const char *)) +{ + m_trace.cmd_printf = printf; +} +void mbed_trace_mutex_wait_function_set(void (*mutex_wait_f)(void)) +{ + m_trace.mutex_wait_f = mutex_wait_f; +} +void mbed_trace_mutex_release_function_set(void (*mutex_release_f)(void)) +{ + m_trace.mutex_release_f = mutex_release_f; +} +void mbed_trace_exclude_filters_set(char *filters) +{ + if (filters) { + (void)strncpy(m_trace.filters_exclude, filters, m_trace.filters_length); + } else { + m_trace.filters_exclude[0] = 0; + } +} +const char *mbed_trace_exclude_filters_get(void) +{ + return m_trace.filters_exclude; +} +const char *mbed_trace_include_filters_get(void) +{ + return m_trace.filters_include; +} +void mbed_trace_include_filters_set(char *filters) +{ + if (filters) { + (void)strncpy(m_trace.filters_include, filters, m_trace.filters_length); + } else { + m_trace.filters_include[0] = 0; + } +} +static int8_t mbed_trace_skip(int8_t dlevel, const char *grp) +{ + if (dlevel >= 0 && grp != 0) { + // filter debug prints only when dlevel is >0 and grp is given + + /// @TODO this could be much better.. + if (m_trace.filters_exclude[0] != '\0' && + strstr(m_trace.filters_exclude, grp) != 0) { + //grp was in exclude list + return 1; + } + if (m_trace.filters_include[0] != '\0' && + strstr(m_trace.filters_include, grp) == 0) { + //grp was in include list + return 1; + } + } + return 0; +} +static void mbed_trace_default_print(const char *str) +{ + puts(str); +} +void mbed_tracef(uint8_t dlevel, const char *grp, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + mbed_vtracef(dlevel, grp, fmt, ap); + va_end(ap); +} +void mbed_vtracef(uint8_t dlevel, const char *grp, const char *fmt, va_list ap) +{ + if (m_trace.mutex_wait_f) { + m_trace.mutex_wait_f(); + m_trace.mutex_lock_count++; + } + + if (NULL == m_trace.line) { + goto end; + } + + m_trace.line[0] = 0; //by default trace is empty + + if (mbed_trace_skip(dlevel, grp) || fmt == 0 || grp == 0 || !m_trace.printf) { + //return tmp data pointer back to the beginning + mbed_trace_reset_tmp(); + goto end; + } + if ((m_trace.trace_config & TRACE_MASK_LEVEL) & dlevel) { + bool color = (m_trace.trace_config & TRACE_MODE_COLOR) != 0; + bool plain = (m_trace.trace_config & TRACE_MODE_PLAIN) != 0; + bool cr = (m_trace.trace_config & TRACE_CARRIAGE_RETURN) != 0; + + int retval = 0, bLeft = m_trace.line_length; + char *ptr = m_trace.line; + if (plain == true || dlevel == TRACE_LEVEL_CMD) { + //add trace data + retval = vsnprintf(ptr, bLeft, fmt, ap); + if (dlevel == TRACE_LEVEL_CMD && m_trace.cmd_printf) { + m_trace.cmd_printf(m_trace.line); + m_trace.cmd_printf("\n"); + } else { + //print out whole data + m_trace.printf(m_trace.line); + } + } else { + if (color) { + if (cr) { + retval = snprintf(ptr, bLeft, "\r\x1b[2K"); + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + ptr += retval; + bLeft -= retval; + } + } + if (bLeft > 0) { + //include color in ANSI/VT100 escape code + switch (dlevel) { + case (TRACE_LEVEL_ERROR): + retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_ERROR); + break; + case (TRACE_LEVEL_WARN): + retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_WARN); + break; + case (TRACE_LEVEL_INFO): + retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_INFO); + break; + case (TRACE_LEVEL_DEBUG): + retval = snprintf(ptr, bLeft, "%s", VT100_COLOR_DEBUG); + break; + default: + color = 0; //avoid unneeded color-terminate code + retval = 0; + break; + } + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0 && color) { + ptr += retval; + bLeft -= retval; + } + } + + } + if (bLeft > 0 && m_trace.prefix_f) { + //find out length of body + size_t sz = 0; + va_list ap2; + va_copy(ap2, ap); + sz = vsnprintf(NULL, 0, fmt, ap2) + retval + (retval ? 4 : 0); + va_end(ap2); + //add prefix string + retval = snprintf(ptr, bLeft, "%s", m_trace.prefix_f(sz)); + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + ptr += retval; + bLeft -= retval; + } + } + if (bLeft > 0) { + //add group tag + switch (dlevel) { + case (TRACE_LEVEL_ERROR): + retval = snprintf(ptr, bLeft, "[ERR ][%-4s]: ", grp); + break; + case (TRACE_LEVEL_WARN): + retval = snprintf(ptr, bLeft, "[WARN][%-4s]: ", grp); + break; + case (TRACE_LEVEL_INFO): + retval = snprintf(ptr, bLeft, "[INFO][%-4s]: ", grp); + break; + case (TRACE_LEVEL_DEBUG): + retval = snprintf(ptr, bLeft, "[DBG ][%-4s]: ", grp); + break; + default: + retval = snprintf(ptr, bLeft, " "); + break; + } + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + ptr += retval; + bLeft -= retval; + } + } + if (retval > 0 && bLeft > 0) { + //add trace text + retval = vsnprintf(ptr, bLeft, fmt, ap); + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + ptr += retval; + bLeft -= retval; + } + } + + if (retval > 0 && bLeft > 0 && m_trace.suffix_f) { + //add suffix string + retval = snprintf(ptr, bLeft, "%s", m_trace.suffix_f()); + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + ptr += retval; + bLeft -= retval; + } + } + + if (retval > 0 && bLeft > 0 && color) { + //add zero color VT100 when color mode + retval = snprintf(ptr, bLeft, "\x1b[0m"); + if (retval >= bLeft) { + retval = 0; + } + if (retval > 0) { + // not used anymore + //ptr += retval; + //bLeft -= retval; + } + } + //print out whole data + m_trace.printf(m_trace.line); + } + //return tmp data pointer back to the beginning + mbed_trace_reset_tmp(); + } + +end: + if (m_trace.mutex_release_f) { + // Store the mutex lock count to temp variable so that it won't get + // clobbered during last loop iteration when mutex gets released + int count = m_trace.mutex_lock_count; + m_trace.mutex_lock_count = 0; + // Since the helper functions (eg. mbed_trace_array) are used like this: + // mbed_tracef(TRACE_LEVEL_INFO, "grp", "%s", mbed_trace_array(some_array)) + // The helper function MUST acquire the mutex if it modifies any buffers. However + // it CANNOT unlock the mutex because that would allow another thread to acquire + // the mutex after helper function unlocks it and before mbed_tracef acquires it + // for itself. This means that here we have to unlock the mutex as many times + // as it was acquired by trace function and any possible helper functions. + do { + m_trace.mutex_release_f(); + } while (--count > 0); + } +} +static void mbed_trace_reset_tmp(void) +{ + m_trace.tmp_data_ptr = m_trace.tmp_data; +} +const char *mbed_trace_last(void) +{ + return m_trace.line; +} +/* Helping functions */ +#define tmp_data_left() m_trace.tmp_data_length-(m_trace.tmp_data_ptr-m_trace.tmp_data) +#if MBED_CONF_MBED_TRACE_FEA_IPV6 == 1 +char *mbed_trace_ipv6(const void *addr_ptr) +{ + /** Acquire mutex. It is released before returning from mbed_vtracef. */ + if (m_trace.mutex_wait_f) { + m_trace.mutex_wait_f(); + m_trace.mutex_lock_count++; + } + char *str = m_trace.tmp_data_ptr; + if (str == NULL) { + return ""; + } + if (tmp_data_left() < 41) { + return ""; + } + if (addr_ptr == NULL) { + return ""; + } + str[0] = 0; + m_trace.tmp_data_ptr += ip6tos(addr_ptr, str) + 1; + return str; +} +char *mbed_trace_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len) +{ + /** Acquire mutex. It is released before returning from mbed_vtracef. */ + if (m_trace.mutex_wait_f) { + m_trace.mutex_wait_f(); + m_trace.mutex_lock_count++; + } + char *str = m_trace.tmp_data_ptr; + if (str == NULL) { + return ""; + } + if (tmp_data_left() < 45) { + return ""; + } + + if ((prefix_len != 0 && prefix == NULL) || prefix_len > 128) { + return ""; + } + + m_trace.tmp_data_ptr += ip6_prefix_tos(prefix, prefix_len, str) + 1; + return str; +} +#endif //MBED_CONF_MBED_TRACE_FEA_IPV6 +char *mbed_trace_array(const uint8_t *buf, uint16_t len) +{ + /** Acquire mutex. It is released before returning from mbed_vtracef. */ + if (m_trace.mutex_wait_f) { + m_trace.mutex_wait_f(); + m_trace.mutex_lock_count++; + } + int i, bLeft = tmp_data_left(); + char *str, *wptr; + str = m_trace.tmp_data_ptr; + if (len == 0 || str == NULL || bLeft == 0) { + return ""; + } + if (buf == NULL) { + return ""; + } + wptr = str; + wptr[0] = 0; + const uint8_t *ptr = buf; + char overflow = 0; + for (i = 0; i < len; i++) { + if (bLeft <= 3) { + overflow = 1; + break; + } + int retval = snprintf(wptr, bLeft, "%02x:", *ptr++); + if (retval <= 0 || retval > bLeft) { + break; + } + bLeft -= retval; + wptr += retval; + } + if (wptr > str) { + if (overflow) { + // replace last character as 'star', + // which indicate buffer len is not enough + *(wptr - 1) = '*'; + } else { + //null to replace last ':' character + *(wptr - 1) = 0; + } + } + m_trace.tmp_data_ptr = wptr; + return str; +} diff --git a/storage/kvstore/source/FileSystemStore.cpp b/storage/kvstore/source/FileSystemStore.cpp index 828ff59..7f5ad5d 100644 --- a/storage/kvstore/source/FileSystemStore.cpp +++ b/storage/kvstore/source/FileSystemStore.cpp @@ -26,7 +26,7 @@ #include #include -#include "mbed_trace.h" +#include "mbed-trace/mbed_trace.h" #define TRACE_GROUP "FSST" #define FSST_REVISION 1 diff --git a/storage/kvstore/tests/UNITTESTS/FileSystemStore/unittest.cmake b/storage/kvstore/tests/UNITTESTS/FileSystemStore/unittest.cmake index e924627..30230a6 100644 --- a/storage/kvstore/tests/UNITTESTS/FileSystemStore/unittest.cmake +++ b/storage/kvstore/tests/UNITTESTS/FileSystemStore/unittest.cmake @@ -5,7 +5,7 @@ set(unittest-includes ${unittest-includes} . .. - ../features/frameworks/mbed-trace/mbed-trace + ../platform/mbed-trace/mbed-trace ) set(unittest-sources @@ -15,7 +15,7 @@ ../storage/filesystem/source/Dir.cpp ../storage/filesystem/source/File.cpp ../storage/filesystem/source/FileSystem.cpp - ../features/frameworks/mbed-trace/source/mbed_trace.c + ../platform/mbed-trace/source/mbed_trace.c ../storage/filesystem/littlefs/littlefs/lfs_util.c ../storage/filesystem/littlefs/littlefs/lfs.c ../platform/source/FileBase.cpp diff --git a/storage/kvstore/tests/UNITTESTS/TDBStore/unittest.cmake b/storage/kvstore/tests/UNITTESTS/TDBStore/unittest.cmake index 373173e..dccc840 100644 --- a/storage/kvstore/tests/UNITTESTS/TDBStore/unittest.cmake +++ b/storage/kvstore/tests/UNITTESTS/TDBStore/unittest.cmake @@ -6,7 +6,7 @@ set(unittest-includes ${unittest-includes} . .. - ../features/frameworks/mbed-trace/mbed-trace + ../platform/mbed-trace/mbed-trace ) set(unittest-sources @@ -14,7 +14,7 @@ ../storage/blockdevice/source/HeapBlockDevice.cpp ../storage/blockdevice/source/BufferedBlockDevice.cpp ../storage/kvstore/source/TDBStore.cpp - ../features/frameworks/mbed-trace/source/mbed_trace.c + ../platform/mbed-trace/source/mbed_trace.c stubs/mbed_atomic_stub.c stubs/mbed_assert_stub.cpp stubs/mbed_error.c