In embedded system development, the visualization and documentation of software architecture are often overlooked, leading to difficulties in project maintenance and chaotic team collaboration. The C4 model created by Simon Brown (Context, Containers, Components, Code) clearly presents software architecture in a layered and progressive manner, making it particularly suitable for resource-constrained and increasingly complex embedded systems.
Core Concepts and Architectural Philosophy
What is the C4 Model
The C4 model is a layered graphical technique for visualizing software architecture, developed based on UML and the 4+1 architectural view model. It describes software systems from different perspectives through four abstraction levels:
The Four Levels of the C4 Model:
- • Context: The relationship between the system and the external world
- • Containers: The main technical building blocks of the system
- • Components: Logical groupings within containers
- • Code: Specific implementation details
Design Philosophy of the C4 Model
Progressive Refinement Principle
The C4 model adopts the concept of “scaling,” gradually delving from the macro system context to the micro code implementation, with each layer providing an appropriate level of detail for specific audiences.
Simplicity First
Compared to complex UML diagrams, the C4 model uses simple boxes, lines, and labels, lowering the barrier to understanding and improving communication efficiency.
Multi-Dimensional Perspective
Different stakeholders can choose the appropriate abstraction level as needed; technical personnel can dive into the component level, while management may only need to understand the system context.
The Four-Layer Architecture of the C4 Model
System Context Diagram
The system context diagram shows the relationship between the target system and its users and external systems, providing all stakeholders with a “big picture” of the system.
<<person>> User family members, using a mobile app to control home devices <<person>> System administrator responsible for system maintenance and configuration <<system>> Smart home control system embedded system for centralized control and monitoring of home devices <<external_system>> Cloud service platform providing remote control and data analysis services <<external_system>> Mobile app user control interface <<external_system>> Sensor network temperature, humidity, light, and other sensors <<external_system>> Home appliances air conditioning, lighting, security devices, etc. using configuration and maintenance control commands [WiFi/Bluetooth] data synchronization [HTTPS] data collection [Zigbee/LoRa] device control [Infrared/RF/WiFi] smart home control system context diagram
Key Elements in Embedded Systems:
- 1. Physical Interaction Boundaries: Clearly define the interfaces between the system and the physical world
- 2. Communication Protocol Identification: Label various communication protocols (SPI, I2C, UART, etc.)
- 3. Power Consumption Considerations: Identify high and low power interaction paths
- 4. Security Boundaries: Identify data flows that are sensitive to security
Container Diagram
The container diagram shows the high-level technical choices of the system and the relationships between the main structural blocks. In embedded systems, containers typically correspond to different processing units, software modules, or hardware components.
<<person>> User <<container>> Main control MCU [STM32F7] running main control logic and protocol stack <<container>> Communication module [ESP32] WiFi/Bluetooth communication processing <<container>> Sensor hub [STM32L4] low-power sensor data collection <<container>> Local storage [SPI Flash] configuration data and log storage embedded controller [CONTAINER] <<container>> Mobile app [React Native] <<container>> Cloud backend [Node.js + MongoDB] <<container>> Sensor network [Zigbee] <<container>> Device network [smart plugs, switches, etc.] external system [CONTAINER] operation control commands [WiFi] command forwarding [UART] sensor queries [I2C] data storage [SPI] device control [Zigbee] data synchronization [HTTPS] data collection [Zigbee] smart home control system container diagram
Key Design Points for Embedded System Containers:
- 1. Separation of Processing Units: Separate different processing units based on functional and performance requirements
- 2. Clear Communication Interfaces: Clearly label hardware interface types and protocols
- 3. Power Consumption Optimization: Concentrate low-power functions into dedicated containers
- 4. Real-Time Guarantees: Ensure real-time tasks have dedicated processing containers
Component Diagram
The component diagram delves into the container, showcasing the main software components and their responsibilities. This layer is crucial for the development team to understand the internal structure of the system.
<<external_container>> Communication module <<external_container>> Sensor hub <<external_container>> Local storage <<external_container>> Device network <<component>> Application layer [business logic processing] <<component>> Protocol stack [Zigbee/LoRa protocol implementation] <<component>> Device manager [device registration, status management] <<component>> Data processor [sensor data processing and algorithms] <<component>> Security module [encryption/decryption, identity authentication] <<component>> Power management [power consumption control and power state management] <<component>> Hardware abstraction layer [HAL] <<component>> RTOS kernel [FreeRTOS] <<component>> Driver layer [peripheral drivers] Main control MCU (STM32F7) [CONTAINER] Device operation data processing requests security verification protocol communication hardware operation ADC/DMA operation power control hardware abstraction system call command reception sensor data configuration storage device communication main control MCU component diagram
Embedded Component Design Principles:
- 1. Hierarchical Architecture: Follow layered architecture principles to avoid direct calls across layers
- 2. Modular Design: Each component has a single responsibility and clear interfaces
- 3. Real-Time Considerations: Distinguish between real-time and non-real-time components
- 4. Resource Isolation: Resource usage of critical components should have clear boundaries
Code Diagram
The code diagram displays specific classes, interfaces, and their relationships. In embedded systems, this layer typically uses UML class diagrams or function call diagrams.
manages
uses
communicates
DeviceManager
-vector<Device*> devices
-map<string, DeviceType> deviceTypes
+registerDevice(Device* device) : bool
+removeDevice(uint32_t deviceId) : bool
+getDevice(uint32_t deviceId) : Device
+getAllDevices() : vector<Device*>
+updateDeviceStatus(uint32_t deviceId, Status status)
«abstract»
Device
#uint32_t deviceId
#string deviceName
#DeviceType type
#Status currentStatus
+getId() : uint32_t
+getName() : string
+getType() : DeviceType
+getStatus() : Status
+execute(Command cmd) : bool
+getCapabilities() : Capabilities
SmartSwitch
-bool isOn
-uint32_t brightness
+execute(Command cmd) : bool
+getCapabilities() : Capabilities
+turnOn() : bool
+turnOff() : bool
+setBrightness(uint32_t level) : bool
TemperatureSensor
-float temperature
-float humidity
-uint32_t sampleRate
+execute(Command cmd) : bool
+getCapabilities() : Capabilities
+readTemperature() : float
+readHumidity() : float
+setSampleRate(uint32_t rate) : bool
ProtocolStack
-uint8_t networkId
-vector<uint32_t> connectedDevices
+initNetwork() : bool
+sendCommand(uint32_t deviceId, Command cmd) : bool
+receiveData() : PacketData
+handleNetworkEvent(NetworkEvent event)
C4 Modeling Toolchain and Practice Process
Recommended Toolchain
Graphical Tools
- 1. Draw.io/Diagrams.net: Free online drawing tool that supports C4 templates
- 2. Lucidchart: Professional diagram tool with strong team collaboration features
- 3. Miro/Mural: Whiteboard tools suitable for remote team collaboration
Code-Based Tools
- 1. PlantUML + C4-PlantUML: Text description generates diagrams, version control friendly
- 2. Structurizr: Professional C4 modeling tool developed by Simon Brown
- 3. Mermaid: Lightweight diagram generation tool, natively supported by GitHub
Documentation Integration
- 1. GitLab/GitHub Wiki: Integrated with code repositories
- 2. Confluence: Enterprise-level document management
- 3. Notion: Modern document and knowledge management tool
Modeling Practice Process
Project Initiation Phase
否
是
Project Initiation
Requirements Analysis
System Boundary Definition
Stakeholder Identification
Create System Context Diagram
Context Diagram Review
Review Passed?
Enter System Design Phase
Key Activities:
- 1. Requirements Analysis: Clarify system functional and non-functional requirements
- 2. Boundary Definition: Determine the scope of the system’s responsibilities
- 3. Stakeholder Identification: Identify all personnel and external systems interacting with the system
- 4. Context Modeling: Create Level 1 system context diagram
System Design Phase
否
是
否
是
System Design Begins
Technology Selection
Container Division
Create Container Diagram
Interface Definition
Container Diagram Review
Review Passed?
Detailed Design Phase
Component Identification
Create Component Diagram
API Design
Component Diagram Review
Review Passed?
Implementation Phase
Design Points:
- 1. Technology Stack Selection: Choose appropriate technology based on embedded system constraints
- 2. Container Division: Divide containers according to functional, performance, and deployment requirements
- 3. Interface Design: Clearly define communication protocols and data formats between containers
Modeling During Implementation Phase
During the implementation phase, the C4 model is mainly used for:
- 1. Guiding Code Structure: Level 4 code diagram guides specific implementation
- 2. Supporting Refactoring Decisions: Analyze the impact of refactoring through architectural diagrams
- 3. Integrating New Features: Assess the impact of new features on the existing architecture
Version Management and Evolution Strategy
Architecture Versioning
# Suggested Directory Structure
docs/
├── architecture/
│ ├── c4-model/
│ │ ├── level1-context/
│ │ │ ├── system-context-v1.0.md
│ │ │ └── system-context-v1.1.md
│ │ ├── level2-containers/
│ │ │ ├── container-overview-v1.0.md
│ │ │ └── ems-container-v1.0.md
│ │ ├── level3-components/
│ │ │ ├── engine-control-components-v1.0.md
│ │ │ └── safety-components-v1.0.md
│ │ └── level4-code/
│ │ ├── device-manager-classes.md
│ │ └── protocol-stack-interfaces.md
│ ├── decisions/
│ │ ├── adr-001-architecture-style.md
│ │ ├── adr-002-communication-protocol.md
│ │ └── adr-003-safety-design.md
│ └── principles/
│ ├── design-principles.md
│ └── coding-standards.md
Evolution Management Strategy
- 1. Incremental Evolution: Avoid large-scale architectural changes
- 2. Backward Compatibility: Maintain interface stability
- 3. Impact Analysis: Assess the impact on other components before changes
- 4. Document Synchronization: Update architectural documentation in sync with code changes