316 lines
6.7 KiB
Markdown
316 lines
6.7 KiB
Markdown
|
||
# Programming Language Recommendation
|
||
## ASF Sensor Hub – Software Architecture
|
||
|
||
---
|
||
|
||
## 1. Overview
|
||
|
||
This document defines the recommended programming language strategy for the ASF Sensor Hub software platform, based on industrial reliability, real-time constraints, and ESP32-S3 / ESP-IDF v5.4 capabilities.
|
||
|
||
The proposed approach is a **hybrid C++ / C model**, where:
|
||
- **C++** is the primary language for application, services, and component logic.
|
||
- **C** is retained for low-level, hardware-near, and performance-critical sections.
|
||
|
||
---
|
||
|
||
## 2. Primary Language Recommendation
|
||
|
||
### Primary Language
|
||
**C++ (C++17 / C++20)**
|
||
|
||
### Rationale
|
||
|
||
#### 2.1 ESP-IDF Native Support
|
||
- ESP-IDF v5.4 provides mature C++ support
|
||
- Proper support for:
|
||
- RTTI
|
||
- Exceptions (configurable)
|
||
- Static linking
|
||
- FreeRTOS integration
|
||
- Seamless interoperability with ESP-IDF C APIs
|
||
|
||
#### 2.2 Alignment with Industrial Requirements
|
||
|
||
| Requirement | C++ Capability |
|
||
|---------------------------|----------------|
|
||
| Deterministic behavior | Explicit memory control, no hidden runtime |
|
||
| Real-time performance | Zero-cost abstractions |
|
||
| Resource constraints | RAII, scoped lifetimes |
|
||
| Reliability | Strong type system, compile-time checks |
|
||
| Maintainability | Modular, component-oriented design |
|
||
|
||
---
|
||
|
||
## 3. Architectural Benefits of C++
|
||
|
||
### 3.1 Component-Based Architecture
|
||
- Natural mapping of components to C++ classes
|
||
- Clear ownership boundaries
|
||
- Explicit interfaces using abstract base classes
|
||
|
||
### 3.2 Event-Driven Design
|
||
- Strong support for:
|
||
- Callbacks
|
||
- Observer pattern
|
||
- State machines
|
||
- Clean separation between event producers and consumers
|
||
|
||
### 3.3 Abstraction Layers
|
||
- Interface-based design
|
||
- Inheritance and composition
|
||
- Clear separation between:
|
||
- Application layer
|
||
- Services
|
||
- Drivers
|
||
|
||
### 3.4 Template System
|
||
- Type-safe generic programming
|
||
- Reusable drivers and protocol handlers
|
||
- Compile-time validation for configurations
|
||
|
||
---
|
||
|
||
## 4. Secondary Language Recommendation
|
||
|
||
### Secondary Language
|
||
**C (ISO C11 / C17)**
|
||
|
||
### Intended Usage Areas
|
||
- Hardware Abstraction Layer (HAL)
|
||
- Interrupt Service Routines (ISRs)
|
||
- ESP-IDF framework integration points
|
||
- Performance-critical or timing-sensitive drivers
|
||
|
||
C remains the most appropriate language for areas requiring:
|
||
- Absolute minimal overhead
|
||
- Direct register access
|
||
- Compatibility with ESP-IDF internal APIs
|
||
|
||
---
|
||
|
||
## 5. Language Configuration Recommendations
|
||
|
||
### ESP-IDF C++ Configuration (`sdkconfig`)
|
||
|
||
```ini
|
||
CONFIG_COMPILER_CXX_EXCEPTIONS=y
|
||
CONFIG_COMPILER_CXX_RTTI=y
|
||
CONFIG_COMPILER_STACK_CHECK_MODE_STRONG=y
|
||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||
````
|
||
|
||
**Notes:**
|
||
|
||
* Exceptions are allowed but must be used in a controlled manner
|
||
* Stack checking is mandatory for industrial reliability
|
||
* Size optimization is preferred over aggressive speed optimization
|
||
|
||
---
|
||
|
||
## 6. Architecture-Specific Language Usage
|
||
|
||
### 6.1 Application Layer (C++)
|
||
|
||
#### Component Interfaces
|
||
|
||
```cpp
|
||
class ISensorManager {
|
||
public:
|
||
virtual ~ISensorManager() = default;
|
||
virtual SensorResult readSensor(SensorId id) = 0;
|
||
virtual void registerCallback(SensorCallback callback) = 0;
|
||
};
|
||
```
|
||
|
||
#### State Machine Example
|
||
|
||
```cpp
|
||
class SystemStateMachine {
|
||
public:
|
||
enum class State { INIT, OPERATIONAL, FAULT, MAINTENANCE };
|
||
|
||
void handleEvent(const SystemEvent& event);
|
||
State getCurrentState() const noexcept;
|
||
|
||
private:
|
||
State currentState_;
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
### 6.2 Driver Layer (C with C++ Wrappers)
|
||
|
||
#### Low-Level C Driver
|
||
|
||
```c
|
||
esp_err_t sensor_driver_init(sensor_config_t* config);
|
||
esp_err_t sensor_driver_read(uint8_t* data, size_t len);
|
||
```
|
||
|
||
#### C++ Wrapper
|
||
|
||
```cpp
|
||
class SensorDriver {
|
||
public:
|
||
explicit SensorDriver(const SensorConfig& cfg);
|
||
std::expected<SensorData, SensorError> read();
|
||
|
||
private:
|
||
sensor_config_t config_;
|
||
};
|
||
```
|
||
|
||
This approach preserves:
|
||
|
||
* Low-level efficiency
|
||
* High-level safety and usability
|
||
|
||
---
|
||
|
||
## 7. Key Language Features for Industrial Requirements
|
||
|
||
### 7.1 Memory Safety (RAII)
|
||
|
||
```cpp
|
||
class I2CTransaction {
|
||
public:
|
||
explicit I2CTransaction(i2c_port_t port) : port_(port) {
|
||
i2c_master_start(port_);
|
||
}
|
||
|
||
~I2CTransaction() {
|
||
i2c_master_stop(port_);
|
||
}
|
||
|
||
private:
|
||
i2c_port_t port_;
|
||
};
|
||
```
|
||
|
||
Ensures:
|
||
|
||
* No resource leaks
|
||
* Deterministic cleanup
|
||
* Exception-safe behavior
|
||
|
||
---
|
||
|
||
### 7.2 Error Handling
|
||
|
||
```cpp
|
||
Result<SensorData, SensorError> readTemperature() {
|
||
if (auto result = validateSensor(); !result) {
|
||
return Error{SensorError::NOT_READY};
|
||
}
|
||
return SensorData{temperature_value};
|
||
}
|
||
```
|
||
|
||
Advantages:
|
||
|
||
* Explicit error paths
|
||
* No hidden failure states
|
||
* Testable behavior
|
||
|
||
---
|
||
|
||
### 7.3 Type Safety
|
||
|
||
```cpp
|
||
enum class GpioPin : uint8_t {
|
||
SENSOR_ENABLE = 12,
|
||
LED_STATUS = 13
|
||
};
|
||
|
||
enum class I2CAddress : uint8_t {
|
||
TEMP_SENSOR = 0x48,
|
||
HUMIDITY = 0x40
|
||
};
|
||
|
||
void configureGpio(GpioPin pin, GpioMode mode);
|
||
```
|
||
|
||
Prevents:
|
||
|
||
* Pin/address mix-ups
|
||
* Invalid parameter usage
|
||
* Entire classes of runtime errors
|
||
|
||
---
|
||
|
||
## 8. Advantages for ASF Sensor Hub
|
||
|
||
| Aspect | Benefit |
|
||
| --------------- | ---------------------------------------- |
|
||
| Maintainability | Modular, readable architecture |
|
||
| Testability | Interfaces and dependency injection |
|
||
| Scalability | Generic programming for sensor expansion |
|
||
| Safety | Strong typing and RAII |
|
||
| Performance | Zero-cost abstractions |
|
||
| Integration | Seamless ESP-IDF C API usage |
|
||
|
||
---
|
||
|
||
## 9. Alternative Considerations
|
||
|
||
### 9.1 Rust (Rejected)
|
||
|
||
* ESP-IDF ecosystem still immature
|
||
* Steeper learning curve
|
||
* Limited adoption in industrial agricultural systems
|
||
|
||
### 9.2 Pure C (Rejected)
|
||
|
||
* Lacks modern abstraction mechanisms
|
||
* More error-prone for large systems
|
||
* Difficult to maintain complex state machines
|
||
|
||
---
|
||
|
||
## 10. Implementation Strategy
|
||
|
||
### Phase 1 – Core Foundation
|
||
|
||
* Core system services in C++
|
||
* Drivers and HAL in C
|
||
|
||
### Phase 2 – Optimization
|
||
|
||
* Migrate selected C modules to C++ where beneficial
|
||
* Improve type safety and testability
|
||
|
||
### Phase 3 – Advanced Features
|
||
|
||
* Introduce modern C++ features where appropriate:
|
||
|
||
* C++20 concepts
|
||
* Advanced compile-time validation
|
||
|
||
---
|
||
|
||
## 11. Conclusion
|
||
|
||
The hybrid **C++ / C approach** provides the optimal balance between:
|
||
|
||
* **Industrial reliability** (deterministic, real-time)
|
||
* **Modern software engineering** (maintainable, testable)
|
||
* **ESP32 optimization** (hardware-aware, efficient)
|
||
* **Team productivity** (clear, expressive design)
|
||
|
||
This language strategy directly supports the ASF architecture principles:
|
||
|
||
* Event-driven execution
|
||
* Component-based design
|
||
* State-aware behavior
|
||
* Deterministic and safe operation
|
||
|
||
---
|
||
|
||
```
|
||
|
||
---
|
||
|
||
```
|