NASA P10 Rules Adapted to MicroPython for PicoCore
This page adapts the NASA P10 coding rules to MicroPython development for PicoCore V2, explaining how to write reliable, efficient, and maintainable embedded Python code.
Overview
NASA's P10 rules are designed for safety-critical systems to prevent unexpected runtime behavior and ensure deterministic execution. We adapt these rules for MicroPython and PicoCore projects, keeping in mind resource constraints.
Rule Mapping to MicroPython
1. Avoid complex flow constructs (goto, recursion)
Python does not have goto
. Recursion is allowed but should be avoided in embedded projects due to limited stack.
# ❌ Avoid deep recursion
# def factorial(n):
# return n * factorial(n-1)
# ✅ Use iteration instead
def factorial(n):
result = 1
for i in range(1, n+1):
result *= i
return result
💡 Tip: Use loops and simple function calls. Avoid call stacks that grow unpredictably.
2. Loops must have fixed bounds
# ✅ Fixed bound loop
for i in range(10):
print(i)
# ❌ While with uncertain exit
while sensor.read() != target:
time.sleep(0.1)
💡 Tip: Use timeouts or fixed iterations instead of potentially infinite loops.
3. Avoid heap memory allocation after initialization
In MicroPython, creating new objects dynamically may allocate on the heap. Prefer preallocated buffers.
# ✅ Preallocate list
data = [0]*100
# ❌ Appending dynamically in a loop
for i in range(100):
data.append(i)
💡 Tip: Use fixed-size data structures. This improves determinism and reduces fragmentation.
4. Restrict functions to a single printed page
Keep functions small and focused.
# ✅ Small, clear functions
def read_temperature():
return sensor.read_temp()
def control_fan():
temp = read_temperature()
if temp > 30:
fan.on()
else:
fan.off()
💡 Tip: This improves readability and maintainability.
5. Use runtime assertions
Assertions help during development but halt execution in MicroPython, which may not be desirable for embedded runtime.
# ✅ Development-only assertions
if __debug__:
assert 0 <= temp <= 50, "Temperature out of range"
# ✅ Runtime checks with handler
if temp < 0 or temp > 50:
handle_error(temp)
💡 Tip: Prefer
if
statements with error handling for production code to maintain deterministic behavior.
6. Restrict the scope of data
# ✅ Local variables
def compute():
temp = sensor.read()
return temp
# ❌ Global variable abuse
temp = 0
💡 Tip: Reduce side effects and keep memory usage predictable.
7. Check return values
# ✅ Check return values
status = motor.start()
if not status:
handle_error("Motor failed")
# ❌ Ignore return
motor.start()
💡 Tip: Explicitly handle all return values to ensure reliability.
8. Use preprocessor only for headers/macros
Not applicable in MicroPython. Instead, keep configuration in constants or .toml
files.
9. Limit pointer usage
Python abstracts pointers. Avoid complex references or closures that create memory indirections.
💡 Tip: Avoid function pointers or dynamic callables for deterministic embedded behavior.
10. Compile with warnings
In MicroPython, use linters like pylint or mypy to detect issues.
💡 Tip: Treat linter warnings as errors in critical embedded code.
Additional Guidelines for MicroPython Embedded Projects
- Assertions: Use for development only, avoid blocking production runtime.
- Try/Except: Avoid heavy exception handling in loops; it is costly. Use pre-checks and validation before execution.
- Deterministic Execution: Precompute values, preallocate memory, avoid dynamic object creation in loops.
- Logging: Minimize logging in real-time loops; buffer or batch writes.
Example: Sensor Polling Loop (Deterministic & Safe)
# Fixed iterations, preallocated buffer, safe checks
readings = [0]*60 # store 60 samples
for i in range(60):
temp = sensor.read()
if 0 <= temp <= 50:
readings[i] = temp
else:
readings[i] = None # handle invalid data
time.sleep(5) # 5s interval, fixed
✅ Combines multiple P10 principles: fixed loops, preallocated memory, and runtime checks.
References
- Nasa Fprime : Fprime Coding Standard
- NASA P10 Coding Standard: NASA Technical Standard
- MicroPython Documentation: https://docs.micropython.org/