Skip to content

Commit 14ff147

Browse files
author
Arto Kinnunen
committed
Squashed 'features/frameworks/mbed-trace/' changes from 7a1bd34..0a4f6be
0a4f6be astyle validation (ARMmbed#89) f43f52d add mention about mbed-os.lib generation and ignore example folder (ARMmbed#88) 3f48e87 .tmp_data_ptr = 0 added (ARMmbed#55) 9697f63 doc update + mbed-os 5 example application (ARMmbed#84) 891508b CI improvements - introduce Jenkinsfile (ARMmbed#87) git-subtree-dir: features/frameworks/mbed-trace git-subtree-split: 0a4f6be43da09feb2e55eae0697546bcc23d0a23
1 parent 1374a5e commit 14ff147

File tree

13 files changed

+459
-7
lines changed

13 files changed

+459
-7
lines changed

.astyleignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
BUILD

.astylerc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Mbed OS code style definition file for astyle
2+
3+
# Don't create backup files, let git handle it
4+
suffix=none
5+
6+
# K&R style
7+
style=kr
8+
9+
# 1 TBS addition to k&r, add braces to one liners
10+
# Use -j as it was changed in astyle from brackets to braces, this way it is compatible with older astyle versions
11+
-j
12+
13+
# 4 spaces, convert tabs to spaces
14+
indent=spaces=4
15+
convert-tabs
16+
17+
# Indent switches and cases
18+
indent-switches
19+
20+
# Remove spaces in and around parentheses
21+
unpad-paren
22+
23+
# Insert a space after if, while, for, and around operators
24+
pad-header
25+
pad-oper
26+
27+
# Pointer/reference operators go next to the name (on the right)
28+
align-pointer=name
29+
align-reference=name
30+
31+
# Attach { for classes and namespaces
32+
attach-namespaces
33+
attach-classes
34+
35+
# Extend longer lines, define maximum 120 value. This results in aligned code,
36+
# otherwise the lines are broken and not consistent
37+
max-continuation-indent=120

.mbedignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ build/*
22
yotta_modules/*
33
yotta_targets/*
44
test/*
5+
example/*

Jenkinsfile

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
echo "Start to build"
2+
3+
properties ([
4+
buildDiscarder(
5+
logRotator(
6+
artifactNumToKeepStr: '10',
7+
numToKeepStr: '100'
8+
)
9+
)
10+
])
11+
12+
// List of targets to compile
13+
def morpheusTargets = [
14+
//"LPC1768",
15+
//"NUCLEO_F401RE",
16+
//"NRF51DK",
17+
"K64F"
18+
]
19+
// Map morpheus toolchains to compiler labels on Jenkins
20+
def toolchains = [
21+
ARM: "armcc",
22+
IAR: "iar_arm",
23+
GCC_ARM: "arm-none-eabi-gcc"
24+
]
25+
// yotta target includes toolchain
26+
def yottaTargets = [
27+
"frdm-k64f-gcc": "gcc",
28+
"frdm-k64f-armcc": "armcc",
29+
"nrf51dk-gcc": "gcc",
30+
"stm32f429i-disco-gcc": "gcc",
31+
"x86-linux-native": "linux && astyle"
32+
]
33+
34+
// Initial maps for parallel build steps
35+
def stepsForParallel = [:]
36+
// Jenkins pipeline does not support map.each, we need to use oldschool for loop
37+
for (int i = 0; i < morpheusTargets.size(); i++) {
38+
for(int j = 0; j < toolchains.size(); j++) {
39+
def target = morpheusTargets.get(i)
40+
def toolchain = toolchains.keySet().asList().get(j)
41+
def compilerLabel = toolchains.get(toolchain)
42+
def stepName = "mbed-os5-${target} ${toolchain}"
43+
stepsForParallel[stepName] = morpheusBuildStep(target, compilerLabel, toolchain)
44+
}
45+
}
46+
// map yotta steps
47+
for (int i = 0; i < yottaTargets.size(); i++) {
48+
def target = yottaTargets.keySet().asList().get(i)
49+
def compilerLabel = yottaTargets.get(target)
50+
def stepName = "mbed-os3-${target}"
51+
stepsForParallel[stepName] = yottaBuildStep(target, compilerLabel)
52+
}
53+
54+
/* Jenkins does not allow stages inside parallel execution,
55+
* https://issues.jenkins-ci.org/browse/JENKINS-26107 will solve this by adding labeled blocks
56+
*/
57+
// Actually run the steps in parallel - parallel takes a map as an argument, hence the above.
58+
timestamps {
59+
timeout(time: 30, unit: "MINUTES") {
60+
parallel stepsForParallel
61+
}
62+
}
63+
64+
def execute(cmd) {
65+
if(isUnix()) {
66+
sh "${cmd}"
67+
} else {
68+
bat "${cmd}"
69+
}
70+
}
71+
72+
//Create morpheus build steps for parallel execution
73+
def morpheusBuildStep(target, compilerLabel, toolchain) {
74+
return {
75+
node ("${compilerLabel}") {
76+
deleteDir()
77+
dir("mbed-trace") {
78+
String buildName = "mbed-os5-${target}-${toolchain}"
79+
def scmVars = checkout scm
80+
env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT
81+
setBuildStatus('PENDING', "build ${buildName}", 'build starts')
82+
stage ("build:${buildName}") {
83+
try{
84+
execute("mbed --version")
85+
execute("echo https://github.com/armmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9 > mbed-os.lib")
86+
execute("mbed deploy")
87+
execute("rm -rf ./mbed-os/features/frameworks/mbed-trace")
88+
execute("mbed compile -m ${target} -t ${toolchain} --library")
89+
setBuildStatus('SUCCESS', "build ${buildName}", "build done")
90+
} catch (err) {
91+
echo "Caught exception: ${err}"
92+
setBuildStatus('FAILURE', "build ${buildName}", "build failed")
93+
throw err
94+
}
95+
}
96+
stage("build:example:${buildName}") {
97+
execute("mkdir ../example-mbed-os-5 || true")
98+
execute("cp -R example/mbed-os-5 ../example-mbed-os-5")
99+
dir("../example-mbed-os-5") {
100+
def exampleName = "example-${buildName}"
101+
setBuildStatus('PENDING', "build ${exampleName}", 'build starts')
102+
try {
103+
execute("echo \"https://github.com/ARMmbed/mbed-os/#6a0a86538c0b9b2bfcc4583b1e2b7fea8f4e71e9\" > mbed-os.lib")
104+
execute("echo \"https://github.com/ARMmbed/mbed-trace#${env.GIT_COMMIT_HASH}\" > mbed-trace.lib")
105+
execute("mbed new .")
106+
execute("mbed deploy")
107+
execute("rm -rf ./mbed-os/features/frameworks/mbed-trace")
108+
execute("rm -rf ./mbed-trace/example")
109+
execute("rm -rf ./mbed-trace/test")
110+
execute("mbed compile -t ${toolchain} -m ${target}")
111+
setBuildStatus('SUCCESS', "build ${exampleName}", "build done")
112+
} catch(err) {
113+
echo "Caught exception: ${err}"
114+
setBuildStatus('FAILURE', "build ${exampleName}", "build failed")
115+
currentBuild.result = 'FAILURE'
116+
} finally {
117+
// clean up
118+
postBuild(buildName, false)
119+
step([$class: 'WsCleanup'])
120+
}
121+
}
122+
}
123+
}
124+
}
125+
}
126+
}
127+
128+
//Create yotta build steps for parallel execution
129+
def yottaBuildStep(target, compilerLabel) {
130+
return {
131+
String buildName = "mbed-os3-${target}"
132+
node ("${compilerLabel}") {
133+
deleteDir()
134+
dir("mbed-trace") {
135+
def scmVars = checkout scm
136+
env.GIT_COMMIT_HASH = scmVars.GIT_COMMIT
137+
def isTest = target == "x86-linux-native" // tests are valid only in linux target
138+
stage ("build:${buildName}") {
139+
setBuildStatus('PENDING', "build ${buildName}", 'build starts')
140+
try{
141+
execute("yotta --version")
142+
execute("yotta target $target")
143+
execute("yotta --plain build mbed-trace")
144+
setBuildStatus('SUCCESS', "build ${buildName}", "build done")
145+
} catch (err) {
146+
echo "Caught exception: ${err}"
147+
setBuildStatus('FAILURE', "build ${buildName}", "build failed")
148+
currentBuild.result = 'FAILURE'
149+
}
150+
} // stage
151+
if (isTest) {
152+
stage("test:${buildName}") {
153+
setBuildStatus('PENDING', "test ${buildName}", 'test starts')
154+
try {
155+
execute("yotta test mbed_trace_test")
156+
execute("lcov --base-directory . --directory . --capture --output-file coverage.info")
157+
execute("genhtml -o ./test_coverage coverage.info")
158+
execute("gcovr -x -o junit.xml")
159+
execute("cppcheck --enable=all --std=c99 --inline-suppr --template=\"{file},{line},{severity},{id},{message}\" source 2> cppcheck.txt")
160+
161+
// check if astyle is correct
162+
execute("astyle --options=.astylerc source/*.c mbed-trace/*.h")
163+
// check differency
164+
execute("git diff-index -p --exit-code HEAD")
165+
166+
setBuildStatus('SUCCESS', "test ${buildName}", "test done")
167+
} catch(err) {
168+
echo "Caught exception: ${err}"
169+
setBuildStatus('FAILURE', "test ${buildName}", "test failed")
170+
currentBuild.result = 'FAILURE'
171+
}
172+
} // stage
173+
stage("example:${buildName}") {
174+
dir("example/linux") {
175+
def exampleName = "example-linux"
176+
setBuildStatus('PENDING', "build ${exampleName}", 'build starts')
177+
try {
178+
execute("make")
179+
setBuildStatus('SUCCESS', "build ${exampleName}", "build done")
180+
} catch(err) {
181+
echo "Caught exception: ${err}"
182+
setBuildStatus('FAILURE', "build ${exampleName}", "build failed")
183+
currentBuild.result = 'FAILURE'
184+
}
185+
}
186+
} // stage
187+
188+
stage("leak-check:${buildName}") {
189+
dir("example/linux") {
190+
def stageName = "leak-check"
191+
setBuildStatus('PENDING', "test ${stageName}", 'test starts')
192+
try {
193+
execute("./memtest.sh")
194+
setBuildStatus('SUCCESS', "test ${stageName}", "test done")
195+
} catch(err) {
196+
echo "Caught exception: ${err}"
197+
setBuildStatus('FAILURE', "test ${stageName}", "test failed")
198+
currentBuild.result = 'FAILURE'
199+
}
200+
}
201+
} // stage
202+
} // if linux
203+
postBuild(buildName, isTest)
204+
step([$class: 'WsCleanup'])
205+
} // dir
206+
}
207+
}
208+
}
209+
210+
def postBuild(buildName, isTest) {
211+
// move files to target+toolchain specific folder
212+
execute("mkdir -p output/${buildName}")
213+
execute("find . -name 'libmbed-trace.a' -exec mv {} 'output/${buildName}' \\;")
214+
execute("find . -name 'mbed-trace.ar' -exec mv {} 'output/${buildName}' \\;")
215+
execute("find ../example-mbed-os-5 -name 'example-mbed-os-5.bin' -exec mv {} 'output/${buildName}/example-mbed-os-5.bin' \\; || true")
216+
// Archive artifacts
217+
step([
218+
$class: 'ArtifactArchiver',
219+
artifacts: "cppcheck.txt,output/**",
220+
fingerprint: true,
221+
allowEmptyArchive: true
222+
])
223+
if (isTest) {
224+
// Publish cobertura
225+
step([
226+
$class: 'CoberturaPublisher',
227+
coberturaReportFile: 'junit.xml'
228+
])
229+
// Publish compiler warnings
230+
step([
231+
$class: 'WarningsPublisher',
232+
parserConfigurations: [[
233+
parserName: 'GNU Make + GNU C Compiler (gcc)',
234+
pattern: 'mbed-trace/*.h,source/*.c,test/*.cpp'
235+
]],
236+
unstableTotalAll: '0',
237+
useDeltaValues: true,
238+
usePreviousBuildAsReference: true
239+
])
240+
// Publish HTML reports
241+
publishHTML(target: [
242+
alwayLinkToLastBuild: false,
243+
keepAll: true,
244+
reportDir: "test_coverage",
245+
reportFiles: "index.html",
246+
reportName: "Build HTML Report"
247+
])
248+
}
249+
}
250+
// helper function to set build status to github PR
251+
def setBuildStatus(String state, String context, String message) {
252+
step([
253+
$class: "GitHubCommitStatusSetter",
254+
reposSource: [
255+
$class: "ManuallyEnteredRepositorySource",
256+
url: "https://github.com/ARMmbed/mbed-trace.git"
257+
],
258+
contextSource: [
259+
$class: "ManuallyEnteredCommitContextSource",
260+
context: context
261+
],
262+
errorHandlers: [[
263+
$class: "ChangingBuildStatusErrorHandler",
264+
result: "UNSTABLE"
265+
]],
266+
commitShaSource: [
267+
$class: "ManuallyEnteredShaSource",
268+
sha: env.GIT_COMMIT_HASH
269+
],
270+
statusResultSource: [
271+
$class: 'ConditionalStatusResultSource',
272+
results: [
273+
[
274+
$class: 'AnyBuildResult',
275+
message: message,
276+
state: state
277+
]
278+
]
279+
]
280+
])
281+
}

README.md

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ The purpose of the library is to provide a light, simple and general tracing sol
2020
## Compromises
2121

2222
* The traces are stored as ASCII arrays in the flash memory (pretty high memory consumption). Therefore, it is not necessary to:
23-
* encode/decode the trace messages on the fly (this may take too much CPU time) or
24-
* have external dev-env dependencies to encode the traces compile time and an external application to decode the traces.
23+
* encode/decode the trace messages on the fly (this may take too much CPU time) or
24+
* have external dev-env dependencies to encode the traces compile time and an external application to decode the traces.
2525
* 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.
26-
* The trace function uses `stdout` as the default output target because it goes directly to serial port when initialized.
26+
* The trace function uses `stdout` as the default output target because it goes directly to serial port in mbed-os.
2727
* The trace function produces traces like: `[<levl>][grp ]: msg`. This provides an easy way to detect trace prints and separate traces from normal prints (for example with _regex_).
2828
* This approach requires a `sprintf` implementation (`stdio.h`). The memory consumption is pretty high, but it allows an efficient way to format traces.
2929
* The solution is not Interrupt safe. (PRs are more than welcome.)
30-
* 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.
30+
* 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.
3131

3232
## Examples of traces
3333

@@ -43,7 +43,7 @@ The purpose of the library is to provide a light, simple and general tracing sol
4343
### Prerequisites
4444

4545
* Initialize the serial port so that `stdout` works. You can verify that the serial port works using the `printf()` function.
46-
* 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#L170).
46+
* 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).
4747
* To enable the tracing API:
4848
* With yotta: set `YOTTA_CFG_MBED_TRACE` to 1 or true. Setting the flag to 0 or false disables tracing.
4949
* [With mbed OS 5](#enabling-the-tracing-api-in-mbed-os-5)
@@ -78,9 +78,16 @@ Don't forget to fulfill the other [prerequisites](#prerequisites)!
7878

7979
([Click here for more information on the configuration system](https://docs.mbed.com/docs/mbed-os-api/en/latest/config_system/))
8080

81+
82+
## Examples
83+
84+
* [mbed-os-5](example/mbed-os-5)
85+
* [linux](example/linux)
86+
8187
### Traces
8288

83-
When you want to print traces, use the `tr_<level>` macros. The macros behave like `printf()`. For example, `tr_debug("hello %s", "trace")` produces the following trace line: `[DBG ][APPL] hello trace<cr><lf>`.
89+
When you want to print traces, use the `tr_<level>` macros. The macros behave like `printf()`. For example,
90+
`tr_debug("hello %s", "trace")` produces the following trace line: `[DBG ][APPL] hello trace<cr><lf>`.
8491

8592
Available levels:
8693

@@ -148,7 +155,9 @@ In Mbed OS, the build time maximum tracing level can be set through `mbed_app.js
148155

149156
### Helping functions
150157

151-
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:
158+
The purpose of the helping functions is to provide simple conversions,
159+
for example from an array to C string, so that you can print everything to single trace line.
160+
They must be called inside the actual trace calls, for example:
152161

153162
```
154163
tr_debug("My IP6 address: %s", mbed_trace_ipv6(addr));

example/linux/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
all:
2+
gcc main.c -g -I ../.. ../../source/mbed_trace.c -DYOTTA_CFG -DMBED_CONF_MBED_TRACE_FEA_IPV6=0 -o app

0 commit comments

Comments
 (0)