Skip to content

Commit 77c021f

Browse files
committed
Add useful memory stats library
1 parent f0de577 commit 77c021f

14 files changed

+3917
-0
lines changed

libraries/mbed-memory-status/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Max Vilimpoc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# mbed-memory-status
2+
3+
## Purpose
4+
5+
Print thread stack, ISR stack, and global heap locations, sizes, and utilization at runtime when using mbed OS. Useful for tracking down total runtime memory usage and stack overflows.
6+
7+
It will print debug information to the serial port, or use SEGGER Real Time Transfer (RTT), or use the Serial Wire Output (SWO) capabilities in supported ARM Cortex chips.
8+
9+
Does *not* use printf(). It *will* automatically initialize the default serial port to 115200 8N1 using the low-level mbed `serial_api.h` if no other instantiation has occurred.
10+
11+
The code has now been fixed to detect whether it is running on the CMSIS-RTOS 1 or CMSIS-RTOS 2 API and will adjust its low-level API calls accordingly.
12+
13+
## Example
14+
15+
```c
16+
#include "mbed_memory_status.h"
17+
18+
int main()
19+
{
20+
print_all_thread_info();
21+
print_heap_and_isr_stack_info();
22+
}
23+
```
24+
25+
## Building
26+
27+
When building the code, make sure to pass the `MBED_STACK_STATS_ENABLED` compiler macro as follows, otherwise mbed will eliminate the stack canary code:
28+
29+
```
30+
mbed compile -D MBED_STACK_STATS_ENABLED=1
31+
```
32+
33+
This value can also be added permanently to the `mbed_app.json` macros.
34+
35+
## Output
36+
37+
Using ARM RTX RTOS on up to mbed 5.4.7, this will print something like:
38+
39+
```
40+
stack ( start: 20005100 end: 20005420 size: 00000320 used: 00000070 ) thread ( id: 2000542C entry: 00020D91 )
41+
stack ( start: 20003D1C end: 2000451C size: 00000800 used: 00000254 ) thread ( id: 2000546C entry: 000201E1 )
42+
stack ( start: 20004E58 end: 20005058 size: 00000200 used: 00000050 ) thread ( id: 20005644 entry: 0002022D )
43+
heap ( start: 200056E8 end: 20007800 size: 00002118 used: 00000398 ) alloc ( ok: 00000006 fail: 00000000 )
44+
isr_stack ( start: 20007800 end: 20008000 size: 00000800 used: 000002B0 )
45+
```
46+
47+
Using CMSIS-RTOS 2 from mbed 5.5 and higher, we gain access to thread names, so this will print something like:
48+
49+
```
50+
stack ( start: 20004628 end: 20005628 size: 00001000 used: 000000F8 ) thread ( id: 200045D8 entry: 0001CEBD name: main_thread )
51+
stack ( start: 200040A0 end: 200042A0 size: 00000200 used: 00000100 ) thread ( id: 20003D58 entry: 0001D019 name: unknown )
52+
stack ( start: 20003DA0 end: 200040A0 size: 00000300 used: 00000068 ) thread ( id: 20003D10 entry: 0001F1BD name: unknown )
53+
heap ( start: 20005738 end: 2000FC00 size: 0000A4C8 used: 00000000 ) alloc ( ok: 00000000 fail: 00000000 )
54+
isr_stack ( start: 2000FC00 end: 20010000 size: 00000400 )
55+
```
56+
57+
## Use
58+
59+
Add to your program:
60+
61+
```
62+
mbed add https://github.com/nuket/mbed-memory-status.git mbed-memory-status
63+
```
64+
65+
To enable the ISR stack usage tracking, the following assembly code needs to be added to your chip's specific `startup_[your chip].S` file:
66+
67+
```asm
68+
#if DEBUG_ISR_STACK_USAGE
69+
LDR R0, =fill_isr_stack_with_canary
70+
BLX R0
71+
#endif
72+
```
73+
74+
See the `startup_example.S.txt` file for what this looks like (the file is a modified copy of `startup_NRF51822.S`).
75+
76+
Then define this in `mbed_memory_status.c`, or via the `mbed_app.json` macros, or via the command line:
77+
78+
```c
79+
#define DEBUG_ISR_STACK_USAGE 1
80+
```
81+
82+
## Outputs
83+
84+
With `#define OUTPUT_SERIAL 1`:
85+
86+
![Serial Output](output-uart.png)
87+
88+
With `#define OUTPUT_RTT 1`:
89+
90+
![SEGGER Real Time Transfer Output](output-rtt.png)
91+
92+
With `#define OUTPUT_SWO 1` (and `-D ENABLE_SWO` on an nRF52 Development Kit):
93+
94+
![Serial Wire Output](output-swo.png)
95+
96+
And, having all of them active together works too!
97+
98+
![All At Once](output-simultaneous.png)
99+
100+
## Supports
101+
102+
[mbed OS](https://github.com/ARMmbed/mbed-os/) 5.2.0 - 5.9.5 (and up to [b53a9ea](https://github.com/ARMmbed/mbed-os/commit/b53a9ea4c02fd67cb0cc94d08361e8815585b7bf))
103+
104+
## Gotchas
105+
106+
On mbed 5.5 and up, there may be a Heisenbug when calling print_thread_info() inside of osKernelLock()!
107+
108+
This error sometimes appears on the serial console shortly after chip startup, but not always:
109+
`mbed assertation failed: os_timer->get_tick() == svcRtxKernelGetTickCount(), file: .\mbed-os\rtos\TARGET_CORTEX\mbed_rtx_idle.c`
110+
111+
The RTOS seems to be asserting an idle constraint violation due to the slowness of sending data through the serial port, but it does not happen consistently.
112+
113+
Resetting or power-cycling the chip may solve this problem.
114+
115+
## Why This Exists
116+
117+
This code exists because of a stupid amount of bug-hunting:
118+
119+
> https://vilimpoc.org/blog/2017/02/01/stack-heap-and-thread-crash-hunting-in-mbed-os/
120+
> https://vilimpoc.org/blog/2017/02/04/isr-stack-usage-on-mbed/

0 commit comments

Comments
 (0)