- Contains the host code with a protocol implementation, data analyser and web-based visualiser
350 lines
8.4 KiB
Markdown
350 lines
8.4 KiB
Markdown
# Getting Started with MiniProfiler
|
|
|
|
This guide will help you get started with MiniProfiler for profiling your embedded STM32 applications.
|
|
|
|
## Prerequisites
|
|
|
|
### Host System
|
|
- Python 3.8 or higher
|
|
- pip package manager
|
|
- Modern web browser (Chrome, Firefox, Edge)
|
|
- Serial port access (USB-to-Serial adapter or built-in UART)
|
|
|
|
### Embedded Target (for Phase 2)
|
|
- STM32 microcontroller (STM32F4/F7/H7 recommended)
|
|
- GCC ARM toolchain
|
|
- UART or USB-CDC peripheral configured
|
|
- ST-Link or similar programmer/debugger
|
|
|
|
## Installation
|
|
|
|
### 1. Clone the Repository
|
|
|
|
```bash
|
|
git clone https://github.com/yourusername/miniprofiler.git
|
|
cd miniprofiler
|
|
```
|
|
|
|
### 2. Install Python Dependencies
|
|
|
|
```bash
|
|
cd host
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
Or install as a package:
|
|
|
|
```bash
|
|
pip install -e .
|
|
```
|
|
|
|
### 3. Verify Installation
|
|
|
|
```bash
|
|
miniprofiler --help
|
|
```
|
|
|
|
You should see the help message with available options.
|
|
|
|
## Testing Without Hardware
|
|
|
|
Before connecting to real hardware, you can test the visualization with sample data.
|
|
|
|
### Generate Sample Data
|
|
|
|
```bash
|
|
cd host/tests
|
|
python sample_data_generator.py
|
|
```
|
|
|
|
This creates several sample data files:
|
|
- `sample_flamegraph.json` - Flame graph visualization data
|
|
- `sample_statistics.json` - Function statistics
|
|
- `sample_timeline.json` - Timeline data
|
|
- `sample_profile_data.bin` - Binary protocol data
|
|
|
|
### View Sample Visualizations
|
|
|
|
You can view the sample JSON files by loading them in the web interface or by opening them directly:
|
|
|
|
```bash
|
|
# View flame graph data
|
|
cat sample_flamegraph.json | python -m json.tool
|
|
|
|
# View statistics
|
|
cat sample_statistics.json | python -m json.tool
|
|
```
|
|
|
|
## Running the Host Application
|
|
|
|
### Start the Web Server
|
|
|
|
```bash
|
|
# From the host directory
|
|
python run.py
|
|
|
|
# Or using the installed CLI
|
|
miniprofiler
|
|
```
|
|
|
|
The server will start on `http://localhost:5000` by default.
|
|
|
|
### Custom Host/Port
|
|
|
|
```bash
|
|
miniprofiler --host 0.0.0.0 --port 8080
|
|
```
|
|
|
|
### Enable Debug Mode
|
|
|
|
```bash
|
|
miniprofiler --debug --verbose
|
|
```
|
|
|
|
## Using the Web Interface
|
|
|
|
### 1. Open the Browser
|
|
|
|
Navigate to `http://localhost:5000`
|
|
|
|
You should see the MiniProfiler dashboard with:
|
|
- Connection controls
|
|
- Profiling controls (disabled until connected)
|
|
- Status display
|
|
- Three visualization tabs
|
|
|
|
### 2. Configure Connection
|
|
|
|
Enter your serial port details:
|
|
- **Serial Port**: `/dev/ttyUSB0` (Linux/Mac) or `COM3` (Windows)
|
|
- **Baud Rate**: `115200` (default)
|
|
- **ELF Path**: Path to your `.elf` file (optional, for symbol resolution)
|
|
|
|
**Finding Your Serial Port:**
|
|
|
|
Linux/Mac:
|
|
```bash
|
|
ls /dev/tty* | grep -i usb
|
|
# or
|
|
ls /dev/tty.usb*
|
|
```
|
|
|
|
Windows:
|
|
- Open Device Manager
|
|
- Look under "Ports (COM & LPT)"
|
|
- Note the COM port number (e.g., COM3)
|
|
|
|
### 3. Connect to Device
|
|
|
|
Click the **Connect** button.
|
|
|
|
If successful, you'll see:
|
|
- Status indicator turns green
|
|
- "Connected to /dev/ttyUSB0" message
|
|
- Metadata panel appears with device information
|
|
- Profiling controls become enabled
|
|
|
|
### 4. Start Profiling
|
|
|
|
Click **Start Profiling**.
|
|
|
|
The device will begin sending profiling data, and you'll see:
|
|
- Real-time updates in all three visualization tabs
|
|
- Record count incrementing
|
|
- Summary statistics updating
|
|
|
|
### 5. Explore Visualizations
|
|
|
|
#### Flame Graph Tab
|
|
- Shows aggregate CPU time by function
|
|
- Wider bars = more time spent
|
|
- Click to zoom into specific call stacks
|
|
- Search for functions by name
|
|
- Hover for details
|
|
|
|
#### Timeline Tab
|
|
- Shows function execution over time
|
|
- X-axis = time in microseconds
|
|
- Y-axis = call stack depth
|
|
- Color = duration (darker = longer)
|
|
- Useful for finding timing issues
|
|
|
|
#### Statistics Tab
|
|
- Sortable table of function statistics
|
|
- Columns: Function, Address, Calls, Total/Avg/Min/Max Time
|
|
- Click column headers to sort
|
|
- Find hot spots and outliers
|
|
|
|
### 6. Control Profiling
|
|
|
|
- **Stop Profiling**: Pause data collection
|
|
- **Clear Data**: Reset all visualizations
|
|
- **Reset Buffers**: Clear device-side buffers
|
|
|
|
### 7. Disconnect
|
|
|
|
Click **Disconnect** when done to close the serial connection.
|
|
|
|
## Understanding the Visualizations
|
|
|
|
### Flame Graph
|
|
|
|
The flame graph shows **aggregated** profiling data:
|
|
|
|
```
|
|
┌─────────────────────────────────┐
|
|
│ main (10s) │ ← Root function
|
|
├──────────────┬──────────────────┤
|
|
│ app_loop │ process_data │ ← Called by main
|
|
│ (6s) │ (4s) │
|
|
├──────┬───────┼──────────────────┤
|
|
│ read │ write │ calculate │ ← Nested calls
|
|
│ (3s) │ (3s) │ (4s) │
|
|
└──────┴───────┴──────────────────┘
|
|
```
|
|
|
|
**Interpretation:**
|
|
- Width = total time (including children)
|
|
- Read from bottom (root) to top (leaves)
|
|
- Widest bars are hotspots to optimize
|
|
|
|
### Timeline
|
|
|
|
The timeline shows **chronological** execution:
|
|
|
|
```
|
|
Time ───────────────────────►
|
|
│ ████ func_a
|
|
│ ██ func_b (called by func_a)
|
|
│ ████ func_c
|
|
│ ██ func_d
|
|
```
|
|
|
|
**Interpretation:**
|
|
- X-axis = time progression
|
|
- Y-axis = call depth
|
|
- Gaps = idle time or excluded functions
|
|
- Useful for timing analysis and debugging
|
|
|
|
### Statistics Table
|
|
|
|
| Function | Calls | Total Time | Avg Time |
|
|
|----------|-------|------------|----------|
|
|
| main | 1 | 10000 μs | 10000 μs |
|
|
| app_loop | 100 | 6000 μs | 60 μs |
|
|
| calculate | 100 | 4000 μs | 40 μs |
|
|
|
|
**Interpretation:**
|
|
- Calls = number of times function was called
|
|
- Total = cumulative time across all calls
|
|
- Avg = total / calls
|
|
- Min/Max = shortest/longest single execution
|
|
|
|
## Troubleshooting
|
|
|
|
### "Failed to connect to /dev/ttyUSB0"
|
|
|
|
**Possible causes:**
|
|
- Wrong port name
|
|
- Port in use by another application
|
|
- Insufficient permissions
|
|
|
|
**Solutions:**
|
|
```bash
|
|
# Linux: Check permissions
|
|
ls -l /dev/ttyUSB0
|
|
sudo chmod 666 /dev/ttyUSB0
|
|
|
|
# Or add user to dialout group
|
|
sudo usermod -a -G dialout $USER
|
|
# Log out and back in
|
|
|
|
# Check if port is in use
|
|
lsof | grep ttyUSB0
|
|
```
|
|
|
|
### No Data Appearing
|
|
|
|
**Check:**
|
|
1. Is profiling started? (Click "Start Profiling")
|
|
2. Is embedded device actually profiling?
|
|
3. Is UART configured correctly on embedded side?
|
|
4. Check baud rate matches on both sides
|
|
5. Look for errors in browser console (F12)
|
|
|
|
### CRC Errors in Console
|
|
|
|
**Possible causes:**
|
|
- Baud rate mismatch
|
|
- Electrical noise on UART lines
|
|
- Cable issues
|
|
|
|
**Solutions:**
|
|
- Verify baud rate configuration
|
|
- Use shielded cable
|
|
- Add delays in embedded UART transmission
|
|
- Reduce baud rate to 57600
|
|
|
|
### Buffer Overflows
|
|
|
|
**Symptoms:**
|
|
- `buffer_overflows` counter > 0 in device status
|
|
- Missing profiling data
|
|
|
|
**Solutions:**
|
|
- Increase baud rate (460800 or 921600)
|
|
- Increase embedded ring buffer size
|
|
- Reduce instrumentation (exclude more files)
|
|
- Use sampling mode (future feature)
|
|
|
|
### Symbols Not Resolved
|
|
|
|
**Symptoms:**
|
|
- Function names show as `func_0x08000XXX` or `unknown_0x08000XXX`
|
|
|
|
**Solutions:**
|
|
- Provide path to `.elf` file in connection settings
|
|
- Ensure `.elf` file has debug symbols (`-g` flag)
|
|
- Verify `.elf` file matches firmware on device
|
|
- Check build ID in metadata matches
|
|
|
|
### Web Interface Not Loading
|
|
|
|
**Check:**
|
|
1. Is server running? Look for "Starting web server..." message
|
|
2. Correct URL? Should be `http://localhost:5000`
|
|
3. Port already in use? Try different port: `miniprofiler --port 8080`
|
|
4. Firewall blocking? Add exception for Python/Flask
|
|
|
|
## Next Steps
|
|
|
|
### For Development
|
|
1. Read [PROTOCOL.md](PROTOCOL.md) to understand the communication protocol
|
|
2. Review the code in `host/miniprofiler/` to customize behavior
|
|
3. Modify visualizations in `host/web/`
|
|
|
|
### For Embedded Integration
|
|
1. Wait for Phase 2 implementation of embedded module
|
|
2. Or start implementing based on protocol specification
|
|
3. See examples in `embedded/` directory (coming soon)
|
|
|
|
### For Testing
|
|
1. Create custom sample data with `sample_data_generator.py`
|
|
2. Test with Renode emulation (Phase 4)
|
|
3. Benchmark overhead on real hardware
|
|
|
|
## Support
|
|
|
|
- **Documentation**: See `docs/` directory
|
|
- **Issues**: Open an issue on GitHub
|
|
- **Examples**: Check `examples/` directory (coming soon)
|
|
|
|
## What's Next?
|
|
|
|
After getting familiar with the host application:
|
|
1. **Phase 2**: Implement embedded module for STM32
|
|
2. **Phase 3**: Test on real hardware
|
|
3. **Phase 4**: Set up Renode emulation for automated testing
|
|
|
|
Stay tuned for updates!
|