0
# File System Mounting
1
2
Mount local directories on MicroPython devices for seamless development workflows, enabling direct access to local files from device code without explicit file transfers.
3
4
## Capabilities
5
6
### Directory Mounting
7
8
Mount local filesystem directories to make them accessible from MicroPython device code.
9
10
```python { .api }
11
def do_mount(state, args):
12
"""
13
Mount local directory on device.
14
15
Parameters:
16
- state: State object with active transport
17
- args: Mount configuration arguments
18
19
Args attributes:
20
- path: List containing local directory path to mount
21
- unsafe_links: Boolean to follow symbolic links outside mount directory
22
23
Makes local directory contents accessible via device filesystem,
24
enabling seamless development workflows.
25
"""
26
```
27
28
### Directory Unmounting
29
30
Unmount previously mounted local directories and clean up resources.
31
32
```python { .api }
33
def do_umount(state, path):
34
"""
35
Unmount local directory.
36
37
Parameters:
38
- state: State object with active transport
39
- path: Mount path to unmount (unused, unmounts current mount)
40
41
Removes mounted directory access and cleans up transport resources.
42
"""
43
```
44
45
## Command-Line Interface
46
47
### Basic Mounting Operations
48
49
```bash
50
# Mount current directory
51
mpremote mount .
52
53
# Mount specific directory
54
mpremote mount /path/to/project
55
56
# Mount with symbolic link following
57
mpremote mount --unsafe-links /path/with/symlinks
58
59
# Mount and execute code
60
mpremote mount . exec "import my_module"
61
62
# Unmount current directory
63
mpremote umount
64
```
65
66
### Development Workflow Integration
67
68
```bash
69
# Mount project directory and run main script
70
mpremote mount . run main.py
71
72
# Mount source directory and start REPL for testing
73
mpremote mount src/ repl
74
75
# Mount library directory and install dependencies
76
mpremote mount libs/ mip install --target /mounted/libs extra-package
77
```
78
79
## Usage Examples
80
81
### Interactive Development
82
83
```python
84
from mpremote.main import State
85
from mpremote.commands import do_mount, do_umount
86
87
# Set up connected device state
88
state = State()
89
# ... connect to device ...
90
91
# Mount current directory
92
args = type('Args', (), {
93
'path': ['.'],
94
'unsafe_links': False
95
})()
96
do_mount(state, args)
97
98
# Now device can access local files directly
99
# ... do development work ...
100
101
# Unmount when done
102
do_umount(state, None)
103
```
104
105
### Project Development Workflow
106
107
```bash
108
# Project structure:
109
# project/
110
# ├── main.py
111
# ├── lib/
112
# │ ├── sensors.py
113
# │ └── networking.py
114
# ├── config/
115
# │ └── settings.py
116
# └── tests/
117
# └── test_sensors.py
118
119
# Mount project root
120
mpremote mount project/
121
122
# Device can now import modules directly:
123
mpremote exec "
124
import main
125
import lib.sensors
126
import config.settings
127
"
128
129
# Run tests
130
mpremote exec "
131
import tests.test_sensors
132
tests.test_sensors.run_all()
133
"
134
135
# Run main application
136
mpremote run main.py
137
```
138
139
### Rapid Prototyping
140
141
```bash
142
# Create and test code iteratively
143
echo "
144
def test_function():
145
return 'Hello from mounted file!'
146
147
if __name__ == '__main__':
148
print(test_function())
149
" > prototype.py
150
151
# Mount and test immediately
152
mpremote mount . exec "import prototype; print(prototype.test_function())"
153
154
# Modify file and test again without file transfer
155
echo "
156
def test_function():
157
return 'Updated function!'
158
159
def new_feature():
160
return 'New functionality added!'
161
" > prototype.py
162
163
mpremote exec "
164
# Reload module to get changes
165
import sys
166
if 'prototype' in sys.modules:
167
del sys.modules['prototype']
168
import prototype
169
print(prototype.test_function())
170
print(prototype.new_feature())
171
"
172
```
173
174
### Library Development
175
176
```bash
177
# Develop MicroPython library with live testing
178
mkdir my_sensor_lib
179
cd my_sensor_lib
180
181
cat > sensor.py << 'EOF'
182
class TemperatureSensor:
183
def __init__(self, pin):
184
from machine import ADC
185
self.adc = ADC(pin)
186
187
def read_celsius(self):
188
# Convert ADC reading to temperature
189
raw = self.adc.read()
190
voltage = raw * 3.3 / 1024
191
return (voltage - 0.5) * 100
192
EOF
193
194
cat > test_sensor.py << 'EOF'
195
from sensor import TemperatureSensor
196
197
def test_sensor():
198
# Test with mock or real hardware
199
temp = TemperatureSensor(0)
200
reading = temp.read_celsius()
201
print(f'Temperature: {reading:.1f}°C')
202
return reading
203
204
if __name__ == '__main__':
205
test_sensor()
206
EOF
207
208
# Mount library directory and test
209
mpremote mount . exec "import test_sensor; test_sensor.test_sensor()"
210
```
211
212
## Mount Behavior and Limitations
213
214
### File Access Behavior
215
216
When a directory is mounted:
217
218
- **Read Access**: Device can read all files in mounted directory
219
- **Write Access**: Device can create/modify files (changes affect local filesystem)
220
- **Import Support**: Python modules can be imported directly from mounted path
221
- **Path Resolution**: Mounted directory appears as part of device filesystem
222
223
### Symbolic Link Handling
224
225
```bash
226
# Default: symbolic links outside mount directory are not followed
227
mpremote mount /project # Safe mode
228
229
# Allow following external symbolic links (potentially unsafe)
230
mpremote mount --unsafe-links /project
231
```
232
233
Safety considerations:
234
- Default behavior prevents access outside mounted directory
235
- `--unsafe-links` allows following links that point outside mount root
236
- Use `--unsafe-links` only with trusted content
237
238
### Performance Considerations
239
240
- **Network Overhead**: Each file access requires communication with host
241
- **Caching**: mpremote may cache file contents for performance
242
- **Large Files**: Large file access may be slower than local device storage
243
- **Real-time**: Not suitable for high-frequency file operations
244
245
## Advanced Usage Patterns
246
247
### Multi-Directory Development
248
249
```bash
250
# Mount multiple directories in sequence (only one active at a time)
251
mpremote mount ./src exec "import core_module"
252
mpremote umount
253
mpremote mount ./tests exec "import test_suite; test_suite.run()"
254
mpremote umount
255
mpremote mount ./config exec "import settings; print(settings.CONFIG)"
256
```
257
258
### Configuration Management
259
260
```bash
261
# Separate code and configuration
262
mkdir project config
263
264
echo "
265
# Configuration settings
266
DEBUG = True
267
SENSOR_PIN = 4
268
WIFI_SSID = 'development'
269
" > config/settings.py
270
271
echo "
272
def load_config():
273
import settings
274
return {
275
'debug': settings.DEBUG,
276
'sensor_pin': settings.SENSOR_PIN,
277
'wifi_ssid': settings.WIFI_SSID
278
}
279
" > project/config_loader.py
280
281
# Mount config directory
282
mpremote mount config/ exec "
283
import settings
284
print('Config loaded:', settings.DEBUG, settings.SENSOR_PIN)
285
"
286
287
# Switch to project directory
288
mpremote umount
289
mpremote mount project/ exec "
290
import config_loader
291
config = config_loader.load_config()
292
print('Loaded config:', config)
293
"
294
```
295
296
### Template and Asset Management
297
298
```bash
299
# Manage web templates and static assets
300
mkdir webapp
301
mkdir webapp/templates
302
mkdir webapp/static
303
304
echo "<html><body><h1>{{title}}</h1></body></html>" > webapp/templates/index.html
305
echo "body { font-family: Arial; }" > webapp/static/style.css
306
307
# Mount and serve web content
308
mpremote mount webapp/ exec "
309
import os
310
print('Templates:', os.listdir('templates'))
311
print('Static files:', os.listdir('static'))
312
313
# Read template
314
with open('templates/index.html', 'r') as f:
315
template = f.read()
316
print('Template:', template)
317
"
318
```
319
320
## Error Handling
321
322
Mounting operations may encounter various error conditions:
323
324
```python
325
from mpremote.transport import TransportError
326
from mpremote.commands import CommandError
327
328
try:
329
do_mount(state, args)
330
except TransportError as e:
331
print(f"Mount failed: {e}")
332
# Possible causes:
333
# - Device communication error
334
# - Transport not connected
335
except OSError as e:
336
print(f"Local filesystem error: {e}")
337
# Possible causes:
338
# - Directory doesn't exist
339
# - Permission denied
340
# - Invalid path
341
```
342
343
### Common Error Scenarios
344
345
```bash
346
# Directory doesn't exist
347
mpremote mount /nonexistent/path
348
# Error: Directory not found
349
350
# Permission denied
351
mpremote mount /root/restricted
352
# Error: Permission denied
353
354
# Already mounted
355
mpremote mount .
356
mpremote mount other_dir # Will replace previous mount
357
```
358
359
## Best Practices
360
361
### Security Considerations
362
363
```bash
364
# Safe mounting - restrict to project directory
365
mpremote mount ./project
366
367
# Avoid mounting system directories
368
# DON'T: mpremote mount /
369
# DON'T: mpremote mount /home/user
370
371
# Use absolute paths for clarity
372
mpremote mount "$(pwd)/src"
373
```
374
375
### Development Workflow
376
377
```bash
378
# Organize project structure for mounting
379
project/
380
├── src/ # Main source code
381
├── lib/ # Local libraries
382
├── config/ # Configuration files
383
├── tests/ # Test files
384
└── data/ # Data files
385
386
# Mount specific directories as needed
387
mpremote mount src/ exec "import main_module"
388
mpremote mount tests/ exec "import test_runner; test_runner.run_all()"
389
```
390
391
### Performance Optimization
392
393
```bash
394
# Minimize file operations during mount
395
# Good: Load configuration once
396
mpremote mount config/ exec "
397
import settings
398
CONFIG = settings.get_config()
399
"
400
401
# Avoid: Repeated file access
402
# Suboptimal: mpremote exec "import settings; print(settings.DEBUG)"
403
```