🛰️Zafer Satılmış - Aviora

Architecture Deep Dive

How developer workflow is separated from customer customization. Result: clean API at the application layer, controlled extension point at config and generation.

Developer perspective

A developer writes business logic once and keeps using the same file operations. No customer branch is required in app modules.

  • One include: `Midd_FS/fs_port.h`
  • One startup contract: `FS_HARDWARE_INIT` then `fsInit`
  • One API family: `fs*` operations

Customer perspective

Each customer controls file system behavior in JSON. The customer can switch active backend and parameters without editing app source files.

  • `activeFsName` selects backend
  • `cells`, `geometry`, `flashHwFunc` define behavior
  • Generated header reflects selected configuration

Layer model

Mermaid architecture layers
flowchart TB
  APP[Application Services] --> API["Midd_FS/fs_port.h"]
  API --> GEN1["Customers/FS_Port_Config.h"]
  GEN1 --> GEN2["Customers/NAME/Fs/cus_fs_port_config.h"]
  GEN2 --> PORT["fs_port_flashLink or littlefs or flashFS"]
  PORT --> HW["Hardware callbacks from flashHwFunc"]
  CONF["Customers/NAME/Fs/fs_config.json"] --> SCRIPT[generate_fs_port_config.py]
  SCRIPT --> GEN1
  SCRIPT --> GEN2
[Fallback layer model]
Application Services
  -> Midd_FS/fs_port.h
    -> Customers/FS_Port_Config.h
      -> Customers/NAME/Fs/cus_fs_port_config.h
        -> selected fs_port backend
          -> hardware callbacks
Customers/NAME/Fs/fs_config.json
  -> generate_fs_port_config.py
    -> generated headers

Lifecycle

During startup, generated macros create and configure backend operations. After this point, app code only sees common API behavior.

Startup sequence
sequenceDiagram
  participant App as AppZMeterGw
  participant Gen as Generated FS config
  participant Port as Active FS port
  App->>Gen: FS_HARDWARE_INIT(error)
  Gen->>Port: bind callbacks and geometry
  App->>Port: fsInit()
  Port-->>App: ready
  App->>Port: fsOpenFile/fsReadFile/fsWriteFile
[Fallback sequence]
App -> FS_HARDWARE_INIT(error)
    -> backend callback and geometry binding
App -> fsInit()
    -> backend ready
App -> fs* operations

Operational benefit

  • Lower regression risk during customer adaptation
  • Clear change scope in generated files
  • Fast onboarding for new developers
  • Safer long term maintenance

The architecture is fit for product families where hardware and memory map may change per customer.